java 将导航抽屉添加到现有活动

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/41743401/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 06:07:32  来源:igfitidea点击:

Add Navigation Drawer to an existing activity

javaandroidnavigation-drawer

提问by user7415791

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?

我有一个正在编写的应用程序,它已经包含很多代码,我决定要向主活动工具栏添加一个导航抽屉,但我不知道如何在不创建新的导航抽屉项目并复制的情况下进行操作我的整个项目似乎需要做很多工作,是否有将导航抽屉添加到现有项目的教程?

回答by anthorlop

Create a layout layout_left_menu.xml:

创建布局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.

您必须创建 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:

  1. 更改您的主要活动布局以使用 DrawerLayout 并添加您的自定义视图“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. 活动类:

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:

设置点击监听器。您可以根据 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:

我已经创建了自己的界面 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

添加到应用程序 build.gradle

compile 'com.android.support:design:26.0.0'
compile 'com.jakewharton:butterknife:8.6.0'

Change all @Bind to @BindView

将所有@Bind 更改为@BindView

回答by Yury Dombaev

The easiest way for you would be using thislibrary.

对您来说最简单的方法是使用这个库。

Its really easy to implement and its very flexible.

它真的很容易实现并且非常灵活。

If you want to do it yourself, consider reading official docsabout creating navigation drawer.

如果您想自己做,请考虑阅读有关创建导航抽屉的官方文档

回答by xarlymg89

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.

我已经按照@yury-dombaev 的建议尝试过 MaterialDrawer 库,我不得不承认它比官方的 Navigation Drawer 更容易实现。

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

可以使用 Android X 依赖项或普通依赖项来实现。

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.

就我而言,因为我有普通的,所以我必须坚持使用 MaterialDrawer 6.0.9v。虽然有一个迁移指南,我会看看。

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 :)
  1. 按照库的 v 6.0.9 的设置 1 中的说明在您的应用程序 build.gradle 中添加依赖项:https: //github.com/mikepenz/MaterialDrawer/tree/v6.0.9
  2. onCreate您的Activity:的() 方法中添加您的抽屉new DrawerBuilder().withActivity(this).build();
  3. 现在你有了一个基本的(和无用的)横向菜单。所以是时候继续阅读 Material Drawer 文档并添加菜单元素了 :)