【问题标题】:Android: Change Button background in ListView Row with onClickAndroid:使用 onClick 更改 ListView 行中的按钮背景
【发布时间】:2011-11-10 01:30:49
【问题描述】:

我的行包含一个按钮,该按钮在我的适配器的 getView 中设置了自己的单击侦听器。我可以在行的父项中使用 android:descendantFocusability="blocksDescendants" 区分我的按钮点击和实际的行项目点击。

当我点击一个按钮时,它会正确设置按钮背景,我的问题是当我滚动列表时,它也为不同的行设置了它。我认为他们在某个地方有观点回收的问题。

这是我的代码:

@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 行的按钮,按钮背景会发生应有的变化。但是当我向下滚动列表时,其他按钮也会随机设置。然后有时当我向上滚动到位置 1 时,按钮背景会再次恢复到原来的状态。

我在这里缺少什么?我知道我就在那里,这只是我没有做的小事。

【问题讨论】:

  • 当您更改为 if(true || convertView == null){... (所以它总是膨胀),那么它可以正常工作吗?不是解决方案,只是想知道问题是否不再出现。
  • 是的,这会阻止背景在其他随机行上发生变化。显然不是你说的解决方案,但是它会停止问题,直到我向上滚动并且按钮恢复到原来的背景。

标签: android listview button onclick adapter


【解决方案1】:

是的,你是对的,观点被回收了。您将需要跟踪单击了哪些位置并在 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;
    }
}

【讨论】:

  • 非常感谢!我只需将 setBackgroundResource(0) 中的 0 更改为我的其他可绘制对象,一切都按预期工作。非常感谢!
  • 哥们,你救了我的命
【解决方案2】:

我使用 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;
}

这与 OnClickListener 一起工作仍然完美,您可以在其中完成重要工作。

【讨论】:

    【解决方案3】:
    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);
    
    }
    });
    

    【讨论】:

    • 你能不能再补充一个解释?
    猜你喜欢
    • 1970-01-01
    • 2014-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-25
    • 1970-01-01
    相关资源
    最近更新 更多