Android常见的高级组件搭建移动应用界面

Android常见的高级组件结合可以搭建移动应用常见的界面结构,如下图所示:
主内容
侧滑菜单
菜单

上述的界面可以发现有侧滑菜单,界面的主内容区顶部可以显示Home键、应用标题以及菜单。在底部有导航栏方便导航。通过侧滑菜单和底部的导航可以方便实现界面内容的切换。
这样的通用界面可以在多种的应用中进行套用,使用也非常方便。
一、定义顶部的工具条和侧滑菜单
(1)MainActivity对应的布局activity_main.xml如下:

<androidx.drawerlayout.widget.DrawerLayout
    android:id="@+id/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:layout_width="match_parent"
    android:layout_height="match_parent">
    <RelativeLayout
        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" />
    </RelativeLayout>
</androidx.drawerlayout.widget.DrawerLayout>

在上述的布局中DrawerLayout和NavigationView结合定义侧滑菜单。在内容区定义了一个Toolbar.
(2)将自定义的Toolbar设置默认的ActionBar
需要在应用配置文件AndroidManifest.xml中配置如下:

<activity
            android:name=".MainActivity"
            **android:theme="@style/Theme.AppCompat.NoActionBar"**
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
</activity>

设置MainActivity活动的主题维NoActionBar,为Toolbar设置为动作条提供方便。
(3)在MainActivity.kt中设置Toolbar为支持的动作条

setSupportActionBar(binding.toolbar)

(4)定义动作条上的菜单:
假设在res/menu/目录下创建menu.xml为如下内容:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:title="菜单"
      android:icon="@mipmap/ic_launcher"
      app:showAsAction="always">
    <menu>
      <item
          android:id="@+id/aboutItem"
          android:icon="@android:drawable/ic_dialog_info"
          android:title="关于我们"
          app:showAsAction="always" />
      <item
          android:id="@+id/exitItem"
          android:icon="@android:drawable/ic_notification_clear_all"
          android:title="退出应用"
          app:showAsAction="always" />
    </menu>
  </item>
</menu> 

这是一个二级菜单,将一级菜单以图标显示,点击弹出二级菜单,使得二级菜单能同时将菜单标题和图标显示。
(5)修改MainActivity.kt代码,增加菜单的处理:

class MainActivity : AppCompatActivity() {
    
    
    lateinit var binding:ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
       
        configToolbar()
        setContentView(binding.root)
    }

    fun configToolbar(){
    
    
        setSupportActionBar(binding.toolbar)
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
    
    
        menuInflater.inflate(R.menu.menu,menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
    
    
        when(item.itemId){
    
    
            R.id.aboutItem-> Toast.makeText(MainActivity@this,"Testing...",Toast.LENGTH_LONG).show()
            R.id.exitItem-> exitProcess(0)
        }
        return true
    }
}

(6)增加侧滑菜单的导航视图NavigationView,需要修改activity_main.xml布局文件如下:

<androidx.drawerlayout.widget.DrawerLayout
    android:id="@+id/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:layout_width="match_parent"
    android:layout_height="match_parent">
    <RelativeLayout
        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" />
    </RelativeLayout>

    **<com.google.android.material.navigation.NavigationView
        android:id="@+id/navigationView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:headerLayout="@layout/header_layout"
        app:menu="@menu/menu_navigation"
        android:layout_gravity="start"
        />**
</androidx.drawerlayout.widget.DrawerLayout>

其中,
NavigationView元素中定义的
app:headerLayout="@layout/header_layout":对应的是layout目录下的header_layout.xml表示侧滑菜单的头部布局,具体定义略;
app:menu="@menu/menu_navigation":对应的侧滑菜单下部的导航菜单的内容,对应res/menu目录下的menu_navigation.xml,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/favorityItem"
        android:title="我的收藏" android:icon="@android:drawable/btn_star" />
    <item
        android:id="@+id/appItem"
        android:title="关于应用" android:icon="@android:drawable/ic_dialog_info"/>
    <item
        android:id="@+id/configItem"
        android:title="系统配置" android:icon="@android:drawable/ic_menu_manage"/>
</menu>

修改MainActivity.kt,增加对侧滑菜单的处理

class MainActivity : AppCompatActivity() {
    
    
    lateinit var binding:ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
     
        configToolbar()
        configDrawer()
     
        setContentView(binding.root)
    }

    fun configToolbar(){
    
    
        setSupportActionBar(binding.toolbar)
    }

    fun configDrawer(){
    
    
        supportActionBar?.let{
    
    
            it.setDisplayHomeAsUpEnabled(true)
            it.setHomeAsUpIndicator(R.mipmap.ic_launcher)
        }
        binding.navigationView.itemIconTintList = null
        binding.navigationView.setCheckedItem(R.id.favorityItem)
        binding.navigationView.setNavigationItemSelectedListener {
    
    
            when(it.itemId){
    
    
                R.id.favorityItem->Snackbar.make(binding.drawerLayout,"FAVORITE",
                       Snackbar.LENGTH_LONG).setAction("点击"){
    
    
                           exitProcess(0)
                }.show()
                R.id.appItem->Toast.makeText(this,"APP",Toast.LENGTH_LONG).show()
                R.id.configItem->Toast.makeText(this,"CONFIG",Toast.LENGTH_LONG).show()
            }
            binding.drawerLayout.closeDrawer(GravityCompat.START)
            true
        }
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
    
    
        menuInflater.inflate(R.menu.menu,menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
    
    
        when(item.itemId){
    
    
            android.R.id.home->binding.drawerLayout.openDrawer(GravityCompat.START)
            R.id.aboutItem-> Toast.makeText(MainActivity@this,"Testing...",Toast.LENGTH_LONG).show()
            R.id.exitItem-> exitProcess(0)
        }
        return true
    }
}

对上述代码的说明:
(a)代码:

        supportActionBar?.let{
    
    
            it.setDisplayHomeAsUpEnabled(true)
            it.setHomeAsUpIndicator(R.mipmap.ic_launcher)
        }

上述代码块调用的两个函数是允许显示顶部的Home键以及设置顶部Home键的图标为res/mipmap目录的ic_launcher

(b)代码:

binding.navigationView.setNavigationItemSelectedListener {
    
    
            when(it.itemId){
    
    
                R.id.favorityItem->Snackbar.make(binding.drawerLayout,"FAVORITE",
                       Snackbar.LENGTH_LONG).setAction("点击"){
    
    
                           exitProcess(0)
                }.show()
                R.id.appItem->Toast.makeText(this,"APP",Toast.LENGTH_LONG).show()
                R.id.configItem->Toast.makeText(this,"CONFIG",Toast.LENGTH_LONG).show()
            }
            binding.drawerLayout.closeDrawer(GravityCompat.START)
            true
        }
    }

增加侧滑菜单的导航菜单的导航处理。在这里简单的处理显示交互的消息框Toast,并通过binding.drawerLayout.closeDrawer(GravityCompat.START)关闭侧滑菜单。
(c)在Toolbar仍需要增加Home键,通过点击Home键实现侧滑菜单的显示
在onOptionsItemSelected中增加

        when(item.itemId){
    
    
            **android.R.id.home->binding.drawerLayout.openDrawer(GravityCompat.START)**
           ...
         }

这里android.R.id.home对应Home键,如运行结果显示的:显示Home键
(7) 定义底部导航视图BottomNavigationView
(a)修改activity_main.xml布局

  <androidx.drawerlayout.widget.DrawerLayout
    android:id="@+id/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:layout_width="match_parent"
    android:layout_height="match_parent">
    <RelativeLayout
        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" />

        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:layout_toEndOf="@+id/btView"
            />
            
        **<com.google.android.material.bottomnavigation.BottomNavigationView
            android:id="@+id/btView"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:menu="@menu/menu_navigation"
            android:layout_alignParentBottom="true"/>**
    </RelativeLayout>

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/navigationView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:headerLayout="@layout/header_layout"
        app:menu="@menu/menu_navigation"
        android:layout_gravity="start"
        />
</androidx.drawerlayout.widget.DrawerLayout>

(b)定义修改MainActivity增加底部导航视图BottomNavigationView的处理

class MainActivity : AppCompatActivity() {
    
    
    lateinit var binding:ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)

        configToolbar()
        configDrawer()
        configBottomNavigationView()
        setContentView(binding.root)
    }

    fun configToolbar(){
    
    
        setSupportActionBar(binding.toolbar)
    }

    fun configDrawer(){
    
    
        supportActionBar?.let{
    
    
            it.setDisplayHomeAsUpEnabled(true)
            it.setHomeAsUpIndicator(R.mipmap.ic_launcher)
        }
        binding.navigationView.itemIconTintList = null
        binding.navigationView.setCheckedItem(R.id.favorityItem)
        binding.navigationView.setNavigationItemSelectedListener {
    
    
            when(it.itemId){
    
    
                R.id.favorityItem->Snackbar.make(binding.drawerLayout,"FAVORITE",
                       Snackbar.LENGTH_LONG).setAction("点击"){
    
    
                           exitProcess(0)
                }.show()
                R.id.appItem->Toast.makeText(this,"APP",Toast.LENGTH_LONG).show()
                R.id.configItem->Toast.makeText(this,"CONFIG",Toast.LENGTH_LONG).show()
            }
            binding.drawerLayout.closeDrawer(GravityCompat.START)
            true
        }
    }

    fun configBottomNavigationView(){
    
    
        binding.btView.itemIconTintList = null
        binding.btView.setOnItemSelectedListener {
    
    
            when(it.itemId){
    
    
                R.id.favorityItem->Snackbar.make(binding.drawerLayout,"FAVORITE",
                       Snackbar.LENGTH_LONG).setAction("点击"){
    
    
                       exitProcess(0)
                }.show()
                R.id.appItem->Toast.makeText(this,"APP",Toast.LENGTH_LONG).show()
                R.id.configItem->Toast.makeText(this,"CONFIG",Toast.LENGTH_LONG).show()
            }
            true
        }
    }
    
    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
    
    
        menuInflater.inflate(R.menu.menu,menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
    
    
        when(item.itemId){
    
    
            android.R.id.home->binding.drawerLayout.openDrawer(GravityCompat.START)
            R.id.aboutItem-> Toast.makeText(MainActivity@this,"Testing...",Toast.LENGTH_LONG).show()
            R.id.exitItem-> exitProcess(0)
        }
        return true
    }
}

参考文献
《Android移动应用开发(微课版)》 陈轶 清华大学出版社 
 ISBN:978-7-302-59734-6

猜你喜欢

转载自blog.csdn.net/userhu2012/article/details/127545452