Add Navigation Drawer to an existing activity

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-29 18:38:09

问题


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?


回答1:


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:

  1. 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>
    
  2. 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




回答2:


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.




回答3:


I've tried the MaterialDrawer library, as suggested by @yury-dombaev and I have to admit it's far easier to implement than the official Navigation Drawer.

It's possible to implement either with Android X dependencies or with the normal ones.

In my case, since I have the normal ones, I've to stick with the MaterialDrawer 6.0.9v. Although there's a migration guide that I'll give a look.

To implement the library within your current activity do the following:

  1. Add the dependencies in your app build.gradle as explained in Setup 1 of the v 6.0.9 of the library: https://github.com/mikepenz/MaterialDrawer/tree/v6.0.9
  2. Add your drawer in the onCreate() method of your Activity: new DrawerBuilder().withActivity(this).build();.
  3. Now you've got a basic (and useless) lateral menu. So it's time you continue reading the Material Drawer documentation and add menu elements :)


来源:https://stackoverflow.com/questions/41743401/add-navigation-drawer-to-an-existing-activity

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!