ListView的每个Item下都有2个Button(A和B),需求是点击ButtonA,然后ButtonA隐藏。
可是在上下滚屏操作中,发现屏幕下方最新出现的某个Item上的ButtonA也被隐藏了。
如果我分别把同屏的2个Item下ButtonA都隐藏,那么向下滚屏后,又会在某处新出现2个ButtonA被隐藏的Item.
怎么让Item记住他的Button的状态呢?
Android listview

解决方案 »

  1. 你的adapter中的getView方法怎么写的?
    可以用一个List<HashMap<String,Boolean>>来存放button信息
    在getView中
    if(!list.get(position).get("A")){
        btnA.setVisibility(View.GONE);
    }然后再onItemClickListener的onClick方法中
    改变对应位置的hashmap的值,然后再用adapter.notifyDataSetChanged();刷新界面。
      


  2. 我做的比举的例子复杂一些,每个Item上有4个Button(下载、暂停、续传、开始。控件都在同一位置,要求只能显示一个其余隐藏)和一个ProgressBar。
    需求是:当我点击下载的时候,下载按钮切换为暂停按钮,同时同步更新ProgressBar。
    这是我的getView方法。public View getGroupView(final int groupPosition, boolean isExpanded,
    View convertView, ViewGroup parent) {
    if (null == convertView) {
    groupHolder = new GroupViewHolder();
    convertView = inflater.inflate(R.layout.item_listview_apps, null);
    groupHolder.iv_app_icon = (ImageView) convertView
    .findViewById(R.id.iv_app_icon);
    groupHolder.iv_bonus_icon = (ImageView) convertView
    .findViewById(R.id.iv_bonus_value);
    groupHolder.iv_corner_icon = (ImageView) convertView
    .findViewById(R.id.iv_corner_icon);
    groupHolder.tv_icon_bonus = (TextView) convertView
    .findViewById(R.id.tv_icon_bonus);
    groupHolder.tv_app_name = (TextView) convertView
    .findViewById(R.id.tv_app_name);
    groupHolder.tv_app_task = (TextView) convertView
    .findViewById(R.id.tv_app_task);
    groupHolder.tv_app_task_bonus = (TextView) convertView
    .findViewById(R.id.tv_app_task_bonus);
    groupHolder.tv_app_task_progress = (TextView) convertView
    .findViewById(R.id.tv_app_task_progress);
    groupHolder.btn_start_app = (Button) convertView
    .findViewById(R.id.btn_start_app);
    groupHolder.btn_download_app = (Button) convertView
    .findViewById(R.id.btn_download_app);
    groupHolder.btn_continue_download_app = (Button) convertView
    .findViewById(R.id.btn_continue_download_app);
    groupHolder.btn_pause_download_app = (Button) convertView
    .findViewById(R.id.btn_pause_download_app);
    groupHolder.pb_item_app = (ProgressBar) convertView
    .findViewById(R.id.pb_item_app);

    convertView.setTag(groupHolder);
    } else {
    groupHolder = (GroupViewHolder) convertView.getTag();
    }
    app = (App) getGroup(groupPosition);
    // 从App对象中取值
    String temp = app.getCurrentTaskBonus();
    if (temp != null) {
    appBonus = temp;
    }
    // appState = Byte.valueOf(app.getState());
    appIcon = app.getIcon();
    packageName = app.getPackageName();
    appIconUrl = app.getIconUrl();
    appName = app.getName();
    // appProgress = Byte.valueOf(app.getProgress());
    appCurrentTask = app.getCurrentTask();
    appCurrentTaskBonus = app.getCurrentTaskBonus();
    appSize = app.getSize();
    downloadUrl = app.getDownloadUrl();
    if (appIconUrl.trim().length() > 0) {
    groupHolder.iv_app_icon
    .setImageBitmap(Tools.Url2Bitmap(appIconUrl));
    } else {
    groupHolder.iv_app_icon.setImageDrawable(appIcon);
    }
    // AppName
    groupHolder.tv_app_name.setText(appName);
    // AppCurrentTask
    groupHolder.tv_app_task.setText(appCurrentTask);
    groupHolder.tv_icon_bonus.setText(appCurrentTaskBonus);
    groupHolder.tv_app_task_bonus.setText(appCurrentTaskBonus + "金币");
    groupHolder.btn_download_app.setText(appSize);
    groupHolder.btn_start_app
    .setOnClickListener(new ButtonOnclickListener(
    groupPosition, groupHolder.btn_download_app,
    groupHolder.btn_continue_download_app,
    groupHolder.btn_start_app,
    groupHolder.btn_pause_download_app,
    groupHolder.pb_item_app));
    groupHolder.btn_continue_download_app
    .setOnClickListener(new ButtonOnclickListener(
    groupPosition, groupHolder.btn_download_app,
    groupHolder.btn_continue_download_app,
    groupHolder.btn_start_app,
    groupHolder.btn_pause_download_app,
    groupHolder.pb_item_app));
    groupHolder.btn_download_app
    .setOnClickListener(new ButtonOnclickListener(
    groupPosition, groupHolder.btn_download_app,
    groupHolder.btn_continue_download_app,
    groupHolder.btn_start_app,
    groupHolder.btn_pause_download_app,
    groupHolder.pb_item_app));
    groupHolder.btn_pause_download_app
    .setOnClickListener(new ButtonOnclickListener(
    groupPosition, groupHolder.btn_download_app,
    groupHolder.btn_continue_download_app,
    groupHolder.btn_start_app,
    groupHolder.btn_pause_download_app,
    groupHolder.pb_item_app));
    return convertView;class GroupViewHolder {
    private ImageView iv_corner_icon = null;
    private ImageView iv_app_icon = null;
    private ImageView iv_bonus_icon = null;
    private TextView tv_app_task_bonus = null;
    private TextView tv_app_name = null;
    private TextView tv_app_task = null;
    private TextView tv_icon_bonus = null;
    private TextView tv_app_task_progress = null;
    private Button btn_start_app = null;
    private Button btn_download_app = null;
    private Button btn_pause_download_app = null;
    private Button btn_continue_download_app = null;
    private ProgressBar pb_item_app = null;
    }点击btn_download_app按钮后会创建一个AsyncTask对象,在其中进行网络下载操作,同时要更新ProgressBar和切换相应的Button,问题就是当我滚屏的时候,下面新生成的Item中的ProgressBar和Button的状态和上面操作的Item完全一致。
      

  3. getView方法返回的convertView是重用的,就是如果前面有它会直接拿来用而不会重新创建,只是里面的数据变了。
    要想达到你想要的结果,你需要点击按钮的时候存储对应的值到list中,然后listview展示的时候,每个item需要取前面那个值做判断然后决定按钮是否隐藏,不知道我说明白了没有。
      

  4. // AppName        groupHolder.tv_app_name.setText(appName);        // AppCurrentTask        groupHolder.tv_app_task.setText(appCurrentTask);        groupHolder.tv_icon_bonus.setText(appCurrentTaskBonus);        groupHolder.tv_app_task_bonus.setText(appCurrentTaskBonus + "金币");        groupHolder.btn_download_app.setText(appSize);
    你的数据又重新加载了 当然状态丢失 准确的说不是状态丢失 是你重置了状态
      

  5. 除了点击事件会触发按钮状态改变之外,我在AsyncTask中进行的网络操作也会更改按钮的状态,怎么办啊
      

  6. 网络操作会怎么改?一样也存在list中,把List<HashMap<String,Boolean>>改成List<HashMap<String,Integer>>
    getView的时候
    if(null != list.get(position).get("percentage")){
        pb_item_app.setProgress(list.get(position).get("percentage"));
    }
    然后每当你下载的时候,比如说每下载1%,就往list里面存值,然后在提醒adapter刷新。
      

  7. 为啥是onItemClickListener的onClick方法中
    改变对应位置的hashmap的值,然后再用adapter.notifyDataSetChanged();刷新界面。
    不是Button的OnClickListener的onClick方法吗?
      

  8. 如果你的button的onclick方法可以获得position的话也可以
    因为你需要position来告诉adapter哪个button被点了。哪条list状态改变了,
    list中的值得改变会使得getview返回的view的ui发生变化,然后通过adapter.notifyDataSetChanged();
    来告诉系统刷新ui,获得新的view的ui
      

  9. 网络操作是这样的:AsyncTask中有onPreExecute()和onPreExecute()
    在onPreExecute()中将下载按钮隐藏,暂停按钮显示出来。
    在onPreExecute()中将暂停按钮隐藏,将开始按钮显示出来。
      

  10. 其实我也理解的不太好。
    convertView就相当于一个容器,具体的内容还是要通过你的list中的值来设置UI
    如果你的getView与你的data没有联系,那么你界面上的listView永远是返回相同的内容。
      

  11. 在onPreExecute()中,根据当前系统的状态,往你的adapter中的list put不同的内容
    比如说
    if(下载中){
    list.get(position).put("buttonStatus",暂停) //暂停可以设成int值
    adapter.notifyDataSetChanged();
    }然后再getView中
    用个switch判断
    switch(list.get(position).get("buttonStatus"))
    case 开始:
    开始button设置为visibility
    其他button设置为gone
    break;
    //其他的同理
    case 暂停:
    break;
    case 续传:
    break;
    case 下载:
    break;
      

  12. 用ItemClickListener虽然能知道那个Postion被点了,但是怎么能知道是这个Item下的哪个Button被点了呢?
      

  13. new ButtonOnclickListener(
    groupPosition, groupHolder.btn_download_app,
    groupHolder.btn_continue_download_app,
    groupHolder.btn_start_app,
    groupHolder.btn_pause_download_app,
    groupHolder.pb_item_app)
    重构你这个listener,加入一个buttontype参数。
      

  14. 这里没太看懂,
    或者有没有什么办法在ButtonOnClickListener的OnClick()中得到是哪条Item被点击了?
      

  15. ButtonOnclickListener
    这个类应该是你自己写的吧。
    implements View.OnClickListenr
    override onClick()方法对吧。把你的构造方法重新写一下
    public ButtonOnclickListener (int groupPosition , int buttonType , ....)
      

  16. 会,所以你看很多的app的listview上下滑的时候都很卡,因为他们在加载数据,刷新adapter,显示UI等等。先把功能做出来,然后再做优化,或者重构把。
      

  17. 我也遇到了listview 多个button显示的问题  
    只要快速滑动listview button就会错乱,其余数据全部是正确的
      

类似问题 »