Search code examples
androidandroid-listviewandroid-arrayadapterlayout-inflater

Android: Update ListViewItem with new .xml from code


I have a ListView with an OnClick-method, which I want to change the layout of the clicked ListViewItem. I want to do this by setting the layout to a new XML. As the view loads I set the items' default layout in the ArrayAdapter's getView-method by

LayoutInflater vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            if(position % 2 == 0){
                v = vi.inflate(R.layout.wizard_listview_rowlayout_even, null);
            } else {
                v = vi.inflate(R.layout.wizard_listview_rowlayout_odd, null);
            }

This works, as the method returns the inflated view. I tried using this in the onClick-method

LayoutInflater vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.wizard_listview_rowlayout_checked, null);

but this doesn't work, probably because the View (v) is never returned. Is there any way to manipulate the view (the ListViewItem) such that the layout in the app are updated?

I've tried using selectors, but it only make my app crash, and I feel I'm so close using this method.

Thanks :)

EDIT: Here's my complete ListViewFiller-class:

public class ListViewFiller extends ListActivity {

private Context context;
private ArrayList<String> items;
private final ListView listview;

ListViewFiller(final ListView listview, ArrayList<String> items, Context appContext){
    context = appContext;
    this.listview = listview;
    this.items = items;
    ArrayAdapter adapter = new StudiesAdapter(appContext, android.R.layout.simple_list_item_1, items);
    listview.setAdapter(adapter);
    listview.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
    listview.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View v,
                  int position, long id) {
            v.setSelected(true);
            print();
            LayoutInflater vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.wizard_listview_rowlayout_checked, null);
            listview.invalidate();
        }           
    });
}

public class StudiesAdapter extends ArrayAdapter<String> {
    private ArrayList<String> studies;
    public StudiesAdapter(Context context, int textViewResourceId, ArrayList<String> studies) {
        super(context, textViewResourceId, studies);
        this.studies = studies;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View v = convertView;
        if (true) { //opprinnelig if(v == null)
            LayoutInflater vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            if(position % 2 == 0){
                v = vi.inflate(R.layout.wizard_listview_rowlayout_even, null);
            } else {
                v = vi.inflate(R.layout.wizard_listview_rowlayout_odd, null);
            }
        }

        String study = studies.get(position);
        if (study != null) {
            TextView text = (TextView) v.findViewById(R.id.label);

            if (text != null) {
                text.setText(study);
                Typeface face = Typeface.createFromAsset(context.getAssets(), "MyriadWebPro-Bold.ttf");
                text.setTypeface(face);
            }

        }

        return v;
    }
}

}

What I try to achieve is when the list-item is clicked (and the onItemClick-method is called), I want to set the layout of the item to the xml-file "R.layout.wizard_listview_rowlayout_checked".


Solution

  • I found out: The ListView apparently calls the getView-method more than once. To fix the issue, I had to, in getView, check if the view at a specific position was checked or not, and set the XML to checked, odd or even based on that.

    In the clickListener I then set the item to checked.