Android: NavigationDrawer/несколько видов деятельности/одно и то же меню
То, что я пытаюсь сделать, имеет меню NavigationDrawer следующим образом:
NavigationDrawer
Я выяснил, как изменять макеты при нажатии пунктов меню, но как загрузить новую активность, не теряя меню?
Мой главный вопрос:
Например, скажем, один из моих опций меню приведет вас к макету, где есть некоторые кнопки, которые что-то делают. Мне нужно загрузить сопроводительную активность/класс, который будет обрабатывать действия и функциональные возможности этой конкретной "страницы" в приложении. Если другой параметр меню приведет вас к макету только с изображением, это будет другое действие без всего того кода, который обрабатывает функциональность кнопок, поскольку на этом экране нет кнопок.
Надеюсь, это имеет смысл! Я следил за многими учебниками/видеороликами в Интернете, используя несколько методов (фрагменты и т.д.), Но ничего не ответил на мой вопрос.
Ответы
Ответ 1
Из того, что я понимаю, вы хотите, чтобы навигационный ящик присутствовал в каждом действии. Есть два метода:
Используйте ответ @Russell. Сделайте основное действие, имеющее структуру кадра, обычно называемую content_frame, которая охватывает все действие. У этого действия есть код для навигационного ящика. При нажатии кнопки вы можете заменить содержимое этого макета на макет нужного фрагмента (то есть либо фрагмент с несколькими кнопками, либо произнесите изображение). Таким образом, элементы в ящике все фрагменты. В руководствах фрагменты вызываются через getFragmentManager(). Посмотрите серию видео на навигационном ящике от этих ребят, slidenerd: https://www.youtube.com/watch?v=K8hSIP2ha-g. Попробуйте реализовать его во время просмотра видео
Я лично предпочитаю этот метод, но у него есть свои ограничения. Создайте базовую активность, в которой будет код для навигационной панели. Это имеет структуру кадра, обычно называемую 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]()