динамически изменять макет ящика

У меня такая ситуация: при запуске приложения в первом отображаемом фрагменте (A) есть список некоторых пользователей. При нажатии на пользователя отображается другой фрагмент (B), и вместе меню ящика будет отличаться для каждого пользователя.

Как вы можете видеть, я НЕ могу настроить DrawerLayout при запуске приложения (основное действие или Launcher), так как у меня еще нет данных для listView, но мне нужно настроить его при нажатии пользователя в списке в фрагмент A после завершения запуска приложения (вот когда я могу получить данные для listView меню ящика, на что указывает идентификатор: fragment_drawer в XML-файле ниже).

Вот файл xml для «MainActivity»:

<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, я думаю запустить второе действие, скажем, Activity2, и указанный выше файл макета xml будет применен к этому новому действию, при нажатии на пользователя во фрагменте A я просто продолжаю делать это: закрытие существующий Activity2, вызвав finish() и создав новый экземпляр Activity2 с новыми данными для меню ящика? Возможен ли вообще такой подход?

Любые подсказки высоко ценятся!

Спасибо, Шон


person Shawn Chen    schedule 25.05.2016    source источник


Ответы (1)


Мне нужно было сделать приложение, в котором я должен был сделать Activity с 4 фрагментами и ViewPager, где только в 2 я открывал другой Drawer.

Макет Activity должен содержать DrawerLayout*, но, поскольку сам Drawer зависит от того, на каком фрагменте я нахожусь, я решил, что именно фрагмент должен отвечать за рендеринг (или нет) Drawer .

*Если действие не содержит DrawerLayout, оно не будет отображаться на весь экран!


Я сделал что-то подобное, хотя это требует некоторого рефакторинга и очистки :)

Работая над идеей, что Фрагмент отвечает за рендеринг Ящика, но именно Активность имеет к нему доступ, я сделал два интерфейса для связи Фрагмента и Активности:

/** 
 * 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 не имеют ничего, кроме стандартной реализации Drawer:

Макет деятельности с ящиком:

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

Фрагменты действительно не имеют ничего, кроме общего Фрагмента. Пример:

<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>
person RominaV    schedule 25.05.2016
comment
Не могли бы вы предоставить XML-файл макета и примеры кодов действий, фрагментов? Спасибо! - person Shawn Chen; 26.05.2016
comment
Привет, я начал с вашей информации и, наконец, сделал то же самое, используя интерфейс, определенный во фрагменте B и реализованный в активности контейнера, как в этом URL-адресе: developer.android.com/training/basics/fragments/. Я рисую меню в методе onAttach() фрагмента B. Большое спасибо за помощь! - person Shawn Chen; 26.05.2016
comment
@ShawnChen рад, что смог помочь :) - person RominaV; 26.05.2016