A ListView is nothing but a container of views that are stacked on each other. Imagine something like your Facebook posts on your mobile phones.
We can create custom views for each item to place in the list, with all the components we need, like buttons, layouts, edit texts and so on.
In fact, the first thing I will show oyu is our list_adapter_item.xml, which contains all the information on how to display our items in the list:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#FACAAA"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:text="Account title" android:id="@+id/textView8" android:layout_gravity="center_horizontal" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:id="@+id/list_adapter_item_title" android:layout_gravity="center_horizontal" android:text=".........." android:textStyle="bold|italic" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:text="Account login" android:id="@+id/textView9" android:layout_gravity="center_horizontal" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:text=".............." android:id="@+id/list_adapter_item_loginID" android:layout_gravity="center_horizontal" android:textStyle="bold|italic" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:text="Account password" android:id="@+id/textView5" android:layout_gravity="center_horizontal" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:text="..........." android:id="@+id/list_adapter_item_psw" android:layout_gravity="center_horizontal" android:textStyle="bold|italic" /> </LinearLayout> |
You may now behold my amazing design skills:
This is what each view inside our ListView is going to be displayed.
Before we go on and create our list adapter class, let's place the actual list on the display.
Simply go to your content_main.xml and drag in a ListView. After changing the colors to match the previous layout file, this is what you should see:
Although very simple, I will post the actual xml code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" android:background="#FACAAA" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:showIn="@layout/activity_main" tools:context=".MainActivity"> <ListView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/listView" android:layout_gravity="top" android:layout_weight="1" /> </LinearLayout> |
We can now go on and create a custom list adapter. When we use a ListView it is necessary to set a listAdapter, which is a class that contains all the settings regarding how to display the actual items, including which layout to use. You could use the default layouts that are available in the system but, since we are going to use our own, we will create our custom class.
This is it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | public class MyListAdapter extends BaseAdapter { Context context; String[] titles; TextView title_text_view; TextView loginID_text_view; TextView psw_text_view; public MyListAdapter(Context context, String[] titles) { this.titles = titles; this.context = context; } @Override public int getCount() { return titles.length; } @Override public Object getItem(int position) { return titles[position]; } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { View view; Account a = PswDatabase.getInstance().getAccountByTitle(titles[position],false); LayoutInflater inflater= (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = inflater.inflate(R.layout.list_adapter_item,null); title_text_view = (TextView) view.findViewById(R.id.list_adapter_item_title); loginID_text_view = (TextView) view.findViewById(R.id.list_adapter_item_loginID); psw_text_view = (TextView) view.findViewById(R.id.list_adapter_item_psw); title_text_view.setText(a.getTitle()); loginID_text_view.setText(a.getId()); psw_text_view.setText(a.getThePassword()); return view; } } |
The class must extend BaseAdapter in order to be used for a ListView.
Most of the inherited methods are pretty self explanatory, but the real stuff happens in the getView function. Here is where the custom view for each item is created. On lines 40 and 41, we use the inflater object to inflate our custom layout in the previously created view. Once the view is ready, we can finally get all the references to our texview.
For each item we have an index, position, and we use that value to get each account object in the database by its title (line 38). We then assign their respective strings (title, login, password) to the textviews. This will run for as many views we need, which are going to be as many as the title array's elements.
At this point all we have to do in get the ListView reference and assign the adapter.
In the MainActivity, create a method called UpdateList() which is called in the onCreate. The method will do what its names suggests it would do, which is updating the listview.
1 2 3 4 5 6 7 8 9 10 11 | void UpdateList() { ListView listView; listView = (ListView)findViewById(R.id.listView); String[] titles = new String[PswDatabase.getInstance().getTitlesList().size()]; titles = PswDatabase.getInstance().getTitlesList().toArray(titles); MyListAdapter adapter = new MyListAdapter(MainActivity.this,titles); listView.setAdapter(adapter); } |
We firstly get our list view reference form the layout. We then get the list of titles from the database. the method used was not implemented in the previous post, and it is displayed below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public List<String> getTitlesList() { List<String> titles = new ArrayList<String>(); SQLiteDatabase db = getReadableDatabase(); Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_NAME,null); if(cursor.moveToFirst()) { do{ String s = cursor.getString(1); titles.add(s); }while(cursor.moveToNext()); } return titles; } |
We should now ready to go. You should place a call to UpdateList every time the database is changed, so the list will be updated as well..
Imagine we had added 2 accounts in our database. Using our PswDatabase class we wrote last time, we would proceeed like this:
1 2 | Account a1 = new Account("Gmail account","myusername@gmail.com","mypassword"); Account a2 = new Account("Youtube account","myyoutube username","myyoutubePassw0rd"); |
Once the list is updated, you should see this:
Conclusion
We should now have a working database with a ListView that displays the information to the user. This will conclude the topic. It wold be possible to add buttons to edit and delete each record. All you would have to do is to add the actual Button view in the layout, reference it in the MyListAdapter class, set an on click listener that calls the deleteAccountByTitle method in the database class. That simple.And of course, a better design would not hurt, but this is a good example on how to use a list view efficiently.