Search code examples
androidlistviewlistadapterbaseadapter

BaseAdapter not populating listview


So i have a base adapter class that I built. I also try to use this in one of my activities. I have a xml for the parent layout and an xml for the rows to inflate. However, these components are not linking together. The app doesnt crash but the rows are not inflated (although the parent xml file still displays on the creen). Could some look at my code and tell me what critical component i am overlooking? I will only post the relevant code. Cant post the error logs since no errors are occurring. Thanks very much

Parent XML (nearby_places_list)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp"
    android:orientation="vertical"
    android:background="@drawable/bg">

   <Button
    android:id="@+id/continuetomap"
    android:layout_height="100dp"
    android:layout_width="match_parent"
    android:background="@drawable/map_continue"
    />

   <ListView
       android:id="@+id/list_view_nearby"
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       android:divider="#b5b5b5"
       android:listSelector="@drawable/list_selector">
   </ListView>


</LinearLayout>

Row to Inflate XML (nearby_list_row)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="5dp"
        android:orientation="vertical"
        android:background="@drawable/list_selector">"

        <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        android:background="@drawable/list_selector">

            <LinearLayout
            android:layout_width="0dp"
            android:layout_weight="3"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:background="@drawable/list_selector">
                <TextView
                    android:id= "@+id/name"        
                    android:textSize="20dp" 
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:text="name"
                    android:textColor="#54944d"/>
                 <TextView
                    android:id= "@+id/vicinity"        
                    android:textSize="20dp" 
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:text="vicinity"
                    android:textColor="#000000"/>
                  <TextView
                    android:id= "@+id/openorclosed"
                    android:textSize="20dp"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:text="Open"
                    android:textColor="#000000"
                    android:textStyle="bold"/>    
                    </LinearLayout>


            <RelativeLayout
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="0.74" >

                 <Button
                android:layout_width="60dp"
                android:id="@+id/button_add_to_fav"
                android:background="@drawable/add_square"
                android:layout_height="60dp"
                android:layout_alignParentRight="true"
                />

               <Button
                android:layout_width="60dp"
                android:id="@+id/button_call_rest"
                android:background="@drawable/add_square"
                android:layout_height="60dp"
                android:layout_alignParentRight="true"
                android:layout_below="@+id/button_add_to_fav"
                />

            </RelativeLayout>

          </LinearLayout>


    </RelativeLayout>

Base Adapter Class

public class AdapterForList extends BaseAdapter {

    private final Context context;
    private final ArrayList<HashMap<String, String>> alHm;
    private final String TAG_A;
    private final String TAG_B;
    private final String TAG_C;


    public AdapterForList(Context context, ArrayList<HashMap<String, String>> alhm, String TAG_1, String TAG_2, String TAG_3) {
        super();
        this.context = context;
        this.alHm = alhm;
        TAG_A = TAG_1;
        TAG_B = TAG_2;
        TAG_C = TAG_3;
    }

    @Override
    public View getView(int position, View convertView , ViewGroup parent){
        LayoutInflater inflator = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        convertView = inflator.inflate(R.layout.nearby_list_row, parent, false);
        TextView tv1 = (TextView) convertView.findViewById(R.id.name);
        TextView tv2 = (TextView) convertView.findViewById(R.id.vicinity);
        TextView tv3 = (TextView) convertView.findViewById(R.id.openorclosed);
        Button btnAdd= (Button) convertView.findViewById(R.id.button_add_to_fav);
        Button btnCall= (Button) convertView.findViewById(R.id.button_call_rest);

        if (alHm.get(position).containsKey(TAG_A)){  // get the value from the key (if it exist) and set the first text view to it 
            String value = alHm.get(position).get(TAG_A);
            tv1.setText(value);;
        }

        if (alHm.get(position).containsKey(TAG_B)){   
            String value = alHm.get(position).get(TAG_B);
            tv2.setText(value);;
        }

        if (alHm.get(position).containsKey(TAG_C)){  // get the value from the key (if it exist) and set the first text view to it 
            String value = alHm.get(position).get(TAG_C);
            tv3.setText(value);;
        }

        return convertView;
    }
    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return alHm.size();
    }
    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return position;
    }
    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }

}

Relevant activity code

protected void onPostExecute(Boolean result){
    if (result){
        // adding data to listview
        final ListView lv = (ListView) findViewById(R.id.list_view_nearby);
        lv.setAdapter(new AdapterForList(context, listOfHM, JSONextractor.TAG_NAME,   
            JSONextractor.TAG_VICINITY,  JSONextractor.TAG_OPERATINGHOURS_OPENNOW));

        //more code ...

    }
}

Solution

  • So it turns out my code did work (but not optimally). I posted below how to correctly use the base adapter

    Just read the article (really opened my mind) posed by savadow. basically the way i have my BaseAdapter im not utilizing any of the optimization ability of the class. Instead I will change the code to the following in the base adapter class.

    http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/

    public View getView(int position, View convertView , ViewGroup parent){
            LayoutInflater inflator = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            if (convertView == null){  
            convertView = inflator.inflate(R.layout.nearby_list_row, parent, false);
            }
            // now if the convertView is not null i simply update the values rather than re-inflate the view (inflating is expensive)
    
            tv1 = (TextView) convertView.findViewById(R.id.name);
            tv2 = (TextView) convertView.findViewById(R.id.vicinity);
            tv3 = (TextView) convertView.findViewById(R.id.openorclosed);
            btnAdd= (Button) convertView.findViewById(R.id.button_add_to_fav);
            btnCall= (Button) convertView.findViewById(R.id.button_call_rest);