Android: NavigationDrawer/несколько видов деятельности/одно и то же меню

То, что я пытаюсь сделать, имеет меню NavigationDrawer следующим образом: NavigationDrawer

Я выяснил, как изменять макеты при нажатии пунктов меню, но как загрузить новую активность, не теряя меню?

Мой главный вопрос:

Например, скажем, один из моих опций меню приведет вас к макету, где есть некоторые кнопки, которые что-то делают. Мне нужно загрузить сопроводительную активность/класс, который будет обрабатывать действия и функциональные возможности этой конкретной "страницы" в приложении. Если другой параметр меню приведет вас к макету только с изображением, это будет другое действие без всего того кода, который обрабатывает функциональность кнопок, поскольку на этом экране нет кнопок.

Надеюсь, это имеет смысл! Я следил за многими учебниками/видеороликами в Интернете, используя несколько методов (фрагменты и т.д.), Но ничего не ответил на мой вопрос.

Ответы

Ответ 1

Из того, что я понимаю, вы хотите, чтобы навигационный ящик присутствовал в каждом действии. Есть два метода:

  1. Используйте ответ @Russell. Сделайте основное действие, имеющее структуру кадра, обычно называемую content_frame, которая охватывает все действие. У этого действия есть код для навигационного ящика. При нажатии кнопки вы можете заменить содержимое этого макета на макет нужного фрагмента (то есть либо фрагмент с несколькими кнопками, либо произнесите изображение). Таким образом, элементы в ящике все фрагменты. В руководствах фрагменты вызываются через getFragmentManager(). Посмотрите серию видео на навигационном ящике от этих ребят, slidenerd: https://www.youtube.com/watch?v=K8hSIP2ha-g. Попробуйте реализовать его во время просмотра видео

  2. Я лично предпочитаю этот метод, но у него есть свои ограничения. Создайте базовую активность, в которой будет код для навигационной панели. Это имеет структуру кадра, обычно называемую content_frame, которая охватывает всю деятельность. Действия, которые должны иметь ящик, расширяют эту базовую активность вместо приложения или активности. Инфляция компоновки работает следующим образом: getLayoutInflater().inflate(R.layout.activity_this, contentFrameLayout); вместо setContentView. Здесь действия начинаются через startActivity.

Минусы 2-го метода:

a) BaseActivity уничтожается и воссоздается каждый раз, когда пользователь меняет активность.

б) действие может расширять только один класс, который по умолчанию становится baseActivity

Плюсы 2-го метода:

а) Вы можете поддерживать стек активности

б) Каждое действие может иметь свои собственные правила изменения конфигурации и правила onsaveInstance.

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

Ответ 2

Благодаря вышеприведенным ответам я смог сделать именно то, что хотел, вот что я сделал для тех, кто ищет это в будущем:

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

Это стандартный DrawerLayout, который объединяет все биты и куски для меню NavigationDrawer. Важным дополнением к этому является бит FrameLayout..., которому я дал ID content_frame. В этом случае все другие макеты, используемые другими видами деятельности, будут нажиматься/добавляться/накачаться.

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

}

Теперь, в методе onNavigationItemSelected, существует оператор switch, который обрабатывает то, что происходит, когда выбран каждый пункт меню. Это важный бит:

Intent anIntent = new Intent(getApplicationContext(), TheClassYouWantToLoad.class);
startActivity(anIntent);
drawerLayout.closeDrawers(); 

Вам нужно заменить "TheClassYouWantToLoad" на свой собственный класс. Теперь в этом новом классе (который предположительно требует, чтобы некоторые новые элементы пользовательского интерфейса загружались), вам нужно следующее:

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

и замените "the_layout_you_want_to_load" на имя макета, который вы хотите загрузить.

Ответ 3

Если вы начнете новое действие, вы потеряете свое меню, потому что новая активность будет охватывать старую активность. Для этого вам нужно использовать фрагменты. Подумайте о фрагментах как о деятельности, которая может жить в рамках другой деятельности.

Используйте фрагменты, но добавьте элементы пользовательского интерфейса в макет действия за пределами FrameLayout (id: content_frame), а затем, когда вы нажимаете на элемент меню, транзакция фрагмента влияет только на Content_frame FrameLayout, оставляя все остальные элементы макета в место.

Повесьте туда, приятель, это станет более ясным отсюда... пока вы не нажмете следующую стену: D

Я предлагаю этот учебник: https://www.udacity.com/course/viewer#!/c-ud853/l-1395568821

И этот материал: http://developer.android.com/training/implementing-navigation/nav-drawer.html

Ответ 4

Вы должны взять на себя BaseActivity с навигационным ящиком в качестве нормальной деятельности. Затем после Расширения этого BaseActvity для всей другой деятельности.

Примечание: В BaseActivity вы должны использовать Framelayout вместо вашего включаемого файла, как показано ниже. Код GitHub доступен здесь

<com.google.android.material.appbar.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/FullscreenTheme.AppBarOverlay">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="90dp"
        android:background="@color/colorPrimary"
        app:popupTheme="@style/FullscreenTheme.PopupOverlay"
        >

    </androidx.appcompat.widget.Toolbar>

</com.google.android.material.appbar.AppBarLayout>

<FrameLayout
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/transparent" />

<com.google.android.material.floatingactionbutton.FloatingActionButton
    android:id="@+id/img_menu_prac_test"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|end"
    android:layout_marginRight="@dimen/fab_margin"
    android:layout_marginBottom="16dp"
    app:srcCompat="@drawable/ic_practice_test"
    tools:ignore="VectorDrawableCompat"
    app:borderWidth="0dp"
    android:backgroundTint="@color/white"
    app:maxImageSize="58dp"
    />

Для получения полного кода посетите проект Github Нажмите здесь, чтобы загрузить завершенный проект Here is Common Navigation Drawer

All activity Design