滚动时更改ListView项中按钮的文本

我有一个ListView ,我使用自custom adapter填充了ListViewTextView和Button。我在custom adapter为该Button生成了一个click事件。在该click事件中我试图更改按钮文本和颜色,到此为止它的工作很好但是当我向上和向下滚动ListView时,其他按钮的文本颜色会发生变化。 我过去几天就在这里停了下来……

 public class CustomAdapter extends BaseAdapter { Activity a; ArrayList Rollno; ArrayList Stdname; ArrayList Stdstatus; public CustomAdapter(Activity a, ArrayList rollno, ArrayList stdname, ArrayList 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; } } 

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

 class CustomAdapter extends BaseAdapter { Activity a; ArrayList Rollno; ArrayList Stdname; ArrayList Stdstatus; HashMap statusArray = new HashMap<>(); public CustomAdapter(Activity a, ArrayList rollno, ArrayList stdname, ArrayList 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; } } 

使用卡片查看相同的问题,我面对这样使用。

  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); } 

看起来您正在覆盖您的标签,导致您的按钮逻辑无法正常工作。

 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 

示例 :

 @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; 

}

放置这个’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; 

}}

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

 private HashMap 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 listerner中,您可以按位置获取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); } 

希望这可以帮助