动态改变抽屉布局

dynamically change the drawer layout

我遇到这种情况:启动应用程序时,显示的第一个片段 (A) 包含一些用户的列表。单击用户时,会显示另一个片段 (B),每个用户的抽屉菜单都会不同。

如您所见,我无法在启动应用程序(主要 activity 或 Launcher)时设置 DrawerLayout,因为我还没有 listView 的数据,但必须设置它在应用程序完成启动后单击片段 A 中的列表中的用户时向上(那时我可以检索抽屉菜单的 listView 的数据,由下面的 id 表示:fragment_drawer xml 文件)。

这是 "MainActivity" 的 xml 文件:

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <!-- The main content view -->
    <FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <!-- The navigation drawer, listView is inside MyDrawerFragment's layout-->
    <fragment android:id="@+id/fragment_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:name="mypackage.com.MyDrawerFragment"
        tools:layout="@layout/drawer_layout" />
</android.support.v4.widget.DrawerLayout>

如何实现片段 B 中的目标?这在片段 B 中完全可以实现吗?

如果无法在片段 B 中执行此操作,我正在考虑启动第二个 activity,比如 Activity2,上面的 xml 布局文件将应用于这个新的 activity,当单击片段 A 中的用户时,我只是继续这样做:通过调用 finish() 关闭现有的 Acitvity2 并使用抽屉菜单的新数据创建一个新的 Activity2 实例?这种方法是否可行?

非常感谢任何提示!

谢谢, 肖恩

我必须做一个应用程序,我必须制作一个 Activity 有 4 个片段和一个 ViewPager,其中只有 2 个我会打开一个不同的抽屉。

Activity的布局必须包含DrawerLayout*,但由于Drawer本身取决于我在哪个Fragment上,我认为它应该是负责渲染(或不渲染)抽屉的片段。

*如果Activity不包含DrawerLayout,就不会满屏显示!


我做了类似的事情,尽管它确实需要一些重构和清理:)

基于 Fragment 负责渲染抽屉的想法,但它是 Activity 可以访问它的那个,我制作了两个接口来与 Fragment 和 Activity 通信:

/** 
 * should be implemented by any fragment interested in communicating 
 * with a {@link FragmentListener} Activity
 */
public interface ActivityListener {
    /**
     * called from {@link FragmentListener} requestOpenDrawer
     * the fragment is in charge of rendering its drawer's layout
     */
    public void renderDrawer(DrawerLayout mDrawerLayout, 
                        NavigationView viewById, Activity activity);
}

-

/** 
 * used to communicate FROM fragments, to its parent Activity
 * implemented by {@link MainTabbedActivity}
 */
public interface FragmentListener {
    /**
     * call from a fragment to request opening the drawer
     * note that if the drawer isn't opened by the activity, 
     * it wouldn't cover the whole screen
     */
    void requestOpenDrawer(Fragment requester);

    void requestCloseDrawer();

    DrawerLayout getDrawerLayout();
}

实施

@Override
public void requestOpenDrawer(Fragment requester) {
    mDrawerLayout.openDrawer(Gravity.RIGHT); //Edit Gravity.End need API 14
    if (requester instanceof ActivityListener) {
        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);

        //let fragment render the drawer
        ((ActivityListener) requester).renderDrawer(mDrawerLayout, navigationView, this);
    }
}

-

@Override
public void renderDrawer(DrawerLayout mDrawerLayout, NavigationView viewById, Activity activity) {
   View child = activity.getLayoutInflater().inflate(R.layout.credit_fragment_drawer, null);

    navigationView.addView(child);
}

布局

Activity 布局和 Fragments 布局都只是标准的抽屉实现:

Activity 带抽屉的布局:

<?xml version="1.0" encoding="utf-8"?>
<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/main_tabbed_drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:openDrawer="right">

    <include
        layout="@layout/activity_main_tabbed_content"
        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="right"
        android:fitsSystemWindows="true" />

</android.support.v4.widget.DrawerLayout>

其中 activity_main_tabbed_content 是您要放入 Activity 的任何内容。

Fragments 真的除了一个普通的Fragment 什么都没有。 示例:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- whatever views you want -->
</RelativeLayout>