Marek Czaplicki Marek Czaplicki - 6 months ago 20
Android Question

OnClickListener doesn't change view in Custom BaseAdapter

I have a custom BaseAdapter that row has some views in it.

Mainly a checkbox (ImageView) and button (ImageView) and hidden text (TextView).

Whenever I click on checkbox I want to change it's drawable and it seems to work, but only when I

notifyDataSetChanged
- which IMO shouldn't matter. If I remove the line then it sometimes work and sometimes doesn't work.

The more important part is that I want the button to show/hide
holder.expansion
but it doesn't work. Regardless
v.getTag()
I have also tried to use
holder.expansion
, but it didn't work either.

How can I get it to work? To change checkbox drawable and show/hide expansion text?

@Override
public View getView(int position, View view, ViewGroup parent)
{
final DrugHolder holder;
if (view == null)
{
holder = new DrugHolder();
view = inflater.inflate(R.layout.drug_list_row, null);
holder.name = (TextView) view.findViewById(R.id.drug_list_name);
holder.checkbox = (ImageView) view.findViewById(R.id.drug_list_checkbox);
holder.arrow = (LinearLayout) view.findViewById(R.id.drug_list_arrow_button);
holder.expansion = (LinearLayout) view.findViewById(R.id.drug_list_expansion);
holder.fullName = (TextView) view.findViewById(R.id.drug_list_full_name);
holder.quantity = (TextView) view.findViewById(R.id.drug_list_quantity);
holder.unitDose = (TextView) view.findViewById(R.id.drug_list_unit_dose);

view.setTag(holder);
}
else
{
holder = (DrugHolder) view.getTag();
}
int colorPos = position % colors.length;
view.setBackgroundColor(colors[colorPos]);

Drug drug = allItems.get(position);
holder.name.setText(drug.Name);
holder.fullName.setText(drug.Name);
holder.quantity.setText(String.format(Locale.GERMANY, "%.2f", drug.Quantity));
holder.unitDose.setText(drug.DoseType);
holder.arrow.setTag(holder.expansion);

holder.checkbox.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
ImageView view = (ImageView) v;
if (view.isSelected())
{
view.setSelected(false);
view.setImageDrawable(context.getDrawable(R.drawable.ic_icon_checkbox_unchecked));
}
else
{
view.setSelected(true);
view.setImageDrawable(context.getDrawable(R.drawable.ic_icon_checkbox_checked));
}
notifyDataSetChanged();
}
});

holder.arrow.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
LinearLayout view = (LinearLayout) v.getTag();
if (view.getVisibility() == View.VISIBLE)
{
view.setVisibility(View.GONE);
}
else
{
view.setVisibility(View.VISIBLE);
}
notifyDataSetChanged();
}
});

return view;
}


According to propositions of changes I have made this:

if (drug.isChecked()) //Here breakpoint - enters only when entering activity
{
holder.checkbox.setImageDrawable(context.getDrawable(R.drawable.ic_icon_checkbox_checked));
}
else
{
holder.checkbox.setImageDrawable(context.getDrawable(R.drawable.ic_icon_checkbox_unchecked));
}
if (drug.isExpanded())
{
holder.fullName.setVisibility(View.VISIBLE);
}
else
{
holder.fullName.setVisibility(View.GONE);
}

holder.checkbox.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
drug.setChecked(!drug.isChecked()); // Breakpoint - enters when clicks
notifyDataSetChanged(); // After F8 goes to this line but never goes to getView again
}
});

holder.arrow.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
drug.setExpanded(!drug.isExpanded()); // Breakpoint - enters when click
notifyDataSetChanged(); // Never goes to this line after F8 - instead it jumps to View.java and shows red block with 'Source code does not match byte code
}
});

Answer Source

You need to save info in Drug about checked state and check this state when you set data into view. For example

if (drug.isChecked()) {
holder.checkbox.setImageDrawable(context.getDrawable(R.drawable.ic_icon_checkbox_checked));
} else {
holder.checkbox.setImageDrawable(context.getDrawable(R.drawable.ic_icon_checkbox_unchecked));
}