在上一篇[“Android常见的高级组件搭建移动应用界面”](https://editor.csdn.net/md/?articleId=127545452)中,是通过导航来实现信息栏的显示。这样的操作过于简单。在实际上,通过侧滑菜单的导航菜单和底部视图导航BottomNavigationView的导航往往可以用于不同Fragment切换来完成。
通过Fragment定义不同的UI界面,结合导航实现不同界面的切换,让交互更好友好和方便。
1. Define Fragments with three different interfaces.
The first fragment class definition code is as follows:
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)
}
}
The second fragment class definition code is as follows:
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)
}
}
The third fragment class definition code is as follows:
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)
}
}
In the above code, three fragment classes are defined as object classes. The object class maintains the only object, itself, through the class.
2. Modify the layout file activity_main.xml corresponding to MainActivity in the previous article "Common Advanced Components in Android to Build Mobile Application Interfaces" and use FragmentContainerView to host fragments. code show as below:
<?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>
3. Add a fragment processing method to the main activity MainActivity.
There are two options for fragment processing:
(1) Fragment replacement.
Replace different fragments in the interface. If you need to switch to a new fragment interface, replace it with a new fragment object. Fragments of the original. At this time the code can be adjusted to:
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) Hiding and displaying fragments:
Add all fragments to the transaction, and display or hide the fragments in the transaction to achieve the purpose of switching the corresponding interface of the fragments. At this time the code can be adjusted to:
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()
}**
}
References:
"Android Mobile Application Development (Micro Course Edition)" Chen Yi Tsinghua University Press
ISBN: 978-7-302-59734-6