I have an app I am writing and it is already contains a lot of code, I decided I want to add a navigation drawer to the main activity toolbar but I don't know how to do it without creating a new navigation drawer project and copy my whole project to it which seems like a lot of work, is there a tutorial to add a navigation drawer to an existing project?
To add a navigation drawer, first declare a DrawerLayout as the root view. Inside the DrawerLayout , add a layout for the main UI content and another view that contains the contents of the navigation drawer.
Navigation drawer used to navigate many screens or functionalities of the app by clicking on the 'hamburger' icon. Swiping from the left is also a way to bring the drawer into view, a screen then slides in, showing many items.
set DrawerLayout tools:openDrawer="end" set NavigationView android:layout_gravity="end" change tag view from androidx.
DrawerLayout acts as a top-level container for window content that allows for interactive "drawer" views to be pulled out from one or both vertical edges of the window.
Create a layout layout_left_menu.xml:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/bgLeftMenu"> <ImageView android:id="@+id/header" android:src="@drawable/ic_launcher" android:layout_width="48dp" android:layout_height="48dp" android:layout_marginTop="26dp" android:layout_marginBottom="8dp" android:layout_marginLeft="30dp" android:layout_marginStart="40dp"/> <RelativeLayout android:layout_width="wrap_content" android:layout_height="48dp" android:layout_marginTop="26dp" android:layout_marginLeft="10dp" android:layout_toRightOf="@id/header"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" android:layout_centerInParent="true"> <TextView android:id="@+id/userName" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/app_name" android:textColor="@color/pressed"/> <TextView android:id="@+id/userEmail" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/app_name" android:layout_below="@id/userName" android:layout_centerInParent="true" android:textColor="@color/pressed" android:visibility="gone"/> </LinearLayout> </RelativeLayout> <ListView android:id="@+id/menu_items_list" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/header" android:dividerHeight="0dp" android:divider="@null" android:background="@color/bgLeftMenu"/> <ProgressBar android:id="@+id/progress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:visibility="gone"/> </RelativeLayout>
Inflate it in a Custom View:
public class SimpleLeftMenuView extends NavigationView { private LayoutInflater mInflater; private Context mContext; private ListView mItemsList; private MenuItemsAdapter mItemsAdapter; private ProgressBar mProgress; private OnClickMenu mListener; private ImageView mHeader; private TextView userName; private TextView userEmail; //region Constructors public SimpleLeftMenuView(Context context) { super(context); mContext = context; mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); initLayout(); setData(); } public SimpleLeftMenuView(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); initLayout(); setData(); } public SimpleLeftMenuView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mContext = context; mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); initLayout(); setData(); } //endregion private void initLayout(){ mInflater.inflate(R.layout.layout_left_menu, this); mItemsList = (ListView) findViewById(R.id.menu_items_list); mProgress = (ProgressBar) findViewById(R.id.progress); mHeader = (ImageView) findViewById(R.id.header); userName = (TextView) findViewById(R.id.userName); userEmail = (TextView) findViewById(R.id.userEmail); mHeader.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // do something } }); } public void setSelectedSection(String idSection) { mItemsAdapter.setLastSelectedSection(idSection); } public void setmListener(OnClickMenu mListener) { this.mListener = mListener; } private void setData() { List<String> sections = new ArrayList<>(); sections.add(mContext.getString(R.string.home_id)); sections.add(mContext.getString(R.string.login_id)); sections.add(mContext.getString(R.string.settings_id)); //......... //sections.add(mContext.getString(R.string.exit_id)); mItemsAdapter = new MenuItemsAdapter(mContext, sections, new OnClickMenu() { @Override public void onClick(String id) { mItemsAdapter.setLastSelectedSection(id); if (mListener != null) mListener.onClick(id); } }); mItemsList.setAdapter(mItemsAdapter); mItemsList.setSelection(0); mItemsList.setItemChecked(0, true); } }
You have to create the MenuItemAdapter.
public class MenuItemsAdapter extends BaseAdapter { private Context mContext; private static String lastSelectedSection; private List<String> mSections; private int currentTextcolor; private OnClickMenu mListener; public MenuItemsAdapter(Context context, List<String> sections, OnClickMenu listener) { mContext = context; mSections = sections; mListener = listener; lastSelectedSection = sections.get(0); } @Override public int getCount() { return mSections.size(); } @Override public String getItem(int position) { return mSections.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { return getCustomView(position, convertView, parent); } public View getCustomView(final int position, View convertView, ViewGroup parent) { final MenuItemHolder holder; if (convertView==null){ LayoutInflater inflater = ((Activity) mContext).getLayoutInflater(); convertView = inflater.inflate(R.layout.layout_left_menu_item, parent, false); holder = new MenuItemHolder(convertView); convertView.setTag(holder); }else { holder = (MenuItemHolder) convertView.getTag(); } Resources r = mContext.getResources(); int pxMarginSection = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, r.getDisplayMetrics()); holder.position = position; holder.mLine.setVisibility(View.GONE); holder.mTitle.setTextColor(mContext.getResources().getColor(R.color.primary)); holder.mIconView.setColorFilter(mContext.getResources().getColor(R.color.primary)); if (mSections.get(position).equals(mContext.getString(R.string.login_id))) { holder.mIconView.setImageResource(R.drawable.ic_login_gp); // holder.mIconView.setColorFilter(mContext.getResources().getColor(R.color.primary)); holder.mTitle.setText(mContext.getString(R.string.action_login)); holder.mLine.setVisibility(View.VISIBLE); holder.mLayoutItem.setPadding(0, pxMarginSection, 0, pxMarginSection); } else if (mSections.get(position).equals(mContext.getString(R.string.settings_id))) { holder.mIconView.setImageResource(R.drawable.option); holder.mTitle.setText(mContext.getString(R.string.action_settings)); holder.mLayoutItem.setPadding(0, pxMarginSection, 0, pxMarginSection); holder.mLine.setVisibility(View.VISIBLE); } else if (mSections.get(position).equals(mContext.getString(R.string.exit_id))) { holder.mIconView.setImageResource(R.drawable.shutdown); holder.mTitle.setText(mContext.getString(R.string.salir)); holder.mLayoutItem.setPadding(0, pxMarginSection, 0, pxMarginSection); holder.mLine.setVisibility(View.VISIBLE); } holder.mLayoutItem.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { switch (motionEvent.getActionMasked()){ case MotionEvent.ACTION_DOWN: currentTextcolor = holder.mTitle.getCurrentTextColor(); holder.mLayoutItemSelect.setBackgroundColor(mContext.getResources().getColor(R.color.primary)); holder.mTitle.setTextColor(mContext.getResources().getColor(R.color.text_info)); holder.mIconView.setColorFilter(mContext.getResources().getColor(R.color.text_info)); return true; case MotionEvent.ACTION_UP: holder.mLayoutItemSelect.setBackgroundResource(R.color.bgLeftMenu); holder.mTitle.setTextColor(currentTextcolor); holder.mIconView.setColorFilter(mContext.getResources().getColor(R.color.primary)); mListener.onClick(mSections.get(position)); return true; case MotionEvent.ACTION_CANCEL: holder.mLayoutItemSelect.setBackgroundColor(mContext.getResources().getColor(R.color.bgLeftMenu)); holder.mTitle.setTextColor(currentTextcolor); holder.mIconView.setColorFilter(mContext.getResources().getColor(R.color.primary)); return true; } return false; } }); return convertView; } class MenuItemHolder { // butterKnife View view; @Bind(R.id.title) TextView mTitle; @Bind(R.id.icon) ImageView mIconView; @Bind(R.id.layoutItem) LinearLayout mLayoutItem; @Bind (R.id.rl_line) View mLine; @Bind(R.id.layoutItemSelect) LinearLayout mLayoutItemSelect; int position; public MenuItemHolder(View itemView) { ButterKnife.bind(this, itemView); view = itemView; } } public void setLastSelectedSection(String idSection) { lastSelectedSection = idSection; } }
Now you have to modify your current Activity:
Change your main activity layout to use DrawerLayout and add your custom view "SimpleLeftMenuView":
<android.support.v4.widget.DrawerLayout android:id="@+id/drawerLayout" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:android="http://schemas.android.com/apk/res/android" android:background="#EDEDED"> // YOUR CURRENT LAYOUT <yourpackage.custom.SimpleLeftMenuView android:id="@+id/navigation_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:background="@color/bgLeftMenu"/> </android.support.v4.widget.DrawerLayout>
Activity class:
Add global variables:
protected @Bind(R.id.navigation_view) SimpleLeftMenuView mLeftMenuView; protected @Bind(R.id.drawerLayout) DrawerLayout mDrawerLayout;
Set onclick listener. You can do an actions depends on the id:
mLeftMenuView.setmListener(new OnClickMenu() { @Override public void onClick(String id) { Log.d("MENU", "ic_menu_hamburger clicked: " + id); closeDrawer(null); if (id.equals(getString(R.string.settings_id))) { Intent intent = new Intent(MainActivity.this, SettingsActivity.class); MainActivity.this.startActivity(intent); } else if (id.equals(getString(R.string.exit_id))) { // salir showRateDialogBeforeExit(); } } });
I have created my own interface OnClickMenu:
public interface OnClickMenu { void onClick(String id); }
And add action to open drawer from menu icon:
@Override public void onBackPressed() { if((mDrawerLayout) != null && (mDrawerLayout.isDrawerOpen(GravityCompat.START))) closeDrawer(null); else { super.onBackPressed(); } } public void closeDrawer(DrawerLayout.DrawerListener listener) { mDrawerLayout.setDrawerListener(listener); mDrawerLayout.closeDrawers(); } public void openDrawer() { mDrawerLayout.setDrawerListener(null); mDrawerLayout.openDrawer(GravityCompat.START); }
Menu:
@Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_home, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: openDrawer(); return true; } return super.onOptionsItemSelected(item); }
add to app build.gradle
compile 'com.android.support:design:26.0.0' compile 'com.jakewharton:butterknife:8.6.0'
Change all @Bind to @BindView
The easiest way for you would be using this library.
Its really easy to implement and its very flexible.
If you want to do it yourself, consider reading official docs about creating navigation drawer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With