2

I have created a Navigation Drawer following a tutorial, but now I have a problem. How can I use it in multiple activities without duplicating the code? I tried extending the main activity, but I found some problems with Toolbar. There's some other way? Thanks, this is my code.

MainActivity.java

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    class NavItem {
        String mTitle;
        int mIcon;

        public NavItem(String title, int icon) {
            mTitle = title;
            mIcon = icon;
        }
    }

    class DrawerListAdapter extends BaseAdapter {

        Context mContext;
        ArrayList<NavItem> mNavItems;

        public DrawerListAdapter(Context context, ArrayList<NavItem> navItems) {
            mContext = context;
            mNavItems = navItems;
        }

        public int getCount() {
            return mNavItems.size();
        }

        public Object getItem(int position) {
            return mNavItems.get(position);
        }

        public long getItemId(int position) {
            return 0;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            View view;

            if (convertView == null) {
                LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                view = inflater.inflate(R.layout.drawer_item, parent, false);
            }
            else {
                view = convertView;
            }

            TextView titleView = (TextView) view.findViewById(R.id.title);
            ImageView iconView = (ImageView) view.findViewById(R.id.icon);

            titleView.setText( mNavItems.get(position).mTitle );
            iconView.setImageResource(mNavItems.get(position).mIcon);

            return view;
        }
    }

    ListView mDrawerList;
    RelativeLayout mDrawerPane;

    private static String TAG = MainActivity.class.getSimpleName();

    private ActionBarDrawerToggle mDrawerToggle;
    private DrawerLayout mDrawerLayout;

    ArrayList<NavItem> mNavItems = new ArrayList<>();

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        assert getSupportActionBar() != null;
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        mNavItems.add(new NavItem(getString(R.string.home), R.drawable.ic_action_home));
        mNavItems.add(new NavItem(getString(R.string.company), R.drawable.ic_action_company));
        mNavItems.add(new NavItem(getString(R.string.services), R.drawable.ic_action_services));
        mNavItems.add(new NavItem(getString(R.string.solutions), R.drawable.ic_action_solutions));
        mNavItems.add(new NavItem(getString(R.string.case_history), R.drawable.ic_action_case_history));
        mNavItems.add(new NavItem(getString(R.string.contacts), R.drawable.ic_action_contacts));

        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
        mDrawerPane = (RelativeLayout) findViewById(R.id.drawerPane);
        mDrawerList = (ListView) findViewById(R.id.navList);
        DrawerListAdapter adapter = new DrawerListAdapter(this, mNavItems);
        mDrawerList.setAdapter(adapter);

        mDrawerList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                mDrawerLayout.closeDrawer(mDrawerPane);

                if (position == 0) {
                    Intent intent = new Intent(getApplicationContext(), MainActivity.class);
                    startActivity(intent);
                } else if (position == 1) {
                    Intent intent = new Intent(getApplicationContext(), CompanyActivity.class);
                    startActivity(intent);
                }
            }
        });

        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.string.drawer_open, R.string.drawer_close) {
            public void onDrawerOpened(View drawerView) {
                super.onDrawerOpened(drawerView);

                invalidateOptionsMenu();
            }

            public void onDrawerClosed(View drawerView) {
                super.onDrawerClosed(drawerView);
                Log.d(TAG, "onDrawerClosed: " + getTitle());

                invalidateOptionsMenu();
            }
        };

        mDrawerLayout.setDrawerListener(mDrawerToggle);
    }

    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    public boolean onOptionsItemSelected(MenuItem item) {
        return mDrawerToggle.onOptionsItemSelected(item);
    }

    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        mDrawerToggle.syncState();
    }
}

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true" >

    <RelativeLayout
        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"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" >

        <ImageView
            android:contentDescription="@string/app_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/logo" />
    </RelativeLayout>

    <include layout="@layout/side_menu" />
    <include layout="@layout/toolbar" />
</android.support.design.widget.CoordinatorLayout>

side_menu.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginTop="?attr/actionBarSize" >

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

    <RelativeLayout
    android:layout_width="280dp"
    android:layout_height="match_parent"
    android:id="@+id/drawerPane"
    android:layout_gravity="start">

        <ListView
            android:id="@+id/navList"
            android:layout_width="280dp"
            android:layout_height="match_parent"
            android:choiceMode="singleChoice"
            android:background="#FFF" />
    </RelativeLayout>
</android.support.v4.widget.DrawerLayout>

toolbar.xml:

<android.support.design.widget.AppBarLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppTheme.AppBarOverlay" >

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:minHeight="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
Maurizio
  • 19
  • 2
  • 2
    Inheritance is your solution. You should give same id to your drawer layout and toolbar. The override setContentView and init your toolbar and drawer layout. Probably, you want to make them protected to access from subclasses. For more info, you might want to check this link: https://github.com/google/iosched – ycagri Nov 26 '15 at 16:24
  • 1
    I stopped reading this when I saw: `MainActivity.js` – Jared Burrows Nov 26 '15 at 16:49

2 Answers2

0

Here is part of real code from my project. @Bind is from awesome Butterknife library. AbstractToolbarActivity it's a sub class of the AppCompatActivity that follows the same logic (avoiding duplicating code of initializing toolbars)

public abstract class AbstractDrawerActivity extends AbstractToolbarActivity {

  @Bind(R.id.drawer_layout) DrawerLayout mDrawerLayout;

  ActionBarDrawerToggle mDrawerToggle;

  protected void initDrawer() {

    mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolbar, R.string.drawer_open,
        R.string.drawer_close);
    mDrawerToggle.setDrawerIndicatorEnabled(true);
    mDrawerLayout.setDrawerListener(mDrawerToggle);

    if (getSupportActionBar() != null) {
      getSupportActionBar().setDisplayHomeAsUpEnabled(true);
      getSupportActionBar().setHomeButtonEnabled(true);
    }
  }

  @Override protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    initDrawer();
    mDrawerToggle.syncState();
  }

  @OnClick(R.id.drawer_user_name) protected void openProfile() {
    final Intent profile = new Intent(this, ProfileActivity.class);
    startActivity(profile);
  }

  // here some onclicks etc, other methods

  @Override protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);

    if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
      mDrawerLayout.closeDrawers();
    }
  }

  @Override public void onBackPressed() {
    if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
      mDrawerLayout.closeDrawers();
    } else {
      super.onBackPressed();
    }
  }

  @Override protected void onPause() {
    super.onPause();

    if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
      mDrawerLayout.closeDrawers();
    }
  }
}

And AbstractToolbarActivity.java:

public abstract class AbstractToolbarActivity extends AppCompatActivity {

  @Bind(R.id.action_bar) Toolbar mToolbar;

  @Override protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    initToolbar();
  }

  protected void initToolbar() {
    setSupportActionBar(mToolbar);
  }
}
Anton Shkurenko
  • 4,301
  • 5
  • 29
  • 64
0

Create a baseactivity with your drawer inside and then extend base activity to all activities in which you want drawer. And instead of calling setcontentview() in oncreate inheriting activities use layout inflator

Check this post

How to Display Navigation Drawer in all activities?

Community
  • 1
  • 1
farhan patel
  • 1,490
  • 2
  • 19
  • 30