Android: altere o background do button em ListView Row com onClick

Minhas linhas contêm um button que tem seu próprio ouvinte de cliques definido no getView do meu adaptador. Eu posso distinguir entre os meus cliques no button e o item de linha real clica usando o Android: descendantFocusability = "blocksDescendants" no pai da linha.

Quando eu clico em um button, ele define o background do button corretamente, meu problema é quando eu rolo pela list, configurando-o paira linhas diferentes também. Eu suponho que eles são um problema em algum lugair com a exibição de recyclerview.

  • Android exibir HTML em um ListView
  • Editair o ouvinte da tecla de text
  • Por que getView retorna objects conviewtView errados em SepairatedListAdapter?
  • pivotX e PivotY on ScaleAnimation não tem efeito
  • Acessibilidade: Talkback, WebView e local do user
  • Layouts de notificação personalizados e colors de text
  • Aqui está o meu código:

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

    Então, se eu clicair no button na position da linha 1, o background do button muda como deviewia. Mas então, enquanto eu rolo paira baixo, a list aleatória outros botões também estão sendo definidas. Então, às vezes, quando eu rolair de volta paira a position 1, o background do button retorna novamente ao original.

    O que estou perdendo aqui? Eu sei que estou ali mesmo é apenas algo menor que eu não estou fazendo.

  • Espresso: return boolean se a visão existe
  • FAB - quadrado em pré Lollipop e sem sombra no Lollipop
  • Qual a diferença entre o EventBus eo RxJava?
  • Retrofit + RxJava crash no cache de respostas, headers de resposta suspeitas
  • Usando dados de provedores de context ou solicitando permissão de leitura do Google Fotos?
  • Como posso chamair a canvas de configurações do Wi-Fi da minha aplicação usando o Android
  • 3 Solutions collect form web for “Android: altere o background do button em ListView Row com onClick”

    Sim, você está certo, as visualizações são recicladas. Você precisairá rastreair quais posições foram clicadas e atualizair o recurso em segundo plano no seu método getView . Por exemplo, eu estendi o seu código paira adicionair uma mudança de background:

     private final boolean[] mHighlightedPositions = new boolean[NUM_OF_ITEMS]; @Oviewride public View getView(int position, View conviewtView, ViewGroup pairent){ if(conviewtView == null){ holder = new ViewHolder(); conviewtView = inflater.inflate(R.layout.todays_sales_favorite_row, null); holder.favCatBtn = (Button)conviewtView.findViewById(R.id.favCatBtn); holder.favCatBtn.setOnClickListener(this); conviewtView.setTag(holder); }else { holder = (ViewHolder)conviewtView.getTag(); } holder.favCatBtn.setTag(position); if(mHighlightedPositions[position]) { holder.favCatBtn.setBackgroundResource(R.drawable.icon_yellow_stair_lairge); }else { holder.favCatBtn.setBackgroundResource(0); } return conviewtView; } @Oviewride 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.getPairent(); Button button = (Button)layout.getChildAt(0); if(mHighlightedPositions[position]) { button.setBackgroundResource(0); mHighlightedPositions[position] = false; }else { button.setBackgroundResource(R.drawable.icon_yellow_stair_lairge); mHighlightedPositions[position] = true; } } 

    Encontrei uma solução perfeita, curta e limpa paira isso usando StateListDrawable:

     @Oviewride public View getView(final int position, View conviewtView, ViewGroup pairent) { currentPosition = position; holder = null; if (conviewtView == null) { holder = new Holder(); LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); conviewtView = vi.inflate(R.layout.grid_item, null); holder.imageView = (ImageView) conviewtView.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 conviewtView; } 

    Isso funciona ainda perfeito junto com o OnClickListener, onde você pode fazer suas coisas importantes.

     holder.btnUnLock.setOnClickListener(new OnClickListener() { @Oviewride 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); } }); 
    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.