简体   繁体   English

不同活动中的相同导航抽屉

[英]Same Navigation Drawer in different Activities

I made a working navigation drawer like it's shown in the tutorial on the developer.android.com website.我制作了一个可用的导航抽屉,就像developer.android.com网站上的教程中所示。 But now, I want to use one Navigation Drawer, i created in the NavigationDrawer.class for multiple Activities in my Application.但是现在,我想使用一个导航抽屉,我在 NavigationDrawer.class 中为应用程序中的多个活动创建了它。

My question is, if anyone here can make a little Tutorial, which explains, how to use one Navigation drawer for multiple Activities.我的问题是,如果这里有人可以制作一个小教程,其中解释了如何将一个导航抽屉用于多个活动。

I read it first at this Answer Android Navigation Drawer on multiple Activities我首先阅读了这个答案Android Navigation Drawer on multiple Activity

but it didn't work on my Project但它对我的项目不起作用

public class NavigationDrawer extends Activity {
public DrawerLayout drawerLayout;
public ListView drawerList;
private ActionBarDrawerToggle drawerToggle;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawerToggle = new ActionBarDrawerToggle((Activity) this, drawerLayout, R.drawable.ic_drawer, 0, 0) {

        public void onDrawerClosed(View view) {
            getActionBar().setTitle(R.string.app_name);
        }

        public void onDrawerOpened(View drawerView) {
            getActionBar().setTitle(R.string.menu);
        }
    };
    drawerLayout.setDrawerListener(drawerToggle);

    getActionBar().setDisplayHomeAsUpEnabled(true);
    getActionBar().setHomeButtonEnabled(true);

    listItems = getResources().getStringArray(R.array.layers_array);
    drawerList = (ListView) findViewById(R.id.left_drawer);
    drawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, android.R.id.text,
            listItems));
    
    drawerList.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int pos, long arg3) {
            drawerClickEvent(pos);
        }
    });
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    if (drawerToggle.onOptionsItemSelected(item)) {
        return true;
    }
    return super.onOptionsItemSelected(item);

}

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

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    drawerToggle.onConfigurationChanged(newConfig);
}
}

In this Activity i want to have the Navigation Drawer so I extends 'NavigationDrawer' and in some other Activities i want to User the Same Navigation drawer在此活动中,我想拥有导航抽屉,因此我扩展了“导航抽屉”,而在其他一些活动中,我想使用相同的导航抽屉

  public class SampleActivity extends NavigationDrawer {...}

If you want a navigation drawer, you should use fragments.如果你想要一个导航抽屉,你应该使用片段。 I followed this tutorial last week and it works great:我上周学习了本教程,效果很好:

http://developer.android.com/training/implementing-navigation/nav-drawer.html http://developer.android.com/training/implementing-navigation/nav-drawer.html

You can also download sample code from this tutorial, to see how you can do this.您还可以从本教程下载示例代码,以了解如何执行此操作。


Without fragments:无碎片:

This is your BaseActivity Code:这是您的 BaseActivity 代码:

public class BaseActivity extends Activity
{
    public DrawerLayout drawerLayout;
    public ListView drawerList;
    public String[] layers;
    private ActionBarDrawerToggle drawerToggle;
    private Map map;

    protected void onCreate(Bundle savedInstanceState)
    {
        // R.id.drawer_layout should be in every activity with exactly the same id.
        drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

        drawerToggle = new ActionBarDrawerToggle((Activity) this, drawerLayout, R.drawable.ic_drawer, 0, 0) 
        {
            public void onDrawerClosed(View view) 
            {
                getActionBar().setTitle(R.string.app_name);
            }

            public void onDrawerOpened(View drawerView) 
            {
                getActionBar().setTitle(R.string.menu);
            }
        };
        drawerLayout.setDrawerListener(drawerToggle);

        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setHomeButtonEnabled(true);

        layers = getResources().getStringArray(R.array.layers_array);
        drawerList = (ListView) findViewById(R.id.left_drawer);
        View header = getLayoutInflater().inflate(R.layout.drawer_list_header, null);
        drawerList.addHeaderView(header, null, false);
        drawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, android.R.id.text1,
                layers));
        View footerView = ((LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(
                R.layout.drawer_list_footer, null, false);
        drawerList.addFooterView(footerView);

        drawerList.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int pos, long arg3) {
                map.drawerClickEvent(pos);
            }
        });
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        if (drawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
        return super.onOptionsItemSelected(item);

    }

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

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        drawerToggle.onConfigurationChanged(newConfig);
    }
}

All the other Activities that needs to have a navigation drawer should extend this Activity instead of Activity itself, example:需要有导航抽屉的所有其他活动应该扩展这个活动而不是活动本身,例如:

public class AnyActivity extends BaseActivity
{
    //Because this activity extends BaseActivity it automatically has the navigation drawer
    //You can just write your normal Activity code and you don't need to add anything for the navigation drawer
}

XML XML

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!-- The main content view -->
    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
        <!-- Put what you want as your normal screen in here, you can also choose for a linear layout or any other layout, whatever you prefer -->
    </FrameLayout>
    <!-- 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="#111"/>
</android.support.v4.widget.DrawerLayout>

Edit:编辑:

I experienced some difficulties myself, so here is a solution if you get NullPointerExceptions.我自己也遇到了一些困难,所以如果您遇到 NullPointerExceptions,这里有一个解决方案。 In BaseActivity change the onCreate function to protected void onCreateDrawer() .在 BaseActivity 中,将 onCreate 函数更改为protected void onCreateDrawer() The rest can stay the same.其余的可以保持不变。 In the Activities which extend BaseActivity put the code in this order:在扩展 BaseActivity 的活动中,按以下顺序放置代码:

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity);
    super.onCreateDrawer();

This helped me fix my problem, hope it helps!这帮助我解决了我的问题,希望它有帮助!

This is how you can create a navigation drawer with multiple activities, if you have any questions feel free to ask.如果您有任何问题,请随时提出,这就是您可以创建具有多个活动的导航抽屉的方法。


Edit 2:编辑2:

As said by @GregDan your BaseActivity can also override setContentView() and call onCreateDrawer there:正如@GregDan 所说,你的BaseActivity也可以覆盖setContentView()并在那里调用 onCreateDrawer :

@Override 
public void setContentView(@LayoutRes int layoutResID) 
{ 
    super.setContentView(layoutResID); 
    onCreateDrawer() ;
}

I've found the best implementation.我找到了最好的实现。 It's in the Google I/O 2014 app.它位于Google I/O 2014应用程序中。

They use the same approach as Kevin's.他们使用与凯文相同的方法。 If you can abstract yourself from all unneeded stuff in I/O app, you could extract everything you need and it is assured by Google that it's a correct usage of navigation drawer pattern.如果你能从 I/O 应用程序中所有不需要的东西中抽象出来,你就可以提取你需要的一切,谷歌保证这是导航抽屉模式的正确用法。 Each activity optionally has a DrawerLayout as its main layout.每个活动都可以选择将DrawerLayout作为其主要布局。 The interesting part is how the navigation to other screens is done.有趣的部分是如何导航到其他屏幕。 It is implemented in BaseActivity like this:它在BaseActivity是这样实现的:

private void goToNavDrawerItem(int item) {
        Intent intent;
        switch (item) {
            case NAVDRAWER_ITEM_MY_SCHEDULE:
                intent = new Intent(this, MyScheduleActivity.class);
                startActivity(intent);
                finish();
                break;

This differs from the common way of replacing current fragment by a fragment transaction.这与通过片段事务替换当前片段的常见方式不同。 But the user doesn't spot a visual difference.但用户没有发现视觉差异。

So this answer is a few years late but someone may appreciate it.所以这个答案晚了几年,但有人可能会欣赏它。 Android has given us a new widget that makes using one navigation drawer with several activities easier. Android 为我们提供了一个新的小部件,它使使用一个导航抽屉和多个活动变得更容易。

android.support.design.widget.NavigationView is modular and has its own layout in the menu folder. android.support.design.widget.NavigationView 是模块化的,在菜单文件夹中有自己的布局。 The way that you use it is to wrap xml layouts the following way:您使用它的方式是按以下方式包装 xml 布局:

  1. Root Layout is a android.support.v4.widget.DrawerLayout that contains two children: an <include ... /> for the layout that is being wrapped (see 2) and a android.support.design.widget.NavigationView. Root Layout 是一个 android.support.v4.widget.DrawerLayout,它包含两个子项:一个<include ... />用于正在包装的布局(参见 2)和一个 android.support.design.widget.NavigationView。

     <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:openDrawer="start"> <include layout="@layout/app_bar_main" android:layout_width="match_parent" android:layout_height="match_parent" /> <android.support.design.widget.NavigationView android:id="@+id/nav_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true" app:headerLayout="@layout/nav_header_main" app:menu="@menu/activity_main_drawer" />

nav_header_main is just a LinearLayout with orientation = vertical for the header of your Navigation Drawar. nav_header_main 只是一个 LinearLayout,你的 Navigation Drawar 的标题的方向 = 垂直。

activity_main_drawer is a menu xml in your res/menu directory. activity_main_drawer 是 res/menu 目录中的菜单 xml。 It can contain items and groups of your choice.它可以包含您选择的项目和组。 If you use the AndroidStudio Gallery the wizard will make a basic one for you and you can see what your options are.如果您使用 AndroidStudio Gallery,向导将为您制作一个基本的库,您可以查看您的选项。

  1. App bar layout is usually now a android.support.design.widget.CoordinatorLayout and this will include two children: a android.support.design.widget.AppBarLayout (which contains a android.support.v7.widget.Toolbar) and an <include ... > for your actual content (see 3).应用栏布局现在通常是一个 android.support.design.widget.CoordinatorLayout ,这将包括两个子项:一个 android.support.design.widget.AppBarLayout(包含一个 android.support.v7.widget.Toolbar)和一个<include ... >用于您的实际内容(参见 3)。

     <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="yourpackage.MainActivity"> <android.support.design.widget.AppBarLayout 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:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay" /> </android.support.design.widget.AppBarLayout> <include layout="@layout/content_main" />

  2. Content layout can be whatever layout you want.内容布局可以是您想要的任何布局。 This is the layout that contains the main content of the activity (not including the navigation drawer or app bar).这是包含活动主要内容的布局(不包括导航抽屉或应用栏)。

Now, the cool thing about all of this is that you can wrap each activity in these two layouts but have your NavigationView (see step 1) always point to activity_main_drawer (or whatever).现在,关于所有这些很酷的事情是,您可以将每个活动包装在这两个布局中,但让您的 NavigationView(参见步骤 1)始终指向 activity_main_drawer(或其他任何内容)。 This means that you will have the same(*) Navigation Drawer on all activities.这意味着您将在所有活动中拥有相同的 (*) Navigation Drawer。

  • They won't be the same instance of NavigationView but, to be fair, that wasn't possible even with the BaseActivity solution outlined above.它们不会是 NavigationView 的同一个实例,但公平地说,即使使用上面概述的 BaseActivity 解决方案,这也是不可能的。

Easiest way to reuse a common Navigation drawer among a group of activities在一组活动中重用通用导航抽屉的最简单方法

app_base_layout.xml app_base_layout.xml

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

    <FrameLayout
        android:id="@+id/view_stub"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </FrameLayout>

    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_view"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:menu="@menu/menu_test"
        />
</android.support.v4.widget.DrawerLayout>

AppBaseActivity.java AppBaseActivity.java

/*
* This is a simple and easy approach to reuse the same 
* navigation drawer on your other activities. Just create
* a base layout that conains a DrawerLayout, the 
* navigation drawer and a FrameLayout to hold your
* content view. All you have to do is to extend your 
* activities from this class to set that navigation 
* drawer. Happy hacking :)
* P.S: You don't need to declare this Activity in the 
* AndroidManifest.xml. This is just a base class.
*/
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.design.widget.NavigationView;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

public abstract class AppBaseActivity extends AppCompatActivity implements MenuItem.OnMenuItemClickListener {
    private FrameLayout view_stub; //This is the framelayout to keep your content view
    private NavigationView navigation_view; // The new navigation view from Android Design Library. Can inflate menu resources. Easy
    private DrawerLayout mDrawerLayout;
    private ActionBarDrawerToggle mDrawerToggle;
    private Menu drawerMenu;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.setContentView(R.layout.app_base_layout);// The base layout that contains your navigation drawer.
        view_stub = (FrameLayout) findViewById(R.id.view_stub);
        navigation_view = (NavigationView) findViewById(R.id.navigation_view);
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, 0, 0);
        mDrawerLayout.setDrawerListener(mDrawerToggle);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        drawerMenu = navigation_view.getMenu();
        for(int i = 0; i < drawerMenu.size(); i++) {
          drawerMenu.getItem(i).setOnMenuItemClickListener(this);
        }
        // and so on...
    }

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

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        mDrawerToggle.onConfigurationChanged(newConfig);
    }

    /* Override all setContentView methods to put the content view to the FrameLayout view_stub
     * so that, we can make other activity implementations looks like normal activity subclasses.
     */
    @Override
    public void setContentView(int layoutResID) {
        if (view_stub != null) {
            LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
            ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT);
            View stubView = inflater.inflate(layoutResID, view_stub, false);
            view_stub.addView(stubView, lp);
        }
    }

    @Override
    public void setContentView(View view) {
        if (view_stub != null) {
            ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT);
            view_stub.addView(view, lp);
        }
    }

    @Override
    public void setContentView(View view, ViewGroup.LayoutParams params) {
        if (view_stub != null) {
            view_stub.addView(view, params);
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Pass the event to ActionBarDrawerToggle, if it returns
        // true, then it has handled the app icon touch event
        if (mDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
        // Handle your other action bar items...

        return super.onOptionsItemSelected(item);
    }

    @Override
    public boolean onMenuItemClick(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.item1:
                // handle it
                break;
            case R.id.item2:
                // do whatever
                break;
            // and so on...
        }
        return false;
    }
}

For anyone else looking to do what the original poster is asking, please consider to use fragments instead the way Kevin said.对于其他想要做原始海报要求的人,请考虑像凯文所说的那样使用片段。 Here is an excellent tutorial on how to do that:这是一个关于如何做到这一点的优秀教程:

https://github.com/codepath/android_guides/wiki/Fragment-Navigation-Drawer https://github.com/codepath/android_guides/wiki/Fragment-Navigation-Drawer

If you choose to instead use activities instead of fragments you are going to run into the problem of the nav drawer being re-created every time you navigate to a new activity.如果您选择使用活动而不是片段,您将遇到每次导航到新活动时都会重新创建导航抽屉的问题。 This results in an ugly/slow rendering of the nav drawer each time.这会导致每次导航抽屉的渲染丑陋/缓慢。

My suggestion is: do not use activities at all, instead use fragments, and replace them in the container (Linear Layout for example) where you show your first fragment.我的建议是:根本不要使用活动,而是使用片段,并在您显示第一个片段的容器(例如线性布局)中替换它们。

The code is available in Android Developer Tutorials, you just have to customize.该代码可在 Android 开发者教程中找到,您只需要自定义即可。

http://developer.android.com/training/implementing-navigation/nav-drawer.html http://developer.android.com/training/implementing-navigation/nav-drawer.html

It is advisable that you should use more and more fragments in your application, and there should be only four basic activities local to your application, that you mention in your AndroidManifest.xml apart from the external ones (FacebookActivity for example):建议您应该在您的应用程序中使用越来越多的片段,并且您的应用程序本地应该只有四个基本活动,除了外部活动(例如 FacebookActivity),您在 AndroidManifest.xml 中提到:

  1. SplashActivity: uses no fragment, and uses FullScreen theme. SplashActivity:不使用片段,使用全屏主题。

  2. LoginSignUpActivity: Do not require NavigationDrawer at all, and no back button as well, so simply use the normal toolbar, but at the least, 3 or 4 fragments will be required. LoginSignUpActivity:完全不需要NavigationDrawer,也没有后退按钮,所以只需使用普通工具栏,但至少需要3或4个片段。 Uses no-action-bar theme使用无操作栏主题

  3. HomeActivity or DashBoard Activity: Uses no-action-bar theme. HomeActivity 或 DashBoard Activity:使用无操作栏主题。 Here you require Navigation drawer, also all the screens that follow will be fragments or nested fragments, till the leaf view, with the shared drawer.在这里你需要导航抽屉,接下来的所有屏幕都将是片段或嵌套片段,直到叶子视图,共享抽屉。 All the settings, user profile and etc. will be here as fragments, in this activity.在此活动中,所有设置、用户配置文件等都将作为片段出现在这里。 The fragments here will not be added to the back stack and will be opened from the drawer menu items.这里的片段不会被添加到后台堆栈中,而是会从抽屉菜单项中打开。 In the case of fragments that require back button instead of the drawer, there is a fourth kind of activity below.在需要返回按钮而不是抽屉的片段的情况下,下面有第四种活动。

  4. Activity without drawer.没有抽屉的活动。 This activity has a back button on top and the fragments inside will be sharing the same action-bar.此活动顶部有一个后退按钮,其中的片段将共享相同的操作栏。 These fragments will be added to the back-stack, as there will be a navigation history.这些片段将被添加到后台堆栈中,因为会有导航历史记录。

[ For further guidance see: https://stackoverflow.com/a/51100507/787399 ] [有关进一步指导,请参阅: https : //stackoverflow.com/a/51100507/787399 ]

Happy Coding !!快乐编码!!

update this code in baseactivity.在 baseactivity 中更新此代码。 and dont forget to include drawer_list_header in your activity xml.并且不要忘记在您的活动 xml 中包含 drawer_list_header。

super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
setContentView(R.layout.drawer_list_header);

and dont use request() in your activity.并且不要在您的活动中使用 request() 。 but still the drawer is not visible on clicking image..and by dragging it will visible without list items.但是在单击图像时仍然看不到抽屉……并且通过拖动它可以在没有列表项的情况下看到。 i tried a lot but no success.我尝试了很多但没有成功。 need some workouts for this...为此需要一些锻炼...

With @Kevin van Mierlo 's answer, you are also capable of implementing several drawers.通过@Kevin van Mierlo 的回答,您还可以实现多个抽屉。 For instance, the default menu located on the left side (start), and a further optional menu, located on the right side, which is only shown when determinate fragments are loaded.例如,位于左侧(开始)的默认菜单和位于右侧的另一个可选菜单,仅在加载确定片段时显示。

I've been able to do that.我已经能够做到这一点。

package xxxxxx;



import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.widget.SearchView;
import android.support.design.widget.NavigationView;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;


public class loginhome extends AppCompatActivity {
    private Toolbar toolbar;
    private NavigationView navigationView;
    private DrawerLayout drawerLayout;

    // Make sure to be using android.support.v7.app.ActionBarDrawerToggle version.
    // The android.support.v4.app.ActionBarDrawerToggle has been deprecated.
    private ActionBarDrawerToggle drawerToggle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.loginhome);

        // Initializing Toolbar and setting it as the actionbar
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);


        //Initializing NavigationView


        navigationView = (NavigationView) findViewById(R.id.nav_view);

        //Setting Navigation View Item Selected Listener to handle the item click of the navigation menu
        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {

            // This method will trigger on item Click of navigation menu

            public boolean onNavigationItemSelected(MenuItem menuItem) {


                //Checking if the item is in checked state or not, if not make it in checked state
                if(menuItem.isChecked()) menuItem.setChecked(false);
                else menuItem.setChecked(true);

                //Closing drawer on item click
                drawerLayout.closeDrawers();

                //Check to see which item was being clicked and perform appropriate action
                switch (menuItem.getItemId()){


                    //Replacing the main content with ContentFragment Which is our Inbox View;
                    case R.id.nav_first_fragment:
                        Toast.makeText(getApplicationContext(),"First fragment",Toast.LENGTH_SHORT).show();
                         FirstFragment fragment = new FirstFragment();
                        android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
                        fragmentTransaction.replace(R.id.frame,fragment);
                        fragmentTransaction.commit();
                        return true;

                    // For rest of the options we just show a toast on click
                    case R.id.nav_second_fragment:
                        Toast.makeText(getApplicationContext(),"Second fragment",Toast.LENGTH_SHORT).show();
                        SecondFragment fragment2 = new SecondFragment();
                        android.support.v4.app.FragmentTransaction fragmentTransaction2 = getSupportFragmentManager().beginTransaction();
                        fragmentTransaction2.replace(R.id.frame,fragment2);
                        fragmentTransaction2.commit();
                        return true;

                    default:
                        Toast.makeText(getApplicationContext(),"Somethings Wrong",Toast.LENGTH_SHORT).show();
                        return true;

                }
            }
        });

        // Initializing Drawer Layout and ActionBarToggle
        drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this,drawerLayout,toolbar,R.string.drawer_open, R.string.drawer_close){

            @Override
            public void onDrawerClosed(View drawerView) {
                // Code here will be triggered once the drawer closes as we dont want anything to happen so we leave this blank
                super.onDrawerClosed(drawerView);
            }

            @Override
            public void onDrawerOpened(View drawerView) {
                // Code here will be triggered once the drawer open as we dont want anything to happen so we leave this blank

                super.onDrawerOpened(drawerView);
            }
        };

        //Setting the actionbarToggle to drawer layout
        drawerLayout.setDrawerListener(actionBarDrawerToggle);

        //calling sync state is necessay or else your hamburger icon wont show up
        actionBarDrawerToggle.syncState();







    }

use this for your toolbar.xml将此用于您的 toolbar.xml

<?xml version="1.0" encoding="utf-8"?>

    <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimary"
        android:elevation="4dp"
        android:id="@+id/toolbar"
        android:theme="@style/ThemeOverlay.AppCompat.Dark"


        >

    </android.support.v7.widget.Toolbar>

use this for navigation header if want to use如果要使用,请将此用于导航标题

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="192dp"
    android:background="?attr/colorPrimaryDark"
    android:padding="16dp"
    android:theme="@style/ThemeOverlay.AppCompat.Dark"
    android:orientation="vertical"
    android:gravity="bottom">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:id="@+id/navhead"
        android:orientation="vertical"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true">

        <TextView
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="16dp"
            android:textColor="#ffffff"
            android:text="tanya"
            android:textSize="14sp"
            android:textStyle="bold"

            />

        <TextView
            android:id="@+id/email"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#ffffff"
            android:layout_marginLeft="16dp"
            android:layout_marginTop="5dp"
            android:text="tanya.com"
            android:textSize="14sp"
            android:textStyle="normal"

            />
    </LinearLayout>
    <de.hdodenhof.circleimageview.CircleImageView
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:layout_below="@+id/imageView"
        android:layout_marginTop="15dp"

        android:src="@drawable/face"
        android:id="@+id/circleView"
        />



</RelativeLayout>

I do it in Kotlin like this:我在 Kotlin 中这样做:

open class BaseAppCompatActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {

protected lateinit var drawerLayout: DrawerLayout
protected lateinit var navigationView: NavigationView
@Inject
lateinit var loginService: LoginService

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    Log.d("BaseAppCompatActivity", "onCreate()")
    App.getComponent().inject(this)
    drawerLayout = findViewById(R.id.drawer_layout) as DrawerLayout

    val toolbar = findViewById(R.id.toolbar) as Toolbar
    setSupportActionBar(toolbar)

    navigationView = findViewById(R.id.nav_view) as NavigationView
    navigationView.setNavigationItemSelectedListener(this)

    val toggle = ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)

    drawerLayout.addDrawerListener(toggle)
    toggle.syncState()
    toggle.isDrawerIndicatorEnabled = true

    val navigationViewHeaderView = navigationView.getHeaderView(0)
    navigationViewHeaderView.login_txt.text = SharedKey.username
}
private inline fun <reified T: Activity> launch():Boolean{
    if(this is T) return closeDrawer()
    val intent = Intent(applicationContext, T::class.java)
    startActivity(intent)
    finish()
    return true
}

private fun closeDrawer(): Boolean {
    drawerLayout.closeDrawer(GravityCompat.START)
    return true
}
override fun onNavigationItemSelected(item: MenuItem): Boolean {
    val id = item.itemId

    when (id) {
        R.id.action_tasks -> {
            return launch<TasksActivity>()
        }
        R.id.action_contacts -> {
            return launch<ContactActivity>()
        }
        R.id.action_logout -> {
            createExitDialog(loginService, this)
        }
    }
    return false
}
}

Activities for drawer must inherit this BaseAppCompatActivity , call super.onCreate after content is set (actually, can be moved to some init method) and have corresponding elements for ids in their layout抽屉的活动必须继承这个BaseAppCompatActivity ,在设置内容后调用super.onCreate (实际上,可以移动到一些 init 方法)并在其布局中具有对应的 id 元素

My answer is just a conceptual one without any source code.我的回答只是一个没有任何源代码的概念性回答。 It might be useful for some readers like myself to understand.对于一些像我这样的读者来说,理解它可能很有用。

It depends on your initial approach on how you architecture your app.这取决于您如何构建应用程序的初始方法。 There are basically two approaches.基本上有两种方法。

  1. You create one activity (base activity) and all the other views and screens will be fragments.您创建一个活动(基本活动),所有其他视图和屏幕都将是片段。 That base activity contains the implementation for Drawer and Coordinator Layouts.该基本活动包含抽屉和协调器布局的实现。 It is actually my preferred way of doing because having small self-contained fragments will make app development easier and smoother.这实际上是我的首选方式,因为拥有小的独立片段将使应用程序开发更容易、更顺畅。

  2. If you have started your app development with activities, one for each screen , then you will probably create base activity, and all other activity extends from it.如果您已经开始使用活动开发应用程序,每个屏幕一个,那么您可能会创建基础活动,所有其他活动都从它扩展。 The base activity will contain the code for drawer and coordinator implementation.基本活动将包含抽屉和协调器实现的代码。 Any activity that needs drawer implementation can extend from base activity.任何需要抽屉实现的活动都可以从基础活动扩展。

I would personally prefer avoiding to use fragments and activities mixed without any organizing.我个人更愿意避免在没有任何组织的情况下混合使用片段和活动。 That makes the development more difficult and get you stuck eventually.这会使开发变得更加困难,并最终让您陷入困境。 If you have done it, refactor your code.如果你已经这样做了,重构你的代码。

It is elaborated in the following video tutorial在下面的视频教程中详细说明

Navigation Drawer on Multiple Activities Using Base Activity使用基础活动在多个活动上导航抽屉

It is very easy to make a base navigation drawer activity and extend that base navigation drawer activity to all those activities on which you want to display navigation drawer,制作基础导航抽屉活动并将该基础导航抽屉活动扩展到您想要显示导航抽屉的所有活动非常容易,

  1. Make navigation menu, header制作导航菜单、标题
  2. create a base activity for navigation drawer为导航抽屉创建基本活动
  3. create a content layout创建内容布局
  4. Combined menu, header, content layout on base activity基本活动的组合菜单、标题、内容布局
  5. By using frame layout, insert every activity in the drawer menu.通过使用框架布局,在抽屉菜单中插入每个活动。

All steps are clearly explained in the video所有步骤都在视频中清楚地解释了

Create Navigation drawer in your MainActivity using fragment.使用片段在您的 MainActivity 中创建导航抽屉。
Initialize the Navigation Drawer in MainActivity在 MainActivity 中初始化 Navigation Drawer
now in all other activities you want to use same Navigation Drawer put DrawerLayout as base and fragment as navigation drawer.现在在所有其他想要使用相同导航抽屉的活动中,将 DrawerLayout 作为基础并将片段作为导航抽屉。 Just set android:name in your fragment pointing to your fragment Java file.只需在您的片段中设置 android:name 指向您的片段 Java 文件。 You won't need to initialize the fragment in other Activities.您不需要在其他活动中初始化片段。
You can access Nav Drawer by swipe in other activities like in Google Play Store app您可以通过在 Google Play 商店应用等其他活动中滑动来访问 Nav Drawer

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM