Android导航组件“向上按钮”打开抽屉导航

业无高卑志当坚,男儿有求安得闲?这篇文章主要讲述Android导航组件“向上按钮”打开抽屉导航相关的知识,希望能为你提供帮助。
我正在尝试使用带导航图和导航控制器的导航组件实现简单导航。我有我的MainActivity,带有汉堡图标和应用标题的动作栏,抽屉导航和内容区域。
内容区域是我显示不同片段的地方。
内容区域首先加载我的homescreenFragment,其中包含4个按钮(新闻,事件,时间表,个人资料) - 每个按钮都会将片段加载到我的MainActivity的内容区域。它运行正常,唯一的问题如下:当我按下新闻按钮并从我的主屏幕导航到我的NewsFragment时,它加载片段确定并将操作栏标题更改为新闻。汉堡图标更改为“向上按钮”图标,但是当我按下它时,应用程序打开导航抽屉,就好像我按下汉堡包图标而不是导航回到主屏幕。
如何使按钮上升而不显示左侧导航抽屉?
这是我的MainActivity.java:

import android.os.Bundle; import android.support.design.widget.NavigationView; import android.support.v4.view.GravityCompat; 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 androidx.navigation.NavController; import androidx.navigation.Navigation; import androidx.navigation.ui.NavigationUI; public class MainActivity extends AppCompatActivity{Toolbar m_toolbar; DrawerLayout m_drawer; ActionBarDrawerToggle m_toggle; NavigationView m_navigationView; NavController m_navController; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); m_toolbar = findViewById(R.id.toolbar); setSupportActionBar(m_toolbar); m_drawer = findViewById(R.id.drawer_layout); m_navigationView = findViewById(R.id.nav_drawer_view); m_navController = Navigation.findNavController(this, R.id.content); m_toggle = new ActionBarDrawerToggle( this, m_drawer, m_toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); m_drawer.addDrawerListener(m_toggle); //m_toggle.syncState(); //connect actionbar icon and drawer with nav controller NavigationUI.setupWithNavController(m_navigationView, m_navController); NavigationUI.setupActionBarWithNavController(this, m_navController); NavigationUI.setupActionBarWithNavController(this, m_navController, m_drawer); }@Override public boolean onSupportNavigateUp() { return Navigation.findNavController(this, R.id.nav_drawer_view).navigateUp() || super.onSupportNavigateUp(); }@Override public void onBackPressed() { DrawerLayout drawer = findViewById(R.id.drawer_layout); if (drawer.isDrawerOpen(GravityCompat.START)) { drawer.closeDrawer(GravityCompat.START); } else { super.onBackPressed(); } }}

【Android导航组件“向上按钮”打开抽屉导航】我的activity_main.xml
< ?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/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:openDrawer="start"> < LinearLayout android:orientation="vertical" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> < android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/AppTheme.AppBarOverlay"> < android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay" /> < /android.support.design.widget.AppBarLayout> < FrameLayout android:layout_width="match_parent" android:layout_height="match_parent"> < fragment android:id="@+id/content" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" android:name="androidx.navigation.fragment.NavHostFragment" app:navGraph="@navigation/nav_graph" app:defaultNavHost="true"/> < /FrameLayout> < /LinearLayout> < android.support.design.widget.NavigationView android:id="@+id/nav_drawer_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true" app:headerLayout="@layout/nav_header_main" app:menu="@menu/activity_main_drawer" /> < /android.support.v4.widget.DrawerLayout>

导航图:
< ?xml version="1.0" encoding="utf-8"?> < navigation 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/nav_graph" app:startDestination="@id/homeScreenFragment"> < fragment android:id="@+id/homeScreenFragment" android:name="com.mysample.meganews.Fragments.HomeScreenFragment" android:label="@string/app_name" tools:layout="@layout/home_screen_fragment" > < action android:id="@+id/action_to_news" app:destination="@id/newsFragment" app:enterAnim="@anim/nav_default_enter_anim" app:exitAnim="@anim/nav_default_exit_anim" /> < action android:id="@+id/action_to_events" app:destination="@id/eventsFragment" app:enterAnim="@anim/nav_default_pop_enter_anim" app:exitAnim="@anim/nav_default_pop_exit_anim" /> < /fragment> < fragment android:id="@+id/newsFragment" android:name="com.mysample.meganews.Fragments.NewsFragment" android:label="@string/hs_title_news" tools:layout="@layout/news_fragment" /> < fragment android:id="@+id/eventsFragment" android:name="com.mysample.meganews.Fragments.EventsFragment" android:label="events_fragment" tools:layout="@layout/events_fragment" /> < /navigation>

HomeScreenFragment.java文件:
import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.RelativeLayout; import androidx.navigation.NavController; import androidx.navigation.Navigation; /** * A simple {@link Fragment} subclass. */ public class HomeScreenFragment extends Fragment {public HomeScreenFragment() { // Required empty public constructor }@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment return inflater.inflate(R.layout.home_screen_fragment, container, false); }@Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); RelativeLayout rl_news = view.findViewById(R.id.ll_news_btn); RelativeLayout rl_events = view.findViewById(R.id.ll_events_btn); rl_news.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.action_to_news)); rl_events.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.action_to_events)); } }

build.gradle文件:
apply plugin: 'com.android.application'android { compileSdkVersion 28 defaultConfig { applicationId "com.mysample.meganews" minSdkVersion 16 targetSdkVersion 28 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } }dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support:design:28.0.0' implementation 'com.android.support.constraint:constraint-layout:1.1.3' implementation 'com.android.support:support-v4:28.0.0' implementation 'android.arch.lifecycle:extensions:1.1.1' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' implementation 'android.arch.navigation:navigation-fragment:1.0.0-alpha11' implementation 'android.arch.navigation:navigation-ui:1.0.0-alpha11' }

答案这个问题是由于混合了不同的API。这是正确的代码:
activity_main.xml中:

< LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> < androidx.appcompat.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="@color/colorPrimary" android:theme="@style/ThemeOverlay.AppCompat.Dark" /> < fragment android:id="@+id/content" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" android:name="androidx.navigation.fragment.NavHostFragment" app:navGraph="@navigation/nav_graph" app:defaultNavHost="true"/> < /LinearLayout> < com.google.android.material.navigation.NavigationView android:id="@+id/nav_drawer_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" app:headerLayout="@layout/nav_header_main" app:menu="@menu/activity_main_drawer" /> < /androidx.drawerlayout.widget.DrawerLayout>

main activity.Java:
import android.os.Bundle; import com.google.android.material.navigation.NavigationView; import androidx.core.view.GravityCompat; import androidx.drawerlayout.widget.DrawerLayout; import androidx.appcompat.app.ActionBarDrawerToggle; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; import androidx.lifecycle.ViewModelProviders; import androidx.navigation.NavController; import androidx.navigation.Navigation; import androidx.navigation.ui.NavigationUI; import android.view.MenuItem; import android.view.ViewParent; public class MainActivity extends AppCompatActivity { private Toolbar mToolbar; private DrawerLayout mDrawer; private ActionBarDrawerToggle mToggle; private NavigationView mNavigationView; private NavController mNavController; private MainViewModel mViewModel; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mViewModel = ViewModelProviders.of(this).get(MainViewModel.class); setupNavigation(); }private void setupNavigation() { mToolbar = findViewById(R.id.toolbar); setSupportActionBar(mToolbar); getSupportActionBar().setDisplayHomeAsUpEnabled(true); mDrawer = findViewById(R.id.drawerLayout); mNavigationView = findViewById(R.id.nav_drawer_view); mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() { @Override public boolean onNavigationItemSelected(MenuItem menuItem) {//// we need this line to handle the navigation //boolean handled = NavigationUI.onNavDestinationSelected(menuItem, mNavController); //if (handled) { //ViewParent parent = mNavigationView.getParent(); //if (parent instanceof DrawerLayout) { //((DrawerLayout) parent).closeDrawer(mNavigationView); //} //}return true; } }); mNavController = Navigation.findNavController(this, R.id.content); NavigationUI.setupActionBarWithNavController(this, mNavController, mDrawer); // Tie nav graph to items in nav drawer NavigationUI.setupWithNavController(mNavigationView, mNavController); }@Override public boolean onSupportNavigateUp() { //return Navigation.findNavController(this, R.id.content).navigateUp(); //return mNavController.navigateUp()|| super.onSupportNavigateUp(); return NavigationUI.navigateUp(mNavController, mDrawer); }@Override public void onBackPressed() { if (mDrawer.isDrawerOpen(GravityCompat.START)) { mDrawer.closeDrawer(GravityCompat.START); } else { super.onBackPressed(); } }

另一答案我有同样的问题,并通过以下解决方法修复它。
mNavController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() { @Override public void onDestinationChanged(@NonNull NavController controller, @NonNull NavDestination destination, @Nullable Bundle arguments) { if (mAppBarConfiguration.getTopLevelDestinations().contains(destination.getId())) { mToggle.setDrawerIndicatorEnabled(true); } else { mToggle.setDrawerIndicatorEnabled(false); } } });

还要确保将click侦听器设置为ActionBarDrawerToggle,如下所示。
mToggle.setToolbarNavigationClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mActivity.onBackPressed(); } });


    推荐阅读