Android:使用onClick在ListView Row中更改button背景

我的行包含一个button,在适配器的getView中设置了自己的单击监听器。 我能够区分我的button点击和实际的行项目点击使用android:descendantFocusability =“blocksDescendants”在行的父项。

当我点击一个button,它正确设置button的背景,我的问题是当我滚动列表中设置它为不同的行。 我认为他们有一个问题的地方回收的意见。

这是我的代码:

@Override public View getView(int position, View convertView, ViewGroup parent){ if(convertView == null){ holder = new ViewHolder(); convertView = inflater.inflate(R.layout.todays_sales_favorite_row, null); holder.favCatBtn = (Button)convertView.findViewById(R.id.favCatBtn); convertView.setTag(holder); } else { holder = (ViewHolder)convertView.getTag(); } holder.favCatBtn.setTag(position); holder.favCatBtn.setOnClickListener(this); return convertView; } @Override public void onClick(View v) { int pos = (Integer) v.getTag(); Log.d(TAG, "Button row pos click: " + pos); RelativeLayout rl = (RelativeLayout)v.getParent(); holder.favCatBtn = (Button)rl.getChildAt(0); holder.favCatBtn.setBackgroundResource(R.drawable.icon_yellow_star_large); } 

所以,如果我点击行位置1的button,button背景会改变,因为它应该。 但随后当我向下滚动列表随机其他button也设置为好。 然后,有时当我滚动回到位置1时,button背景会再次回到原始位置。

我在这里错过了什么? 我知道我在那里只是一些小事,我没有做。

Solutions Collecting From Web of "Android:使用onClick在ListView Row中更改button背景"

是的,你是对的,意见是回收的。 您将需要跟踪哪些位置被点击,并更新getView方法中的背景资源。 例如,我扩展了你的代码来添加背景切换:

 private final boolean[] mHighlightedPositions = new boolean[NUM_OF_ITEMS]; @Override public View getView(int position, View convertView, ViewGroup parent){ if(convertView == null){ holder = new ViewHolder(); convertView = inflater.inflate(R.layout.todays_sales_favorite_row, null); holder.favCatBtn = (Button)convertView.findViewById(R.id.favCatBtn); holder.favCatBtn.setOnClickListener(this); convertView.setTag(holder); }else { holder = (ViewHolder)convertView.getTag(); } holder.favCatBtn.setTag(position); if(mHighlightedPositions[position]) { holder.favCatBtn.setBackgroundResource(R.drawable.icon_yellow_star_large); }else { holder.favCatBtn.setBackgroundResource(0); } return convertView; } @Override public void onClick(View view) { int position = (Integer)view.getTag(); Log.d(TAG, "Button row pos click: " + position); // Toggle background resource RelativeLayout layout = (RelativeLayout)view.getParent(); Button button = (Button)layout.getChildAt(0); if(mHighlightedPositions[position]) { button.setBackgroundResource(0); mHighlightedPositions[position] = false; }else { button.setBackgroundResource(R.drawable.icon_yellow_star_large); mHighlightedPositions[position] = true; } } 

我发现这个使用StateListDrawable的完美,简短和干净的解决scheme:

 @Override public View getView(final int position, View convertView, ViewGroup parent) { currentPosition = position; holder = null; if (convertView == null) { holder = new Holder(); LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = vi.inflate(R.layout.grid_item, null); holder.imageView = (ImageView) convertView.findViewById(R.id.gridItemBtn); StateListDrawable states = new StateListDrawable(); states.addState(new int[] {android.R.attr.state_pressed}, ContextCompat.getDrawable(context, R.drawable.pressed_state)); states.addState(new int[] {android.R.attr.state_focused}, ContextCompat.getDrawable(context, R.drawable.focused_state)); states.addState(new int[]{}, ContextCompat.getDrawable(context, R.drawable.default_state)); holder.imageView.setImageDrawable(states); } return convertView; } 

这与OnClickListener一起工作仍然很完美,在这里你可以做你的重要的东西。

 holder.btnUnLock.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub // Button btn = Button(v); holder = (ViewHolder) v.getTag(); holder.btnSetLock.setBackgroundResource(R.drawable.btn_lock_bg_right); holder.btnUnLock.setBackgroundResource(R.drawable.btn_unlock_bg_left); } });