带有多个按钮的 Android ListView 自定义行与 OnClickListener 有问题,它会影响多个列表项

标签 android listview button adapter onclicklistener

您好,我已经在论坛上搜索了几个小时,并决定提出一个问题,因为我无法真正找到代码中的错误。我有一个 ListView,后跟一个自定义适配器。 我的 listView 中的每个项目看起来像这样“|txtView| |Btn 0| |Btn 1| |Btn 2|”我正在使用 ViewHolder 来提高性能。我使用自定义适配器中的 setOnClickListener。 单击的每个按钮都应将其背景更改为绿色,将其他按钮更改为灰色。

我的问题是,当点击某行项目的某个按钮时,它也会更改另一行的另一个按钮的背景。我似乎没有发现我的问题,我猜这与我使用 ViewHolder 的重用能力有关。

希望大家帮帮忙,非常感谢。

这是我在适配器中的 getView

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder = null;


    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.bet_list_item, null);

        holder = new ViewHolder();

        holder.tvGameDescription = (TextView) convertView
                .findViewById(R.id.gameDescription);
        holder.button0 = (Button) convertView
                .findViewById(R.id.button0);
        holder.button1 = (Button) convertView
                .findViewById(R.id.button1);
        holder.button2 = (Button) convertView
                .findViewById(R.id.button2);

        convertView.setTag(holder);
    } else {

        holder = (ViewHolder) convertView.getTag();

    }

    MyOnclickListener myOnclickListener = new MyOnclickListener(holder);         

    holder.buttonSide1.setOnClickListener(myOnclickListener);
    holder.buttonSideX.setOnClickListener(myOnclickListener);
    holder.buttonSide2.setOnClickListener(myOnclickListener);

这是监听器实现:

private class MyOnclickListener implements OnClickListener {


    private ViewHolder viewHolder;
    boolean[] buttonsClickStatus = { false, false, false }; //all gray at start and not clicked

    public MyOnclickListener(ViewHolder viewHolder) {
        this.viewHolder = viewHolder;
    }

    @Override
    public void onClick(View v) {
        switch (((Data) v.getTag()).getBtnPosition()) { 

        case Consts.BUTTON_0:
        if (!buttonsClickStatus[0]) { // case the btn is gray unclicked
                setButtonsaBackground(0); // changes the background 
                buttonsClickStatus[0] = true;
                buttonsClickStatus[1] = false;
                buttonsClickStatus[2] = false;
        } else { // case already green clicked already
                addOrRemove = false;
                setButtonsaBackground(3);
                for (int i = 0; i < buttonsClickStatus.length; i++) {
                buttonsClickStatus[i] = false;
            }
        }

        break;

        case Consts.BUTTON_1:
            if (!buttonsClickStatus[1]) { // case gray
                setButtonsaBackground(1);
                buttonsClickStatus[1] = true;
                buttonsClickStatus[0] = false;
                buttonsClickStatus[2] = false;
            } else { // case already green
                addOrRemove = false;
                setButtonsaBackground(3);
                for (int i = 0; i < buttonsClickStatus.length; i++) {
                    buttonsClickStatus[i] = false;
                }
            }
            break;

        case Consts.BUTTON_2:
            if (!buttonsClickStatus[2]) { // case gray
                setButtonsaBackground(2);
                buttonsClickStatus[2] = true;
                buttonsClickStatus[0] = false;
                buttonsClickStatus[1] = false;
            } else { // case already green
                addOrRemove = false;
                setButtonsaBackground(3);
                for (int i = 0; i < buttonsClickStatus.length; i++) {
                buttonsClickStatus[i] = false;
                }
            }
            break;

        default:
            break;
        }

                    //call a function to update data only in the activity
        myActivity.update((Data) v.getTag());

    }

SetBackground 作为私有(private)方法在监听器内部:

    private void setButtonsaBackground(int clicked) {
        switch (clicked) {
        case 0:

            viewHolder.button0.setBackgroundColor(Color.GREEN);
            viewHolder.button1.setBackgroundColor(Color.GRAY);
            viewHolder.button2.setBackgroundColor(Color.GRAY);

            break;
        case 1:

            viewHolder.button1.setBackgroundColor(Color.GREEN);
            viewHolder.button0.setBackgroundColor(Color.GRAY);
            viewHolder.button2.setBackgroundColor(Color.GRAY);

            break;
        case 2:

            viewHolder.button2.setBackgroundColor(Color.GREEN);
            viewHolder.button0.setBackgroundColor(Color.GRAY);
            viewHolder.button1.setBackgroundColor(Color.GRAY);
            break;

        case 3:
            viewHolder.button2.setBackgroundColor(Color.GRAY);
            viewHolder.button0.setBackgroundColor(Color.GRAY);
            viewHolder.button1.setBackgroundColor(Color.GRAY);
            break;

        default:
            break;
        }

    }

最佳答案

我已经通过以下方式解决了这个问题:

我在 button 中标记了 holder

 holder.btnSetLock.setTag(holder);
 holder.btnUnLock.setTag(holder);

我已经通过以下方式设置了背景颜色:

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

}
});

关于带有多个按钮的 Android ListView 自定义行与 OnClickListener 有问题,它会影响多个列表项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15092845/

相关文章:

android - 如何使用文本和图像消息创建聊天 Activity

ios - MFMailComposeViewController 发送按钮禁用

swift - 如何停止我的 UIButton 动画 SWIFT

Android 插件保护不存在

android - 有没有办法从 GreenDao 查询对象中获取游标?

android - 主题级别的 RecyclerView 样式

java - 替换 codenameone 中的列表

android - 按钮监听器和 SimpleCursor 适配器

java - 如何在场景生成器中将按钮适合圆形图像?

java - 如何删除 "Linear Layout"中的渐变边框?