android开发技巧

Android底部导航栏实战

2020-01-22  本文已影响0人  BUG_7621f

微信,QQ这些熟知的Android软件都有底部导航的功能。底部导航却是一个较难实现的功能。让我们通过这篇文章学习一下底部导航的用法。
注:本文全部用Kotlin作为示范代码

1 创建主活动

首先我们创建一个BottomBarTest项目。
然后新建一个MainActivity。我们暂且不需要自动Generate Layout文件。


创建layout_main文件,选择relativelayout



在build.gradle添加如下依赖

implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.vectordrawable:vectordrawable:1.0.1'
implementation 'androidx.navigation:navigation-fragment:2.0.0'
implementation 'androidx.navigation:navigation-ui:2.0.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'
implementation 'androidx.navigation:navigation-fragment-ktx:2.0.0'
implementation 'androidx.navigation:navigation-ui-ktx:2.0.0'

这几个库什么作用我并不想解释

它不重要

老规矩点Sync Now同步


2 添加底部导航栏

首先添加menu文件menu_main.xml。menu的用法我并不想多讲,直接上代码:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/navigation_google"
        android:icon="@drawable/social_google"
        android:title="Google" />

    <item
        android:id="@+id/navigation_stackflow"
        android:icon="@drawable/social_stackflow"
        android:title="StackOverflow" />

    <item
        android:id="@+id/navigation_github"
        android:icon="@drawable/social_github"
        android:title="Github" />
</menu>

图片资源在百度网盘里。(说到百度网盘就恨得不得了每次下载资源慢的不得了)可惜我的Github账号挂了(长叹)...拿去就是这个提取码: dmhv
如果你也要选择精美的icon建议用阿里巴巴图标资源库
选择这三个icon就是为了摆明:遇到问题让Google+StackOverFlow+Github成为习惯,而不是用百度或者CSDN
如果你看到类似于Hardcoded string "Google", should use @string resourse的警告的话,下面有一个解决方案

不用管它

接着在主布局中添加导航栏:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    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">

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/nav_view"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:layout_marginStart="0dp"
        android:layout_marginEnd="0dp"
        android:layout_alignParentBottom="true"
        android:background="?android:attr/windowBackground"
        app:menu="@menu/menu_main" />

</RelativeLayout>

我们把导航栏的高度设置为ActionBar的默认高度(这是为了最后一步使用),因为是底部导航栏,所以设置alignParentBottom为true。

3 创建碎片

前两步是最简单的!!!


首先我们在MainActivity的同级目录下创建ui目录。显然是存放碎片用的。接着建三个目录google,github和stack,用于存放三个按钮的界面碎片
碎片的代码还是很好理解的,以google文件夹为例,我们建立两个文件,GoogleFragment.kt,GoogleViewModel.kt
代码如下:
class GoogleFragment : Fragment() {

    private lateinit var googleViewModel: GoogleViewModel

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        googleViewModel =
            ViewModelProviders.of(this).get(GoogleViewModel::class.java)
        val root = inflater.inflate(R.layout.fragment_google, container, false)
        val textView: TextView = root.findViewById(R.id.text_google)
        googleViewModel.text.observe(this, Observer {
            textView.text = it
        })
        return root
    }
}
class GoogleViewModel : ViewModel() {

    private val _text = MutableLiveData<String>().apply {
        value = "Welcome to Google"
    }
    val text: LiveData<String> = _text
}

就是简单的碎片调用,没什么好说的。接着创建碎片布局文件fragment_google.xml,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/text_google"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="30sp"
        android:textColor="#000000"
        android:layout_marginTop="20dp"
        android:layout_marginLeft="20dp"/>

</LinearLayout>

我们创建了一个基本布局。可以看到这就是碎片的基本布局了(。。一个textview而已
以此类推完成另外2个文件夹的代码

4 完成MainActivity控制

目前运行项目,你得到的界面应该是这样的

原因很简单啊,我们还没有在MainActivity.kt中写任何东西。现在我们需要完成最后的配置。
首先,为了能够放置一个动态Fragment,我们首先需要新建一个navigation。在res目录下新建一个navigation文件夹
然后新建mobile_navigation.xml



代码如下:
<?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/mobile_navigation"
    app:startDestination="@+id/navigation_google">

    <fragment
        android:id="@+id/navigation_google"
        android:name="com.example.bottombartest.ui.google.GoogleFragment"
        android:label="Google"
        tools:layout="@layout/fragment_google" />

    <fragment
        android:id="@+id/navigation_github"
        android:name="com.example.bottombartest.ui.github.GithubFragment"
        android:label="Github"
        tools:layout="@layout/fragment_github" />

    <fragment
        android:id="@+id/navigation_stackflow"
        android:name="com.example.bottombartest.ui.stack.StackFragment"
        android:label="StackOverflow"
        tools:layout="@layout/fragment_stack" />

</navigation>

我们平时很少用到navigation控件。其实不难理解,navigation控件就是可以用于切换的控件。我们放入3个fragment以便切换。有一点就是android:lable属性。这个属性指的是ActionBar上的字。
写完了navigation我们要在layout_main里添加这个控件。可以把它想象成一个碎片。添加方法如下:

<fragment
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="?attr/actionBarSize"
        app:defaultNavHost="true"
        app:navGraph="@navigation/mobile_navigation" />

最后我们要在mainactivity里注册这些控件:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.layout_main)
        val navView: BottomNavigationView = findViewById(R.id.nav_view)
        val navController = findNavController(R.id.nav_host_fragment)
        val appBarConfiguration = AppBarConfiguration(
            setOf(
                R.id.navigation_google, R.id.navigation_github, R.id.navigation_stackflow
            )
        )
        setupActionBarWithNavController(navController, appBarConfiguration)
        navView.setupWithNavController(navController)
    }
}

效果如下:




读完这篇文章你一定很有收获。我们详细学习了底部导航栏的用法。由于Github账号出错的问题,我无法把这个项目上传到Github,大家不可以fork和提交PR,请大家原谅一下。

上一篇 下一篇

猜你喜欢

热点阅读