在上一篇[“Android常见的高级组件搭建移动应用界面”](https://editor.csdn.net/md/?articleId=127545452)中,是通过导航来实现信息栏的显示。这样的操作过于简单。在实际上,通过侧滑菜单的导航菜单和底部视图导航BottomNavigationView的导航往往可以用于不同Fragment切换来完成。
通过Fragment定义不同的UI界面,结合导航实现不同界面的切换,让交互更好友好和方便。
一、定义三个不同界面的Fragment
第一个碎片类定义代码如下:
object FirstFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_first, container, false)
}
}
第二个碎片类定义代码如下:
object SecondFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_second, container, false)
}
}
第三个碎片类定义代码如下:
object ThirdFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_third, container, false)
}
}
上述代码中均将三个碎片类定义成对象类,对象类通过类来维护唯一的对象即自己本身。
二、修改上一篇"Android常见的高级组件搭建移动应用界面"的MainActivity对应的布局文件activity_main.xml,使用FragmentContainerView来承载碎片。代码如下:
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.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/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.constraintlayout.widget.ConstraintLayout
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"
android:background="@android:color/holo_orange_dark"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
**<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragmentLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/toolbar"
app:layout_constraintVertical_bias="0.0"
/>**
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottomNavigationView"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/purple_200"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/toolbar"
app:layout_constraintVertical_bias="1.0"
app:menu="@menu/menu_navigation"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.navigation.NavigationView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/navigationView"
android:layout_gravity="start"
app:menu="@menu/menu_navigation"
app:headerLayout="@layout/layout_header"/>
</androidx.drawerlayout.widget.DrawerLayout>
三、在主活动MainActivity中增加碎片处理的方式
碎片处理有两种方案:
(1)碎片替换
在界面中不同的碎片进行替换,如果需要切换一个新的碎片界面,就用一个新的碎片对象替换原来的碎片。这时代码可以调整为:
class MainActivity : AppCompatActivity() {
lateinit var binding:ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
replaceFragment(FirstFragment)
configToolbar()
configDrawerLayout()
configBottomNavigationView()
setContentView(binding.root)
}
......
/**
* Config toolbar
* 设置头部
*/
fun configToolbar(){
setSupportActionBar(binding.toolbar)
}
fun configDrawerLayout(){
supportActionBar?.let{
it.setDisplayHomeAsUpEnabled(true)
it.setHomeAsUpIndicator(R.mipmap.ic_launcher)
}
binding.navigationView.setCheckedItem(R.id.aboutItem)
binding.navigationView.itemIconTintList = null
binding.navigationView.setNavigationItemSelectedListener {
when(it.itemId){
R.id.appItem->replaceFragment(FirstFragment)
R.id.favorityItem->replaceFragment(SecondFragment)
R.id.configItem->repalceFragment(ThirdFragment)
}
binding.drawerLayout.closeDrawer(GravityCompat.START)
true
}
}
fun configBottomNavigationView(){
binding.bottomNavigationView.itemIconTintList = null
binding.bottomNavigationView.setOnItemSelectedListener{
when(it.itemId){
R.id.appItem->replaceFragment(FirstFragment)
R.id.favorityItem->replaceFragment(SecondFragment)
R.id.configItem->repalceFragment(ThirdFragment)
}
true
}
}
/**
* 实现碎片的替换
* @param fragment Fragment
*/
fun replaceFragment(fragment:Fragment){
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.fragmentLayout,fragment)
transaction.addToBackStack(null)
transaction.commit()
}
}
(2)碎片的隐藏和显示
将所有碎片加入到事务Transaction中,通过事务的显示或隐藏碎片来达到切换碎片对应界面的目的。这时代码可以调整成:
class MainActivity : AppCompatActivity() {
lateinit var binding:ActivityMainBinding
lateinit var currentFragment:Fragment
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
currentFragment = FirstFragment
configToolbar()
configDrawerLayout()
configBottomNavigationView()
switchFragment(currentFragment)
setContentView(binding.root)
}
......
/**
* Config toolbar
* 设置头部
*/
fun configToolbar(){
setSupportActionBar(binding.toolbar)
}
fun configDrawerLayout(){
supportActionBar?.let{
it.setDisplayHomeAsUpEnabled(true)
it.setHomeAsUpIndicator(R.mipmap.ic_launcher)
}
binding.navigationView.setCheckedItem(R.id.aboutItem)
binding.navigationView.itemIconTintList = null
binding.navigationView.setNavigationItemSelectedListener {
**when(it.itemId){
R.id.appItem->switchFragment(FirstFragment)
R.id.favorityItem->switchFragment(SecondFragment)
R.id.configItem->switchFragment(ThirdFragment)
}**
binding.drawerLayout.closeDrawer(GravityCompat.START)
true
}
}
fun configBottomNavigationView(){
binding.bottomNavigationView.itemIconTintList = null
binding.bottomNavigationView.setOnItemSelectedListener{
**when(it.itemId){
R.id.appItem->switchFragment(FirstFragment)
R.id.favorityItem->switchFragment(SecondFragment)
R.id.configItem->switchFragment(ThirdFragment)
}**
true
}
}
......
/**
* 实现碎片的切换
* @param fragment Fragment
*/
**fun switchFragment(fragment: Fragment){
val transaction = supportFragmentManager.beginTransaction()
if(!fragment.isAdded){
transaction.hide(currentFragment)
transaction.add(R.id.fragmentLayout,fragment)
}else{
transaction.hide(currentFragment)
transaction.show(fragment)
}
currentFragment = fragment
transaction.commit()
}**
}
参考文献:
《Android移动应用开发(微课版)》 陈轶 清华大学出版社
ISBN:978-7-302-59734-6