Thursday, January 29, 2015

Creating TextView and ToggleButton list on Android

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:
<?xml version="1.0" encoding="utf-8"?>
<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.

1 comment:

  1. Your posts is really helpful for me.Thanks for your wonderful post. I am very happy to read your post. It is really very helpful for us and I have gathered some important information from this blog.
    Java Training in Chennai

    Java Training in Velachery

    Java Training in Tambaram

    Java Training in Porur

    Java Training in OMR

    Java Training in Annanagar

    ReplyDelete