繁体   English   中英

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

[英]Same Navigation Drawer in different Activities

我制作了一个可用的导航抽屉,就像developer.android.com网站上的教程中所示。 但是现在,我想使用一个导航抽屉,我在 NavigationDrawer.class 中为应用程序中的多个活动创建了它。

我的问题是,如果这里有人可以制作一个小教程,其中解释了如何将一个导航抽屉用于多个活动。

我首先阅读了这个答案Android Navigation Drawer on multiple Activity

但它对我的项目不起作用

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);
}
}

在此活动中,我想拥有导航抽屉,因此我扩展了“导航抽屉”,而在其他一些活动中,我想使用相同的导航抽屉

  public class SampleActivity extends NavigationDrawer {...}

如果你想要一个导航抽屉,你应该使用片段。 我上周学习了本教程,效果很好:

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

您还可以从本教程下载示例代码,以了解如何执行此操作。


无碎片:

这是您的 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);
    }
}

需要有导航抽屉的所有其他活动应该扩展这个活动而不是活动本身,例如:

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

<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>

编辑:

我自己也遇到了一些困难,所以如果您遇到 NullPointerExceptions,这里有一个解决方案。 在 BaseActivity 中,将 onCreate 函数更改为protected void onCreateDrawer() 其余的可以保持不变。 在扩展 BaseActivity 的活动中,按以下顺序放置代码:

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

这帮助我解决了我的问题,希望它有帮助!

如果您有任何问题,请随时提出,这就是您可以创建具有多个活动的导航抽屉的方法。


编辑2:

正如@GregDan 所说,你的BaseActivity也可以覆盖setContentView()并在那里调用 onCreateDrawer :

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

我找到了最好的实现。 它位于Google I/O 2014应用程序中。

他们使用与凯文相同的方法。 如果你能从 I/O 应用程序中所有不需要的东西中抽象出来,你就可以提取你需要的一切,谷歌保证这是导航抽屉模式的正确用法。 每个活动都可以选择将DrawerLayout作为其主要布局。 有趣的部分是如何导航到其他屏幕。 它在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;

这与通过片段事务替换当前片段的常见方式不同。 但用户没有发现视觉差异。

所以这个答案晚了几年,但有人可能会欣赏它。 Android 为我们提供了一个新的小部件,它使使用一个导航抽屉和多个活动变得更容易。

android.support.design.widget.NavigationView 是模块化的,在菜单文件夹中有自己的布局。 您使用它的方式是按以下方式包装 xml 布局:

  1. 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 只是一个 LinearLayout,你的 Navigation Drawar 的标题的方向 = 垂直。

activity_main_drawer 是 res/menu 目录中的菜单 xml。 它可以包含您选择的项目和组。 如果您使用 AndroidStudio Gallery,向导将为您制作一个基本的库,您可以查看您的选项。

  1. 应用栏布局现在通常是一个 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. 内容布局可以是您想要的任何布局。 这是包含活动主要内容的布局(不包括导航抽屉或应用栏)。

现在,关于所有这些很酷的事情是,您可以将每个活动包装在这两个布局中,但让您的 NavigationView(参见步骤 1)始终指向 activity_main_drawer(或其他任何内容)。 这意味着您将在所有活动中拥有相同的 (*) Navigation Drawer。

  • 它们不会是 NavigationView 的同一个实例,但公平地说,即使使用上面概述的 BaseActivity 解决方案,这也是不可能的。

在一组活动中重用通用导航抽屉的最简单方法

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

/*
* 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;
    }
}

对于其他想要做原始海报要求的人,请考虑像凯文所说的那样使用片段。 这是一个关于如何做到这一点的优秀教程:

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

如果您选择使用活动而不是片段,您将遇到每次导航到新活动时都会重新创建导航抽屉的问题。 这会导致每次导航抽屉的渲染丑陋/缓慢。

我的建议是:根本不要使用活动,而是使用片段,并在您显示第一个片段的容器(例如线性布局)中替换它们。

该代码可在 Android 开发者教程中找到,您只需要自定义即可。

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

建议您应该在您的应用程序中使用越来越多的片段,并且您的应用程序本地应该只有四个基本活动,除了外部活动(例如 FacebookActivity),您在 AndroidManifest.xml 中提到:

  1. SplashActivity:不使用片段,使用全屏主题。

  2. LoginSignUpActivity:完全不需要NavigationDrawer,也没有后退按钮,所以只需使用普通工具栏,但至少需要3或4个片段。 使用无操作栏主题

  3. HomeActivity 或 DashBoard Activity:使用无操作栏主题。 在这里你需要导航抽屉,接下来的所有屏幕都将是片段或嵌套片段,直到叶子视图,共享抽屉。 在此活动中,所有设置、用户配置文件等都将作为片段出现在这里。 这里的片段不会被添加到后台堆栈中,而是会从抽屉菜单项中打开。 在需要返回按钮而不是抽屉的片段的情况下,下面有第四种活动。

  4. 没有抽屉的活动。 此活动顶部有一个后退按钮,其中的片段将共享相同的操作栏。 这些片段将被添加到后台堆栈中,因为会有导航历史记录。

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

快乐编码!!

在 baseactivity 中更新此代码。 并且不要忘记在您的活动 xml 中包含 drawer_list_header。

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

并且不要在您的活动中使用 request() 。 但是在单击图像时仍然看不到抽屉……并且通过拖动它可以在没有列表项的情况下看到。 我尝试了很多但没有成功。 为此需要一些锻炼...

通过@Kevin van Mierlo 的回答,您还可以实现多个抽屉。 例如,位于左侧(开始)的默认菜单和位于右侧的另一个可选菜单,仅在加载确定片段时显示。

我已经能够做到这一点。

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();







    }

将此用于您的 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>

如果要使用,请将此用于导航标题

<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>

我在 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
}
}

抽屉的活动必须继承这个BaseAppCompatActivity ,在设置内容后调用super.onCreate (实际上,可以移动到一些 init 方法)并在其布局中具有对应的 id 元素

我的回答只是一个没有任何源代码的概念性回答。 对于一些像我这样的读者来说,理解它可能很有用。

这取决于您如何构建应用程序的初始方法。 基本上有两种方法。

  1. 您创建一个活动(基本活动),所有其他视图和屏幕都将是片段。 该基本活动包含抽屉和协调器布局的实现。 这实际上是我的首选方式,因为拥有小的独立片段将使应用程序开发更容易、更顺畅。

  2. 如果您已经开始使用活动开发应用程序,每个屏幕一个,那么您可能会创建基础活动,所有其他活动都从它扩展。 基本活动将包含抽屉和协调器实现的代码。 任何需要抽屉实现的活动都可以从基础活动扩展。

我个人更愿意避免在没有任何组织的情况下混合使用片段和活动。 这会使开发变得更加困难,并最终让您陷入困境。 如果你已经这样做了,重构你的代码。

在下面的视频教程中详细说明

使用基础活动在多个活动上导航抽屉

制作基础导航抽屉活动并将该基础导航抽屉活动扩展到您想要显示导航抽屉的所有活动非常容易,

  1. 制作导航菜单、标题
  2. 为导航抽屉创建基本活动
  3. 创建内容布局
  4. 基本活动的组合菜单、标题、内容布局
  5. 通过使用框架布局,在抽屉菜单中插入每个活动。

所有步骤都在视频中清楚地解释了

使用片段在您的 MainActivity 中创建导航抽屉。
在 MainActivity 中初始化 Navigation Drawer
现在在所有其他想要使用相同导航抽屉的活动中,将 DrawerLayout 作为基础并将片段作为导航抽屉。 只需在您的片段中设置 android:name 指向您的片段 Java 文件。 您不需要在其他活动中初始化片段。
您可以通过在 Google Play 商店应用等其他活动中滑动来访问 Nav Drawer

暂无
暂无

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

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