Friday, February 3, 2012

Custom ListView with sliding view for each list

We shall look at creating a custom list view – a custom layout, a custom row layout and how we bind the custom data holder to these layouts. The custom row layout consists of five textViews and an Image Button.


At the end of this tutorial you would be able to perform a sliding view for each listview like this.


Before Click

After Click




First let us create a list view object file which contains a list view - custom_list_view.xml.


custom_list_view.xml
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
Creating a list view will
look like this (in eclipse)
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >


    <ListView
        android:id="@+id/listView1:list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>


</LinearLayout>




Note that it must contain a ListView object with android:id="@id/android:list"




Now we will declare how each row in this ListView should be displayed by creating a new xml file –custom_row_view.xml


custom_row_view.xml


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/RelativeLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <LinearLayout
        android:id="@+id/linearLayout1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_toLeftOf="@+id/linearLayout3"
        android:orientation="vertical" >


        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Medium Text"
            android:textAppearance="?android:attr/textAppearanceMedium" />


        <TextView
            android:id="@+id/textView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Small Text"
            android:textAppearance="?android:attr/textAppearanceSmall" />


        <TextView
            android:id="@+id/textView3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Small Text"
            android:textAppearance="?android:attr/textAppearanceSmall" />
    </LinearLayout>


<LinearLayout
        android:id="@+id/linearLayout3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/linearLayout1"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:baselineAligned="false" >


<ImageView
          android:id="@+id/imageView1"
          android:layout_width="25dp"
          android:layout_height="match_parent"
          android:background="@drawable/slide_image"
          android:onClick="myClickHandler"
          android:src="@drawable/double_arrow_left" android:padding="5px"/>




        <LinearLayout
            android:id="@+id/linearLayout2"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@color/bg_brown_color"
            android:orientation="vertical"
            android:paddingLeft="5px" >


            <TextView
                android:id="@+id/textView4"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="18dp"
                android:layout_marginRight="16dp"
                android:text="@string/replies"
                android:textAppearance="?android:attr/textAppearanceSmall" android:textColor="@color/black_color"/>


            <TextView
                android:id="@+id/textView5"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/views"
                android:textAppearance="?android:attr/textAppearanceSmall" android:textColor="@color/black_color"/>
        </LinearLayout>
    </LinearLayout>
</RelativeLayout>

      
Note that the visibility of the LinearLayout is set to gone i.e. it does not get displayed initially. We will make it visible when the imageButton will be clicked that we will perform in the Java file

Now we will make the java file which will help us display the custom layout integrating the custom_row_layout into the listView 
I plan to have 6 items one below the other in each row (1-ImageView, 5-textViews). So, here is the declaration for the same – CustomListView.java


CustomListView.java

package org.learning;

import java.util.*;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.*;
public class LearningActivity extends Activity {
     ListView lw;
private SimpleAdapter adapter;
private ArrayList<HashMap<String, String>> list;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.custom_list_view);
        lw=(ListView) findViewById(R.id.listView1_list);
        list = new ArrayList<HashMap<String,String>>();
        populateList();
        adapter = new SimpleAdapter(
        this,
        list,
        R.layout.custom_row_view,
        new String[] {"title","threadID","startedBy"},
        new int[] {R.id.textView1,R.id.textView2,R.id.textView3}
        );
        lw.setAdapter(adapter);
        lw.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
//Code for performing the on list view listener.
}
});
        findViewById(R.id.linearLayout1);
    }
    public void myClickHandler(View v) {
    LinearLayout vwParentRow = (LinearLayout)v.getParent();
    ImageView iv= (ImageView) vwParentRow.getChildAt(0);
    LinearLayout lw=(LinearLayout) vwParentRow.getChildAt(1);
    if(lw.getVisibility()==View.GONE){
    lw.setVisibility(View.VISIBLE);
    iv.setImageResource(R.drawable.double_arrow_right);
        }else{
            lw.setVisibility(View.GONE);
    iv.setImageResource(R.drawable.double_arrow_left);
    }
    }
    
    void populateList(){
    HashMap<String,String> temp = new HashMap<String,String>();
    temp.put("title","Title");
temp.put("threadID","Sub - Title - 1");
temp.put("startedBy","Sub - Title - 2");
list.add(temp);
     temp.put("title","Title");
temp.put("threadID","Sub - Title - 1");
temp.put("startedBy","Sub - Title - 2");
list.add(temp);
temp.put("title","Title");
temp.put("threadID","Sub - Title - 1");
temp.put("startedBy","Sub - Title - 2");
list.add(temp);
    }
}

Here we have set the default view to custom_list_view. Then, using the  SimpleAdapter, we have set the context, the list containing the data for display, the  custom_row_view, the keys by which the data has to be fetched from the list, the TextViews into which the corresponding data has to be displayed. Now execute and you will have a custom list view and this is what u will see:



You can download the complete source code here.

4 comments:

  1. nice oneeee... how about when the two text views are align after all?

    ReplyDelete
    Replies
    1. i didn't get you. Which text views you want to align?

      Delete
  2. can you explain the arguments of simpleAdapter constructor ?

    ReplyDelete
    Replies
    1. this - specifies the class

      list - array list (list = new ArrayList>();)

      R.layout.custom_row_view - defines an XML layout file which we require for each row. it is defined in layout folder with an XML extension as custom_row_view.xml

      new String[] {"title","threadID","startedBy"} - defines the parameters KEY value which u are going to send in to the adapter as KEY VALUES, u can check the populate() function in which i have mapped those same KEY's as temp.put("title","Title");

      new int[] {R.id.textView1,R.id.textView2,R.id.textView3 - this speifies which textview is to be updated. title is mapped with textview1 and so on. textView1 is defined in the custom_row_view.xml which we previously created.

      Delete