Reputation: 21
Hello I have searched the forum for hours now and decided to place a question cause I can't really find what's wrong in my code. I have a ListView followed by a custom adapter. Each item in my listView looks like this "|txtView| |Btn 0| |Btn 1| |Btn 2|" and I'm using ViewHolder to increase performance. I use setOnClickListener from the custom adapter. Each button clicked should change it's background to Green color and the others to gray.
My problem is that when clicking on a certain button at certain row item it also changes the background on another button at another row. I don't seem to find my problem , i'm guessing it's related to the fact i'm using the reuse ability with the ViewHolder.
Hope you guys can help , many thanks.
this is my getView inside the adapter
@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);
this is the listener implementation :
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 is inside the listener as private method:
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;
}
}
Upvotes: 2
Views: 4995
Reputation: 11
I have solved the problem by the following :
I tagged holder
in button
.
holder.btnSetLock.setTag(holder);
holder.btnUnLock.setTag(holder);
I have set the background color by the following :
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);
}
});
Upvotes: 1
Reputation: 133560
In your getview method.
if(posiiton==0)
{
holder.buttonSide1.setOnClickListener(myOnclickListener);
}
Instead of using if condition you can use
for(int i=0;i<yourlisitemcount;i++)
{
if(position==i) //make sure you click the button in appropriate listview position
{
holder.buttonSide1.setOnClickListener(myOnclickListener);
}
}
Edit - The below code worked for me.
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);
}
}
});
Upvotes: 0
Reputation: 94
Hey i just had a similar problem once when i was working on a project, it was an emergency then and i found out some not so good solution for this.
All i did is gave a unique content description to the text view or the buttons in your case while findViewbyId in the if condition of your getView() method and then checked the condition if the onclick() overridden method.
Will try to find out a better solution for this.
Upvotes: 0