Posted :
A
ListView is a list of views , this tutorial
will show how to
implement a ListView in android . The final
product is shown below .
Start
by creating the application
main activity layout
file ,
activity_main.xml :
<!-- activity_main.xml -->
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
tools:context=".MainActivity">
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@android:color/white"
android:dividerHeight="1dp"
android:headerDividersEnabled="false"
android:footerDividersEnabled="true"
android:listSelector="@drawable/lv_item_pressed"
android:background="@android:color/black" />
</FrameLayout>
The
layout of this activity is a FrameLayout , a
frame layout stacks its childrens on top of one another ,
this layout has only one child ,
which is the ListView .
The
majority of the attributes set for the
ListView
are self explanatory , such as the
layout_width or
layout_height .
The listSelector is just the effect ,
for when an item in the ListView is
selected , in this example a drawable is drawn .
The divider
is the divider between the views in the ListView .
A ListView can have a header , and a footer ,
the headerDividersEnabled , and
footerDividersEnabled
, allows the header and the footer to have a divider displayed .
Having
specified the layout attributes for the ListView ,
it is now time to
create the view for an item in the ListView .
In this example , each
alternate row will have its own view , as such there
are two layout defined , list_view_item.xml ,
and list_view_item_alt.xml .
<!-- list_view_item.xml -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/lv_item_name"
android:layout_width="0dp"
android:layout_weight="6"
android:layout_height="wrap_content"
android:paddingTop="4dp"
android:paddingBottom="4dp"
android:textColor="@color/colorPrimary"
android:textSize="25sp"
android:gravity="center_horizontal" />
<ImageView
android:id="@+id/lv_item_img"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="match_parent" />
<TextView
android:id="@+id/lv_item_time"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="match_parent"
android:paddingEnd="4dp"
android:textColor="@color/colorAccent"
android:textSize="14sp"
android:gravity="center" />
</LinearLayout>
<!-- list_view_item_alt.xml -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/lv_item_img"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="match_parent" />
<TextView
android:id="@+id/lv_item_name"
android:layout_width="0dp"
android:layout_weight="6"
android:layout_height="wrap_content"
android:paddingTop="4dp"
android:paddingBottom="4dp"
android:textColor="@color/colorPrimary"
android:textSize="24sp"
android:gravity="center_horizontal" />
<TextView
android:id="@+id/lv_item_time"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="match_parent"
android:paddingStart="4dp"
android:textColor="@color/colorAccent"
android:textSize="14sp"
android:gravity="center" />
</LinearLayout>
Having
created the layout of the items
to be displayed
in the ListView , it is now time
to create the controller , which will manage
each item creation and display in the ListView ,
this is done by
extending the BaseAdapter class ,
like so :
package com .twiserandom .mobileapps .demo .listview;
import android .content .Context;
import android .view .View;
import android .view .ViewGroup;
import android .widget .BaseAdapter;
import android .widget .ImageView;
import android .widget .TextView;
public class
ListViewController
extends BaseAdapter {
private Context context;
private String names [ ] = {"armin" , "callum" , "eric" , "meg" , "michael" };
private int img_ids[ ] = {R .drawable .armin , R .drawable .callum , R .drawable .eric ,
R .drawable .meg , R .drawable .michael };
private String last_seens [ ] = {"seen 1hr ago" , "seen 1mn ago" , "seen 1 sec ago" ,
"seen 2hr ago" , "seen 3mn ago"};
ListViewController
(Context context ){
this .context = context; }
class
Person {
String name;
int img_id;
String last_seen;
Person
(String name , int img_id , String last_seen ){
this .name = name;
this .img_id = img_id;
this .last_seen = last_seen; }}
@Override
public int
getCount ( ){/*
Return the number of data
elements .*/
return names .length; }
@Override
public Object
getItem
(int position ){/* Can return null ,
if have nothing to pass on .
Data passed here can be gotten ,
for example when implementing
a click listener for an item
in the ListView .*/
return new Person (names [position ] ,
img_ids [position ] ,
last_seens [position ] ); }
@Override
public long
getItemId
(int position ){/* Can return 0
, or -1 , if don't have own
generated IDs , or if not
interested in this method .
This created id can be used
for example , when implementing
a click listener for an item in
the ListView .*/
return img_ids[position ]; }
@Override
public View
getView
(int position, View convertView , ViewGroup parent ){/* Return a view
to be displayed in
the ListView .*/
if (convertView == null ){/* The items in
the list view are
recyclable , which means they
are reusable , so only inflate an
item in the ListView when
necessary .*/
if (position % 2 == 0 )/* If position is
even , inflate
the even list view item .*/
convertView = View .inflate (context , R .layout .list_view_item , null );
else /* else inflate the odd list view
item .*/
convertView = View .inflate (context , R .layout .list_view_item_alt , null ); }
/* Set the data to be displayed */
TextView tv_name = (TextView ) convertView .findViewById (R .id .lv_item_name );
tv_name .setText (names [position ]);
TextView tv_date = (TextView ) convertView .findViewById (R .id .lv_item_time );
tv_date .setText (last_seens [position ]);
ImageView iv_picture = (ImageView ) convertView .findViewById (R .id .lv_item_img );
iv_picture .setImageResource (img_ids [position ]);
return convertView;
/* Return the view to be displayed */ } }
Having
created the controller class , it is now time
to
create the MainActivity class ,
which
will connect the ListView to
its controller , and where
a header , and a footer , will also be added
to the ListView .
/* MainActivity.java */
package com .twiserandom .mobileapps .demo .delete;
import androidx .appcompat .app .AppCompatActivity;
import android .os .Bundle;
import android .view .View;
import android .view .ViewGroup;
import android .widget .AdapterView;
import android .widget .ListView;
import android .widget .TextView;
import android .widget .Toast;
public class
MainActivity
extends AppCompatActivity {
@Override
protected void
onCreate (Bundle savedInstanceState ){
super .onCreate (savedInstanceState );
setContentView (R .layout .activity_main );
ListView lv = findViewById (R .id .list_view );
/* Get the ListView */
View header = View .inflate (this , R .layout .list_view_header , null );
/* Inflate the header layout , and add it to the list view .*/
lv .addHeaderView (header );
View footer = View .inflate(this , R .layout .list_view_footer , null );
/* Inflate the footer layout , and add it to the list view .*/
lv .addFooterView (footer );
lv .setAdapter (new ListViewController (this ) );
/* Connect the controller to the list view .*/
lv .setOnItemClickListener (new AdapterView .OnItemClickListener ( ){
/* Add an item click listener for the list view ,
other types of listeners exist , such as
setOnItemLongClickListener .*/
@Override
public void
onItemClick
(AdapterView > parent , View view , int position , long id ){
ListViewController .Person person =
(ListViewController .Person ) parent .getItemAtPosition (position );
/* Get the data attached in the getItem method
of the controller .*/
Toast .makeText (MainActivity .this ,
person .name + " " + person .last_seen ,
Toast.LENGTH_LONG)
.show ( );/* Show a toast containing
the person name , and last seen .*/ } }); }}
In
the preceding code , a header , and a footer
were added to the ListView ,
so
the header and footer
must have a layout .
These must have
layouts , were inflated in the MainActivity, and
are the following :
<!-- list_view_header.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="match_parent"
android:layout_height="wrap_content"
android:text="Conversations"
android:textSize="32sp"
android:textColor="@android:color/holo_orange_light"
android:gravity="center" />
</LinearLayout>
<!-- list_view_footer.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="match_parent"
android:layout_height="wrap_content"
android:text="@~"
android:textSize="32sp"
android:gravity="center" />
</LinearLayout>
The
listSelector for the ListView
specified in activity_main.xml as
android:listSelector="@drawable/lv_item_pressed" ,
refers to a drawable .
The drawable
set the pressed
item to have a white background , as shown below :
<!-- lv_item_pressed.xml -->
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white"
android:state_pressed="true"/>
<!-- item pressed -->
</selector>