Search code examples
javaandroidxmlandroid-layoutlistadapter

Advice on android setlistadapter and combining two .xml layout


I am using two list adapter as shown on code below. resultList and resultList2 are initialized with new ArrayList <HashMap<String,String>>();

ListAdapter adapter, adapter2;
adapter =new SimpleAdapter(
                getActivity(), resultList, 
                R.layout.list_item1, new String[]{TAG_ID, TAG_FRUIT, TAG_SPECIES},
                new int[]{R.id.Id,R.id.fruit,R.id.species});
adapter2=new SimpleAdapter(
                getActivity(), resultList2, 
                R.layout.list_item_append, new String[]{ TAG_NAME, TAG_ADDRESS, TAG_EMAIL},
                new int[]{ R.id.name, R.id.address, R.id.email});
setListAdapter(adapter);
setListAdapter(adapter2);    //this line has overriden setListAdapter(adapter)

I have two layouts named list_item1.xml and list_item2.xml.

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

     <TextView
        android:id="@+id/Id"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingTop="6dip"
        android:paddingLeft="6dip"
        android:textSize="17sp"
        android:textStyle="bold"
        android:descendantFocusability="blocksDescendants"
        android:visibility="gone"/><!--android:visibility="gone"  --> 

    <TextView
        android:id="@+id/fruit"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingTop="6dip"
        android:paddingLeft="6dip"
        android:textSize="17sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/species"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingTop="6dip"
        android:paddingLeft="6dip"
        android:textSize="17sp"
        android:textStyle="bold" />
</LinearLayout>

second layout: list_item2.xml
list_item.xml

 <TextView
    android:id="@+id/name"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:paddingTop="6dip"
    android:paddingLeft="6dip"
    android:textSize="17sp"
    android:textStyle="bold" />

<TextView
    android:id="@+id/address"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:paddingTop="6dip"
    android:paddingLeft="6dip"
    android:textSize="17sp"
    android:textStyle="bold" />

<TextView
    android:id="@+id/email"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:paddingTop="6dip"
    android:paddingLeft="6dip"
    android:textSize="17sp"
    android:textStyle="bold" />

I have tried to use <include> and <merge> in my new layout but it is not the result I wanted. The result shows all the elements in adapter2. But there are empty list element before each of the adapter2 elements.

My expected result are:
adapter....
adapter....
adapter...
adapter2...
adapter2...
adapter2...

How can I achieve this? I think that setListAdapter is the cause of the problem.

The reason i used two listadapter is because i am trying two fetch two set of data from my database. The data is fetch from the table named tblfruit and tblperson.

    $response["results"] = array();
    $response["results2"] = array();
    // temp user array
    $results = array();
    $results2=array();

    while ($row = mysql_fetch_array($result)){
        $results["id"] = $row["id"];
        $results["fruit"] = $row["fruit"];
        $results["species"] = $row["species"];
        array_push($response["results"], $results);
    }
    while ($row = mysql_fetch_array($result2)){
        $results2["name"] = $row["name"];
        $results2["address"] = $row["address"];
        $results2["email"] = $row["email"];
        array_push($response["results2"], $results2);
    }

Solution

  • Extend ListAdapter and inflate each row with your desired layout within the Adapter's View.getView() method. This method is called once for each row in the ListView (or record inside the adapter, if you want to be specific). It is used to set up (or, well, inflate) the view for each record, and doing things such as setting the value of TextView's, ImageView's, hiding unnecessary components for each row, etc. I haven't tried this with two differente layout resources myself, but I suppose it can be done with this approach.

    public class CustomListAdapter extends ArrayAdapter<CustomObject> {
    
        private Context context;
        private int layoutResourceId_1;
        private int layoutResourceId_2
        private List<CustomObject> list;
    
        public CustomListAdapter(Context context, int layoutResourceId_1, int layoutResourceId_2, List<CustomObject> list) {
            super(context, layoutResourceId_1, list);
            this.context = context;
            this.layoutResourceId_1 = layoutResourceId_1;
            this.layoutResourceId_2 = layoutResourceId_2;
            this.list = list;
        }
    
        ...
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View row = convertView;
    
            LayoutInflater layoutInflater = ((Activity) context).getLayoutInflater();
    
            if(condition_layout_1()) {
                row = layoutInflater.inflate(layoutResourceId_1, parent, false);
                // Use a holder to prepare item
                ...
            } else {
                row = layoutInflater.inflate(layoutResourceId_2, parent, false);
                // Use a holder to prepare item
                ...
            }
    
            return row;
        }
    
        ...
    }