Android:NavigationDrawer /多个活动/相同的菜单

L. *_*Zan 14 android navigation-drawer

我想要做的是有一个这样的NavigationDrawer菜单: NavigationDrawer

我已经弄清楚如何在单击菜单项时更改布局,但如何在不丢失菜单的情况下加载新活动?

我的主要问题:

例如,假设我的一个菜单选项将您带到一个布局,其中有一些按钮可以执行某些操作.我需要加载一个附带的活动/类,它将处理应用程序中特定"页面"的操作和功能.例如,如果另一个菜单选项将您带到仅包含图像的布局,那么这将是另一个没有处理按钮功能的代码的活动,因为此屏幕中没有按钮.

我希望这是有道理的!我使用了几种方法(片段等)在线跟踪了许多教程/视频,但没有完全回答我的问题.

L. *_*Zan 45

感谢上述答案,我能够完全按照自己的意愿行事,这正是我为未来寻找此事的人所做的一切:

我的activity_main.xml如下所示:

<!--When the DrawerLayout is the root layout, the first child-->
<!--of that layout is the contents of the main screen, and the-->
<!--second child is the contents of the menu-->

<!--First child layout-->

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <include
        layout="@layout/toolbar_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

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

</LinearLayout>

<!--Second child layout-->
<android.support.design.widget.NavigationView
    android:id="@+id/navigation_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="start"
    app:headerLayout="@layout/navigation_drawer_header"
    app:menu="@menu/drawer_menu">

</android.support.design.widget.NavigationView>
Run Code Online (Sandbox Code Playgroud)

这是标准的DrawerLayout,它将NavigationDrawer菜单的所有部分组合在一起.对此我的重要补充是FrameLayout ...位,我给了ID content_frame.这是其他活动使用的所有其他布局将被推送/添加/膨胀的地方.

我的BaseActivity.java看起来像这样:

package com.example.test;
import android.content.Intent;
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.support.v7.widget.Toolbar;
import android.view.MenuItem;

public class BaseActivity extends AppCompatActivity {

    DrawerLayout drawerLayout;
    ActionBarDrawerToggle actionBarDrawerToggle;
    Toolbar toolbar;

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

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

        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.drawer_open, R.string.drawer_closed);
        drawerLayout.setDrawerListener(actionBarDrawerToggle);

        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(MenuItem item) {
                switch (item.getItemId()) {

                    case R.id.menu_home:
                        Intent anIntent = new Intent(getApplicationContext(), TheClassYouWantToLoad.class);
                        startActivity(loadPlayer);
                        drawerLayout.closeDrawers();
                        break;

                }
                return false;
            }
        });

    }

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

        actionBarDrawerToggle.syncState();
    }

}
Run Code Online (Sandbox Code Playgroud)

现在,在onNavigationItemSelected方法中,有一个switch语句,用于处理选择每个菜单项时发生的情况.这是重要的一点:

Intent anIntent = new Intent(getApplicationContext(), TheClassYouWantToLoad.class);
startActivity(anIntent);
drawerLayout.closeDrawers(); 
Run Code Online (Sandbox Code Playgroud)

您需要将"TheClassYouWantToLoad"替换为您自己的类.现在在这个新类(可能需要加载一些新的UI元素)中,您需要以下内容:

public class TheClassYouWantToLoad extends BaseActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

FrameLayout contentFrameLayout = (FrameLayout) findViewById(R.id.content_frame); //Remember this is the FrameLayout area within your activity_main.xml
getLayoutInflater().inflate(R.layout.the_layout_you_want_to_load, contentFrameLayout);
    }
}
Run Code Online (Sandbox Code Playgroud)

并将"the_layout_you_want_to_load"替换为要加载的Layout的名称.

  • 浏览navigationDrawer总是会添加到Taks的Back Stack.为了避免内存浪费和简化导航(如果导航到相同的主要活动,它将重新加载最后一个状态)最好将AndroidManifests.xml添加到每个<activity>参数`android:launchMode ="singleTask"`中.这将阻止不断增长的堆栈...请参阅:[API Guides Back Stack](https://developer.android.com/guide/components/activities/tasks-and-back-stack.html#ManagingTasks) (5认同)

suk*_*uku 23

据我所知,您希望导航抽屉出现在每个活动中.有两种方法:

  1. 使用@Russell的答案.创建一个主要活动,其framelayout通常称为content_frame,涵盖整个活动.此活动具有导航抽屉的代码.单击按钮时,您可以使用所需片段的布局替换此布局的内容(即带有多个按钮的片段或说出图像).所以抽屉里的元素都是碎片.在教程中,片段通过getFragmentManager()调用.看看这个人在导航抽屉上的视频系列,幻灯片:https://www.youtube.com/watch? v = K8hSIP2ha-g .尝试在播放视频时实施它

  2. 我个人更喜欢这种方法,但它有其局限性.创建一个基本活动,其中导航抽屉的代码是.这有一个framelayout,通常称为content_frame,它涵盖整个活动.需要使用抽屉的活动扩展此基本活动而不是appcompatactivity或activity.布局膨胀在oncreate中就像这样:getLayoutInflater().inflate(R.layout.activity_this, contentFrameLayout);而不是setContentView.活动开始于此startActivity.

第二种方法的缺点:

a)每次用户更改活动时,都会销毁并重新创建BaseActivity.

b)活动只能扩展一个类,默认情况下变为baseActivity

第二种方法的优点:

a)您可以维护活动堆栈

b)每个活动都可以拥有自己的配置更改规则和onsaveInstance规则.

c)这些活动可以有单独的片段,使用此活动进行交流.尝试在第一种方法中执行此操作将涉及主要活动不必要地实现大量接口(您将学习片段间通信中的接口)