我正在使用android导航控制器。
我的主要活动托管一个导航片段,但其他活动(如工具栏和导航底部栏)应放在哪里?
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
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"
app:layout_collapseMode="pin"
app:popupTheme="@style/AppTheme.PopupOverlay" />
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
app:defaultNavHost="true"
app:navGraph="@navigation/navigation" />
<android.support.design.widget.BottomNavigationView
android:id="@+id/bottom_nav_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="@menu/menu_bottom_nav" />
</LinearLayout>
fragment_home.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />
</RelativeLayout>
或者应该这样将ToolBar和BottomNavigationView放在fragment_home.xml中
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/AppTheme.PopupOverlay" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />
<android.support.design.widget.BottomNavigationView
android:id="@+id/bottom_nav_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="@menu/menu_bottom_nav" />
</RelativeLayout>
答案 0 :(得分:1)
我将为您提供一个示例。请记住,我正在使用SDK 28+的最新androidx进行编译,因此,如果您使用的是较旧的版本,则名称空间会有所不同。
我还使用了数据绑定和Kotlin,因此如果您不使用数据绑定,请不要使用布局和数据标签。
工具栏
<layout 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">
<data>
PUT BINDING VARIABLES HERE
</data>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/SSTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:theme="@style/ToolbarTextAppearance">
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
主要活动
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable name="activity" type="com.a35.activities.MainActivity"/>
<variable name="iBindingRecyclerView" type="com.a35.interfaces.IBindingRecyclerView"/>
</data>
<androidx.drawerlayout.widget.DrawerLayout
android:id="@+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="false"
tools:openDrawer="start">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!--TOP TOOLBAR-->
<include
android:id="@+id/toolbarMain"
layout="@layout/toolbar_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<!--TOP BLACK LINE-->
<View
android:id="@+id/vRedLine"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_2"
android:background="@color/black" />
<!-- FrameLayout is used to insert fragments to display -->
<FrameLayout
android:id="@+id/fragPlaceholder"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</LinearLayout>
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
android:background="@color/colorPrimary">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/nav_drawer_header"
android:id="@+id/navHeader"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/lstMenuItems"
android:layout_below="@+id/navHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:bindRcvInterface="@{iBindingRecyclerView}"
app:bindRcvList="@{activity.getDrawerItemList}"/>
<ImageView
android:id="@+id/imgBottomLogo"
android:layout_width="@dimen/dp_160"
android:layout_height="@dimen/dp_35"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="@dimen/dp_35"
android:src="@drawable/scott_logo" />
</RelativeLayout>
</com.google.android.material.navigation.NavigationView>
</androidx.drawerlayout.widget.DrawerLayout>
</layout>
请注意,“主活动”中的导航视图位于抽屉布局内,其中包含用于构建抽屉内容的“回收站视图”。
除此之外,您还将看到名为fragPlaceHolder的片段的内容占位符。
最后注意到,父布局是一个LinearLayout,第一个元素是工具栏的include元素,我们认为合适。
接下来的样式。如果计划将工具栏用作操作栏,则需要使用不依赖于操作栏的样式。 (为了进行记录,您应该使用工具栏)
样式
<!--Full Screen-->
<style name="A35.FullScreen">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
</style>
清单
<application
android:name=".application.A35Application"
android:allowBackup="true"
android:icon="@mipmap/a35_logo"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/A35.FullScreen">
如果更适合您的需求,您也可以将其放在单个活动中。
现在您还有两个步骤。
如果您使用简单的kotlin和数据绑定,则需要调用setActionToolbar并传递找到的UI或使用合成视图。因此,请添加onCreate 后来扩大视图的大小。
setSupportActionBar(toolbar)
您没有问这个,但我也会提供。当您需要更改片段时,我通常会使用一个带有这样的助手方法的BaseActivity。
protected fun swapFragment(fragment: BaseFragment, @Nullable bundle: Bundle?, hideCurrentFrag: Boolean = false) {
if (fragment.isVisible) {
A35Log.e(mClassTag, "swapFragment called on already visible fragment")
return
}
A35Log.v(mClassTag, "swapFragment( ${fragment.javaClass.simpleName} )")
val currentFragBundle = fragment.arguments
if (currentFragBundle == null && bundle != null) {
fragment.arguments = bundle
A35Log.v(mClassTag, "current bundle is null, so setting new bundle passed in")
} else if (bundle != null) {
fragment.arguments?.putAll(bundle)
A35Log.v(mClassTag, "current fragment bundle was not null, so add new bundle to it")
}
val fragmentManager = supportFragmentManager
fragmentManager.executePendingTransactions()
val fragmentTransaction = fragmentManager.beginTransaction()
//Make sure the requested fragment isn't already on the screen before adding it
if (fragment.isAdded) {
A35Log.v(mClassTag, "Fragment is already added")
if (fragment.isHidden) {
A35Log.v(mClassTag, "Fragment is hidden, so show it")
fragmentTransaction.show(fragment)
if(hideCurrentFrag) {
A35Log.v(mClassTag, "hideCurrentFlag = true, hiding current fragment $mSelectedFragment")
fragmentTransaction.hide(mSelectedFragment!!)
}else{
A35Log.v(mClassTag, "hideCurrentFlag = false, removing current fragment $mSelectedFragment")
fragmentTransaction.remove(mSelectedFragment!!)
}
}else{
A35Log.v(mClassTag, "Fragment is already visible")
}
}else if(mSelectedFragment == null){
A35Log.v(mClassTag,"mSelectedFragment = null, so replacing active fragment with new one ${fragment.javaClass.simpleName}")
fragmentTransaction.replace(R.id.fragPlaceholder, fragment)
}else{
A35Log.v(mClassTag, "Fragment is not added, so adding to the screen ${fragment.javaClass.simpleName}")
fragmentTransaction.add(R.id.fragPlaceholder, fragment)
if(hideCurrentFrag) {
A35Log.v(mClassTag, "hideCurrentFlag = true, hiding current fragment $mSelectedFragment")
fragmentTransaction.hide(mSelectedFragment!!)
}else{
A35Log.v(mClassTag, "hideCurrentFlag = false, removing current fragment $mSelectedFragment")
fragmentTransaction.remove(mSelectedFragment!!)
}
}
A35Log.v(mClassTag, "committing swap fragment transaction")
fragmentTransaction.commit()
A35Log.v(mClassTag, "mSelectedFragment = ${fragment.javaClass.simpleName}")
mSelectedFragment = fragment
}
注意*尽管交换片段非常普遍,但是您需要确保正确处理需求。它应该隐藏还是移除。是处理捆绑包还是忽略捆绑包。我提供给您的方法基本上是在显示片段是否不存在和隐藏,而不是在被告知要隐藏片段时删除。
此处未显示处理为导航抽屉构建适配器和列表以及为这些项目连接侦听器单击的操作,因为这不是您的问题,并且不在此问题的范围内。我不想让我的答案过于肿,因此希望这就是您所需要的。
快乐编码。