Custom adapter for navigation drawer

pez picture pez · Nov 22, 2014 · Viewed 8.6k times · Source

I have a working navigation drawer that uses ArrayAdapter as shown in the documentation. I want to set ImageView icons for each of the navigation drawer items, so I need to create a custom adapter to use, but I am unsure of how to do that. What I have below runs without crashing the app, but the navigation drawer opens up empty, with nothing in it. Can you please help me out? Thanks in advance!

What I've done for a custom adapter so far:

public class CustomAdapter extends ArrayAdapter
{
    private final Context context;

    public CustomAdapter(Context context)
    {
       super(context, R.layout.drawer_list_item);
       this.context = context;
    }

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

        View v = inflater.inflate(R.layout.drawer_list_item, parent, false);
        TextView textViewHome = (TextView) v.findViewById(R.id.drawerHomeTextView);
        ImageView imageViewHome = (ImageView) v.findViewById(R.id.drawerHomeImage);
        TextView textViewList = (TextView) v.findViewById(R.id.drawerListTextView);
        ImageView imageViewList = (ImageView) v.findViewById(R.id.drawerListImage);

        return v;
    }
}

Setting up the drawer in MainActivity:

mDrawerList = (ListView) findViewById(R.id.leftDrawer);

mDrawerList.setAdapter(new CustomAdapter(this));

The ListView used:

<ListView android:id="@+id/leftDrawer"
    android:layout_width="240dp"
    android:layout_height="match_parent"
    android:layout_gravity="left"
    android:choiceMode="singleChoice"
    android:divider="@android:color/transparent"
    android:dividerHeight="0dp"
    android:background="#111"/>

drawer_list_item.xml:

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

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="wrap_content"
    android:layout_width="match_parent">

    <RelativeLayout
        android:id="@+id/drawerRelativeLayoutHome"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <ImageView
            android:id="@+id/drawerHomeImage"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_centerVertical="true"
            android:paddingStart="4dp"
            android:paddingEnd="4dp"
            android:paddingLeft="4dp"
            android:src="@drawable/ic_menu_home"/>

        <TextView
            android:id="@+id/drawerHomeTextView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@+id/drawerHomeImage"
            android:layout_toEndOf="@+id/drawerHomeImage"
            android:background="@drawable/background_activated"
            android:paddingLeft="4dp"
            android:paddingRight="4dp"
            android:paddingTop="12dp"
            android:paddingBottom="12dp"
            android:text="Home"
            android:textSize="20sp"/>
    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/drawerRelativeLayoutList"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/drawerRelativeLayoutHome">

        <!-- same as above, but ic_menu_archive as drawable, and "List" as text -->

    </RelativeLayout>

</RelativeLayout>

Answer

OnThisDayFiftyYearsAgo picture OnThisDayFiftyYearsAgo · Nov 30, 2014

For your custom adapter:

public class NavDrawerAdapter extends ArrayAdapter<NavDrawerItem>
{
    private final Context context;
    private final int layoutResourceId;
    private NavDrawerItem data[] = null;

    public NavDrawerAdapter(Context context, int layoutResourceId, NavDrawerItem [] data)
    {
        super(context, layoutResourceId, data);
        this.context = context;
        this.layoutResourceId = layoutResourceId;
        this.data = data;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        LayoutInflater inflater = ((Activity) context).getLayoutInflater();

        View v = inflater.inflate(layoutResourceId, parent, false);

        ImageView imageView = (ImageView) v.findViewById(R.id.navDrawerImageView);
        TextView textView = (TextView) v.findViewById(R.id.navDrawerTextView);

        NavDrawerItem choice = data[position];

        imageView.setImageResource(choice.icon);
        textView.setText(choice.name);

        return v;
    }
}

For NavDrawerItem:

public class NavDrawerItem
{
    public int icon;
    public String name;

    public NavDrawerItem(int icon, String name)
    {
        this.icon = icon;
        this.name = name;
    }
}

For drawer_list_item.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:background="?android:attr/activatedBackgroundIndicator"
    android:minHeight="?android:attr/listPreferredItemHeightSmall"
    android:padding ="10dp">

    <ImageView
        android:id="@+id/navDrawerImageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:paddingRight="10dp"/>

    <TextView
       android:id="@+id/navDrawerTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_toRightOf="@+id/navDrawerImageView"
        android:paddingRight="10dp"
        android:textAppearance="?android:attr/textAppearanceListItemSmall"/>

</RelativeLayout>

In MainActivity.java, instantiate an array of NavDrawerItem objects, with the appropriate drawable and name for each, and then pass this array when you set the adapter, like so:

mDrawerList.setAdapter(new YourAdapter(this, R.layout.drawer_list_item, yourArray));