Android: change the "Background" button in the list bar using onClick

My lines have a button that has its own click listener installed in my getView adapter. I can distinguish between button clicks and actual row element clicks using android: descendantFocusability = "blocksDescendants" in the parent line.

When I click the button, it sets the button background correctly, my problem is that I am browsing the list, setting it for different lines. I assume that their problem is somewhere with the processing of views.

Here is my code:

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

So if I press the button at position 1, the background of the button will change as it should. But then when I scroll through the list, random other buttons are also set. Then sometimes, when I scroll back to position 1, the background of the button returns to the original again.

What am I missing here? I know that I am here, just something secondary that I do not do.

+7
source share
3 answers

Yes, you are right, the views are reworked. You will need to track which positions have been clicked and update the background resource in the getView method. For example, I expanded your code to add background switching:

 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; } } 
+8
source

I found a perfect, short and clean solution for this using StateListDrawable:

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

It still blends perfectly with OnClickListener where you can make your important stuff.

+1
source
 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); } }); 
-one
source

All Articles