Creating TextView and ToggleButton list on Android

2015/01/29

Categories: Software Mobile Tags: togglebutton notifications android studio listview textview android list

There are lots of tutorials out there on creating lists with multiple elements, but none seem to work out of the box, with listeners and all.
So this is my way of implementing a list where each row consists of a TextView and a ToggleButton.

The code was tested on Android Studio and is intended for SDK 4.4+ (because everything that is below 4.4 should disappear, in my opinion).

After creating a new project with a blank activity, the first step is to modify the layout for the main activity, as follows:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    xmlns:tools="http://schemas.android.com/tools"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    android:orientation="horizontal"  
    android:clickable="false"  
    android:paddingLeft="@dimen/activity_horizontal_margin"  
    android:paddingRight="@dimen/activity_horizontal_margin" >  

    <ListView  
        android:id="@+id/list"  
        android:layout_width="fill_parent"  
        android:layout_height="fill_parent">  
    </ListView>  

</LinearLayout>  

After that we need a new layout for the list row, let’s call it row_layout.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:orientation="horizontal"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent">  

    <TextView  
        android:layout_width="0dp"  
        android:layout_height="wrap_content"  
        android:id="@+id/settings_text"  
        android:layout_weight="1"  
        android:textColor="#000000"/>  

    <ToggleButton  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:id="@+id/toggle_button"  
        android:focusable="false"  
        />  

</LinearLayout>  

What is to note here is the attribute android:focusable=“false” for the ToggleButton. This is mandatory, otherwise the ToggleButton will consume the click notifications. A detailed explanation can be readĀ here.
Let’s define some static values for the list elements. A simple way is to do this is to define an array of items in strings.xml:

<string-array name="Strings">  
    <item>Item 1</item>  
    <item>Item 2</item>  
    <item>Item 3</item>  
    <item>Item 4</item>  
</string-array>  

After the layouts are set we would need a flavour of the Adapter class so we can fill the list with data. For this type of list let’s go with an extension of the ArrayAdapter.

public class ToggleButtonListAdapter extends ArrayAdapter<String> {  
    private final Context context;  
    private final String[] values;  

    public ToggleButtonListAdapter(Context context, String\[\] values) {  
        super(context, R.layout.activity_main, values);  
        this.context = context;  
        this.values = values;  
    }  

    @Override  
    public View getView(final int position, View convertView, ViewGroup parent) {  
        LayoutInflater inflater = (LayoutInflater) context  
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);  
        View rowView = inflater.inflate(R.layout.row_layout, parent, false);  
        TextView textView = (TextView) rowView.findViewById(R.id.settings_text);  
        ToggleButton toggleButton = (ToggleButton) rowView.findViewById(R.id.toggle_button);  

        toggleButton.setOnClickListener(new View.OnClickListener() {  
            private final String[] values = getContext().getResources().getStringArray(R.array.Strings);  

            @Override  
            public void onClick(View v) {  
                Toast.makeText(getContext(), values\[position\] + " checked", Toast.LENGTH_LONG).show();  
            }  
        });  

        textView.setText(values[position]);  

        return rowView;  
    }  
}  

As a last step we need to add some code to the MainActivity’s onCreate() method in order to instantiate the ListView, populate it and add some listeners for the click actions:

@Override  
protected void onCreate(Bundle savedInstanceState) {  
    super.onCreate(savedInstanceState);  
    setContentView(R.layout.activity_main);  

    ToggleButtonListAdapter adapter = new ToggleButtonListAdapter(this, getResources().getStringArray(R.array.Strings));  
    ListView lv = (ListView) findViewById(R.id.list);  
    lv.setAdapter(adapter);  

    lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {  
        private final String[] values = getBaseContext().getResources().getStringArray(R.array.Strings);  

        @Override  
        public void onItemClick(AdapterView parent, View view, int position, long id) {  
            Toast.makeText(getBaseContext(), values[position] + " selected", Toast.LENGTH_LONG).show();  
        }  
    });  
}  

This is enough to have a list of text and toggle buttons, with the ability to react on clicks for the text button, and for the toggle button.
Full source code is availableĀ here.