Skip to content Skip to sidebar Skip to footer

Android Listview With Spinner And A Checkbox

I am a newbie to android development. I am trying to create a List which has a spinner, a edit text and a check box. The data for spinner and check box come from data base. I have

Solution 1:

EDIT - please see comments, this solution may not be correct

I know this question ancient, but it is the first result on Google and I am working on an application that uses Spinners in a ListView as well. I used some sample code from here to get started. I hope this example answers your question. I didn't implement the CheckBoxes but they're very similar to the Spinner - much easier, in fact. This example has a ListView with a TextView and a Spinner. Whenever the user changes a selection in the spinner, the TextView changes to reflect this.

I divided this project up into 3 classes:

  • ListViewTestActivity - main activity
  • DataAdapter - extends ArrayAdapter and works to display the elements in the ListView
  • DataHolder - simple object that just holds some information about the element. This could be implemented in many other ways to suit your needs.

There are also 3 key Android XML files I modified / created:

  • main.xml - modified - the main layout
  • rowview.xml - added - the layout for each element in the ListView
  • strings.xml - modified - the default Android strings file

To start from the bottom up, this main.xml file only contains a single ListView, and nothing else:

<?xml version="1.0" encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_parent"><ListViewandroid:id="@+id/listView1"android:layout_height="match_parent"android:layout_width="match_parent" /></LinearLayout>

And here is the rowview.xml. Remember that this view is duplicated for each row in the ListView:

<?xml version="1.0" encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:orientation="horizontal"android:layout_width="match_parent"android:layout_height="wrap_content"android:weightSum="1"><TextViewandroid:layout_width="wrap_content"android:layout_height="match_parent"android:id="@+id/text"android:layout_weight="0.5"android:textSize="25sp" /><Spinnerandroid:layout_width="0dp"android:layout_height="wrap_content"android:id="@+id/spin"android:prompt="@string/choice_prompt"android:layout_weight="0.5" /></LinearLayout>

The strings.xml file. All I added was an array for the contents of the spinner:

<?xml version="1.0" encoding="utf-8"?><resources><stringname="hello">Hello World, ListViewTestActivity!</string><stringname="app_name">ListViewTest</string><stringname="choice_prompt">Select a choice</string><string-arrayname="choices"><item>Alpha</item><item>Bravo</item><item>Charlie</item></string-array></resources>

Now for the fun stuff. The ListViewActivity class:

publicclassListViewTestActivityextendsActivity {

    @OverridepublicvoidonCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        ListViewlistView= (ListView) findViewById(R.id.listView1);

        DataHolderdata=newDataHolder(this);
        DataHolderdata1=newDataHolder(this);
        DataHolderdata2=newDataHolder(this);
        DataHolderdata3=newDataHolder(this);
        DataHolderdata4=newDataHolder(this);

        DataAdapterd=newDataAdapter(this, R.layout.rowview, newDataHolder[] { data, data1, data2, data3, data4 });

        listView.setAdapter(d);
    }
}

It's pretty simple, you just get the list, make a new adapter, and set the ListView's adapter to the one you made. This is the DataHolder class:

publicclassDataHolder {

    privateint selected;
    private ArrayAdapter<CharSequence> adapter;

    publicDataHolder(Context parent) {
        adapter = ArrayAdapter.createFromResource(parent, R.array.choices, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    }

    public ArrayAdapter<CharSequence> getAdapter() {
        return adapter;
    }

    public String getText() {
        return (String) adapter.getItem(selected);
    }

    publicintgetSelected() {
        return selected;
    }

    publicvoidsetSelected(int selected) {
        this.selected = selected;
    }

}

All the DataHolder class does is hold the Spinner's adapter and whatever other information you might want to store for each entry in the ListView (you may want to store whether it is checked or not, for example). And finally the real "meat" of the app, the DataAdapter class:

publicclassDataAdapterextendsArrayAdapter<DataHolder> {

    private Activity myContext;

    publicDataAdapter(Activity context, int textViewResourceId, DataHolder[] objects) {
        super(context, textViewResourceId, objects);
        myContext = context;
    }

    // We keep this ViewHolder object to save time. It's quicker than findViewById() when repainting.staticclassViewHolder {
        protected DataHolder data;
        protected TextView text;
        protected Spinner spin;
    }

    @Overridepublic View getView(int position, View convertView, ViewGroup parent) {
        Viewview=null;

        // Check to see if this row has already been painted once.if (convertView == null) {

            // If it hasn't, set up everything:LayoutInflaterinflator= myContext.getLayoutInflater();
            view = inflator.inflate(R.layout.rowview, null);

            // Make a new ViewHolder for this row, and modify its data and spinner:finalViewHolderviewHolder=newViewHolder();
            viewHolder.text = (TextView) view.findViewById(R.id.text);
            viewHolder.data = newDataHolder(myContext);
            viewHolder.spin = (Spinner) view.findViewById(R.id.spin);
            viewHolder.spin.setAdapter(viewHolder.data.getAdapter());

            // Used to handle events when the user changes the Spinner selection:
            viewHolder.spin.setOnItemSelectedListener(newOnItemSelectedListener() {

                @OverridepublicvoidonItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
                    viewHolder.data.setSelected(arg2);
                    viewHolder.text.setText(viewHolder.data.getText());
                }

                @OverridepublicvoidonNothingSelected(AdapterView<?> arg0) {
                }

            });

            // Update the TextView to reflect what's in the Spinner
            viewHolder.text.setText(viewHolder.data.getText());

            view.setTag(viewHolder);

            Log.d("DBGINF", viewHolder.text.getText() + "");
        } else {
            view = convertView;
        }

        // This is what gets called every time the ListView refreshesViewHolderholder= (ViewHolder) view.getTag();
        holder.text.setText(getItem(position).getText());
        holder.spin.setSelection(getItem(position).getSelected());

        return view;
    }
}

Here's a screenshot of the final app (it's not very pretty, but it does work):

AppPic

And that's it! I hope I answered your question and helped anyone else who stumbled upon it like I did. If you want to dynamically change the data in the list, use the DataAdapter's add(), remove(), get(), and set() methods. To change the data for each individual spinner, you need to modify the DataHolder class. The SpinnerAdapter is created there, so you just need to dynamically generate the adapters depending on the database response.

Solution 2:

In order to make things like that work one has to store all data in adapter, not in ListView items. Any view that represents a ListView item could be reused to display another item, making any data stored in itself irrelevant until the proper data is set again in getView.

Post a Comment for "Android Listview With Spinner And A Checkbox"