【问题标题】:Text of button in ListView Item is changed while scrolling滚动时更改 ListView 项中按钮的文本
【发布时间】:2017-02-13 11:37:10
【问题描述】:

我有一个ListView,我用自定义适配器填充了ListViewTextView 和按钮。我在custom adapter 中为Button 生成了一个点击事件。在那个点击事件中我试图更改按钮文本和颜色,直到这里它工作正常但是当我上下滚动ListView 时,其他按钮的文本颜色会发生变化。过去几天我在这里停了下来......

public class CustomAdapter extends BaseAdapter {

Activity a;
ArrayList<String> Rollno;
ArrayList<String> Stdname;
ArrayList<String> Stdstatus;

public CustomAdapter(Activity a, ArrayList<String> rollno, ArrayList<String> stdname, ArrayList<String> stdstatus) {
    this.a = a;
    Rollno = rollno;
    Stdname = stdname;
    Stdstatus = stdstatus;
}


@Override
public int getCount() {
    return Rollno.size();
}

@Override
public Object getItem(int position) {
    return Rollno.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}


public  class ViewHolder{
    TextView rollno,name;
    Button status;
}



@Override
public View getView(final int position, View convertView, ViewGroup parent) {
     final  ViewHolder viewHolder=new ViewHolder();
    LayoutInflater li=a.getLayoutInflater();
    View v=li.inflate(R.layout.custom,parent,false);
    viewHolder.rollno=(TextView)v.findViewById(R.id.crollno);
    viewHolder.name=(TextView)v.findViewById(R.id.cname);
    viewHolder.status=(Button)v.findViewById(R.id.btn1);


    viewHolder.rollno.setText(Rollno.get(position));
    viewHolder.name.setText(Stdname.get(position));
    viewHolder.status.setText(Stdstatus.get(position));

   viewHolder.status.setTag(0);
    viewHolder.status.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

           final int status1 = (Integer) v.getTag();

            if (status1 == 1) {
                viewHolder.status.setText("P");
                viewHolder.status.setBackgroundColor(Color.GREEN);

                v.setTag(0);
            } else if (status1 == 2) {
                viewHolder.status.setText("A");
                viewHolder.status.setBackgroundColor(Color.RED);
                v.setTag(1);
            } else if (status1 == 3) {
                viewHolder.status.setText("L");
                viewHolder.status.setBackgroundColor(Color.BLUE);
                v.setTag(2);
            } else {
                viewHolder.status.setText("H");
                viewHolder.status.setBackgroundColor(Color.YELLOW);
                v.setTag(3);

            }

        }
    });
    return v;
}
}

【问题讨论】:

  • 您有这个问题,因为 ListView 正在重用单元格,因此会显示先前单元格的状态。您需要将按钮的状态存储在某处并在getView 中检查状态。
  • 我如何存储按钮的状态。我是 android 新手,你能给我那个代码吗?提前谢谢你的帮助

标签: java android listview


【解决方案1】:

基本上你需要存储位置的状态。 用下面的代码替换你的适配器。

class CustomAdapter extends BaseAdapter {

        Activity a;
        ArrayList<String> Rollno;
        ArrayList<String> Stdname;
        ArrayList<String> Stdstatus;
        HashMap<Integer, Integer> statusArray = new HashMap<>();

        public CustomAdapter(Activity a, ArrayList<String> rollno, ArrayList<String> stdname, ArrayList<String> stdstatus) {
            this.a = a;
            Rollno = rollno;
            Stdname = stdname;
            Stdstatus = stdstatus;
        }


        @Override
        public int getCount() {
            return Rollno.size();
        }

        @Override
        public Object getItem(int position) {
            return Rollno.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }


        public  class ViewHolder{
            TextView rollno,name;
            Button status;
        }



        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            final  ViewHolder viewHolder=new ViewHolder();
            LayoutInflater li=a.getLayoutInflater();
            View v=li.inflate(R.layout.custom,parent,false);
            viewHolder.rollno=(TextView)v.findViewById(R.id.crollno);
            viewHolder.name=(TextView)v.findViewById(R.id.cname);
            viewHolder.status=(Button)v.findViewById(R.id.btn1);


            viewHolder.rollno.setText(Rollno.get(position));
            viewHolder.name.setText(Stdname.get(position));
            viewHolder.status.setText(Stdstatus.get(position));

            int status = statusArray.get(position) != null ? statusArray.get(position) : 0;
            switch (status){
                case 1:
                    viewHolder.status.setText("P");
                    viewHolder.status.setBackgroundColor(Color.GREEN);
                    break;
                case 2:
                    viewHolder.status.setText("A");
                    viewHolder.status.setBackgroundColor(Color.RED);
                    break;
                case 3:
                    viewHolder.status.setText("L");
                    viewHolder.status.setBackgroundColor(Color.BLUE);
                    break;
                default:
                    viewHolder.status.setText("H");
                    viewHolder.status.setBackgroundColor(Color.YELLOW);
                    break;
            }

            viewHolder.status.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    int status1 = statusArray.get(position) != null ? statusArray.get(position) : 0;
                    if (status1 == 1) {
                        statusArray.put(position, 0);
                    } else if (status1 == 2) {
                        statusArray.put(position, 1);
                    } else if (status1 == 3) {
                        statusArray.put(position, 2);
                    } else {
                        statusArray.put(position, 3);
                    }

                    notifyDataSetChanged();
                }
            });
            return v;
        }
    }

【讨论】:

    【解决方案2】:

    使用卡片视图与我遇到的相同问题。

                  if (readvalue.equals("0")) {
            holder.cardView.setCardBackgroundColor(context.getResources().getColor(R.color.texthintcolor));
            //  holder.itemView.setBackgroundResource(0);
            //cardView.setRadius(5);
    
        } else {
            //     holder.itemView.setBackgroundColor());
            holder.cardView.setCardBackgroundColor(context.getResources().getColor(R.color.winter));
    
    
            // cardView.setRadius(5);
    
        }
    

    【讨论】:

      【解决方案3】:

      您似乎正在覆盖您的标签,这导致您的按钮逻辑无法正常工作。

      viewHolder.status.setTag(0);
      

      通常你会这样做:

      if (convertview == null){
        //create and initialize new viewholder and pass it to the views tag field
        //initialize the status tag here and dont set it again later
      }else{
       //get your viewholder from the views tag
      }
      //update your values
      

      Example:

      @Override
      public View getView(int position, View convertView, ViewGroup parent) {
      
      ViewHolderItem viewHolder;
      
      /*
       * The convertView argument is essentially a "ScrapView" as described is Lucas post 
       * http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/
       * It will have a non-null value when ListView is asking you recycle the row layout. 
       * So, when convertView is not null, you should simply update its contents instead of inflating a new row layout.
       */
      if(convertView==null){
      
          // inflate the layout
          LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
          convertView = inflater.inflate(layoutResourceId, parent, false);
      
          // well set up the ViewHolder
          viewHolder = new ViewHolderItem();
          viewHolder.textViewItem = (TextView) convertView.findViewById(R.id.textViewItem);
      
          // store the holder with the view.
          convertView.setTag(viewHolder);
      
      }else{
          // we've just avoided calling findViewById() on resource everytime
          // just use the viewHolder
          viewHolder = (ViewHolderItem) convertView.getTag();
      }
      
      // object item based on the position
      ObjectItem objectItem = data[position];
      
      // assign values if the object is not null
      if(objectItem != null) {
          // get the TextView from the ViewHolder and then set the text (item name) and tag (item ID) values
          viewHolder.textViewItem.setText(objectItem.itemName);
          viewHolder.textViewItem.setTag(objectItem.itemId);
      }
      
      return convertView;
      

      }

      【讨论】:

        【解决方案4】:

        放置这个'viewHolder.status.setTag(0);'下面到 onClickListener 我认为它会起作用

         viewHolder.status.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
        
               final int status1 = (Integer) v.getTag();
        
                if (status1 == 1) {
                    viewHolder.status.setText("P");
                    viewHolder.status.setBackgroundColor(Color.GREEN);
        
                    v.setTag(0);
                } else if (status1 == 2) {
                    viewHolder.status.setText("A");
                    viewHolder.status.setBackgroundColor(Color.RED);
                    v.setTag(1);
                } else if (status1 == 3) {
                    viewHolder.status.setText("L");
                    viewHolder.status.setBackgroundColor(Color.BLUE);
                    v.setTag(2);
                } else {
                    viewHolder.status.setText("H");
                    viewHolder.status.setBackgroundColor(Color.YELLOW);
                    v.setTag(3);
        
                }
        
            }
        });
        viewHolder.status.setTag(0);
        return v;
        

        } }

        【讨论】:

          【解决方案5】:

          每次进入前景时都会重新创建视图,因此只有视图位置才能真正唯一。 您可以创建视图位置的哈希图和您自己的标签(整数),而不是使用视图标签。每次创建视图时,检查 hashmap 中是否存在位置,并根据 hashmap 标签设置按钮颜色。放置线

          private HashMap<Integer,Integer> tagMap = new HashMap<>();
          

          在 customAdapter 的开头。在getView中检查是否添加了位置,如果没有添加相应的按钮标签

          int tag=1; //desired default tag for button
             //add to hashmap if not exist
           if(!tagMap.containsKey(position)){
                  tagMap.put(position,tag);
              }
          

          在 onclick 监听器中,您可以按位置获取 hasmap 标签并相应地设置按钮颜色

             final int status1 = tagMap.get(position);;
          
                  if (status1 == 1) {
                      viewHolder.status.setText("P");
                      viewHolder.status.setBackgroundColor(Color.GREEN);
          
                      tagMap.put(position,0);//this will update tag for current position
                  } else if (status1 == 2) {
                      viewHolder.status.setText("A");
                      viewHolder.status.setBackgroundColor(Color.RED);
                     tagMap.put(position,1);
                  } else if (status1 == 3) {
                      viewHolder.status.setText("L");
                      viewHolder.status.setBackgroundColor(Color.BLUE);
                      tagMap.put(position,2);
                  } else {
                      viewHolder.status.setText("H");
                      viewHolder.status.setBackgroundColor(Color.YELLOW);
                    tagMap.put(position,3);
                  }
          

          希望对你有帮助

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2018-11-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-04-07
            相关资源
            最近更新 更多