Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Navigation Drawer (calling activities) with AbstractMainActivity

I want to have a AbstractMainActivity which creates the Navigation Drawer. In there I should also handle the clicks on the menu items and then call new activities. In those activities, I want to again use the same Navigation Drawer.

I would extend in the Subclasses with the AbstractMainActivity and call the getLayoutResourceID differently from each subclass (as suggested here: android how to create my own Activity and extend it?).

The problem is, that now in the AbstractMainActivity where I want to build the Navigation Drawer, I do not have any access to the navigation drawer layout (xml) element, as I of course want to have a different base layout for the subclasses.

Would I need to "include layout" in all the subclasses layout files? But this does not work, what do I do wrong if I want to use Activities instead of Fragments with the Navigation Drawer?

public abstract class MainActivity extends Activity {

private String[] menuItems;
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //setContentView(R.layout.activity_main);

    setContentView(getLayoutResourceId());

    menuItems = getResources().getStringArray(R.array.menu_items);
    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    mDrawerList = (ListView) findViewById(R.id.left_drawer);

    // Set the adapter for the list view
    mDrawerList.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, menuItems));
    // Set the list's click listener
    mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

}


protected abstract int getLayoutResourceId();

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}


private class DrawerItemClickListener implements ListView.OnItemClickListener {
    @Override
    public void onItemClick(AdapterView parent, View view, int position, long id) {
        selectItem(position);
    }

    /** Swaps fragments in the main content view */
    private void selectItem(int position) {
        //Fragment fragment = new PlanetFragment();
        Bundle args = new Bundle();
       // args.putInt(PlanetFragment.ARG_PLANET_NUMBER, position);

        Intent intent = new Intent(MainActivity.this, ProductListActivity.class);
        startActivity(intent);

    }
}




public class ProductListActivity extends MainActivity {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.options_menu, menu);
    return true;
}

@Override
protected int getLayoutResourceId() {
    // TODO Auto-generated method stub
    return R.layout.activity_product_list;
}

This is the layout of the product list sub-class (activity_product_list.xml):

<RelativeLayout 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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".ProductList" >

<include layout="@layout/activity_main"/>

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

This is the layout of the navigation drawer (activity_main.xml):

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android1="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="300dp"
android:layout_height="500dp" >

<!-- The main content view -->
<FrameLayout
    android:id="@+id/content_frame"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
<!-- The navigation drawer -->
<ListView android:id="@+id/left_drawer"
    android:layout_width="240dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:choiceMode="singleChoice"
    android:divider="@android:color/transparent"
    android:dividerHeight="0dp"
    android:background="#c3c3c3"/>

But the does not work, but if I do not have it, I get null-pointer exceptions when my subclass calls the onCreate of the abstract class, where I want to build the Navigation Drawer, it does not find the layout-elements to set the lists and layout (R.id.left_drawer or R.id.drawer_layout)!

like image 207
fischer_zh Avatar asked Jul 28 '13 12:07

fischer_zh


1 Answers

I'm also trying to figure out how to do this.

I've seen a very good tutorial that does exactly what you want here. The idea is to create an abstract activity class AbstractNavDrawerActivity that all activities with drawers will inherit from. This class uses a NavDrawerActivityConfiguration bean class that holds all the information about the nav drawer including the layout that needs to be inflated

Another approach would be creating a NavDrawerUtil class where you would put static methods that interact with the nav drawer. You would then call these methods from each activity as you need.

The second approach gives you more flexibility and you don't have to worry about order of layout inflations and such but I think it's a less clean solution than the first one with the AbstractNavDrawerActivity that all activities with nav drawer inherit from like you suggested.

like image 150
Michael Avatar answered Oct 24 '22 23:10

Michael