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

时间:2013-02-26 15:25:09

标签: 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 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;
        }

    }

3 个答案:

答案 0 :(得分:1)

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

我在holder中标记了button

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

}
});

答案 1 :(得分:0)

在你的getview方法中。

 if(posiiton==0)
 {
   holder.buttonSide1.setOnClickListener(myOnclickListener);
 }

您可以使用

而不是使用if条件
 for(int i=0;i<yourlisitemcount;i++)
 {
 if(position==i)    //make sure you click the button in appropriate listview position
  {
    holder.buttonSide1.setOnClickListener(myOnclickListener);
  }
 }

编辑 - 以下代码适合我。

                    vh.b1=(Button)arg1.findViewById(R.id.b1);//button 1
            vh.b2=(Button)arg1.findViewById(R.id.b2);// button2

            vh.b1.setOnClickListener(new OnClickListener()
            {

                public void onClick(View v) {
                    if(position==1)
                    {
                        vh.b1.setBackgroundColor(Color.RED);
                        vh.b2.setBackgroundColor(Color.GREEN);
                    }


                }

            });

答案 2 :(得分:0)

嘿,我刚刚在一个项目上工作时遇到了类似的问题,当时是紧急情况,我发现了一些不太好的解决方案。

我所做的就是给你的文本视图或你的案例中的按钮一个独特的内容描述,而你的getView()方法的if条件中的findViewbyId,然后检查条件是否onclick()重写方法。

将尝试为此找到更好的解决方案。