前言
1.老规矩先来看看京东tab栏的效果
2.demo实现的效果
此功能核心是Lottie库,对Lottie不熟悉的朋友们可以先了解下或者参考
1.Lottie github
2.Lottie- 让Android动画实现更简单
……
实现
1.build.gradle依赖
implementation 'com.airbnb.android:lottie:3.7.0'
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.core:core-ktx:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
2.activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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"
tools:context=".MainActivity">
<FrameLayout
android:id="@+id/rlMainContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="50dp"
android:background="@android:color/white"
tools:ignore="MissingConstraints" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bnvMain"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="bottom"
app:itemRippleColor="@null"
android:background="@android:color/white"
app:labelVisibilityMode="labeled"
app:itemTextColor="@drawable/selector_main_bottom_text"
app:menu="@menu/main_menu_bottom_navigation"
tools:ignore="MissingConstraints" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
3.selector_main_bottom_text.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/color999" android:state_enabled="false" />
<item android:color="@color/color333" />
</selector>
4.main_menu_bottom_navigation.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<item
android:id="@+id/home"
android:title="首页"
tools:ignore="MenuTitle"/>
<item
android:id="@+id/service"
android:title="服务中心"/>
<item
android:id="@+id/application"
android:title="应用"/>
<item
android:id="@+id/mine"
android:title="我的"/>
</menu>
5.MainActivity
package com.dawnling.dynamictab
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.core.view.forEach
import androidx.fragment.app.Fragment
import com.airbnb.lottie.LottieCompositionFactory
import com.airbnb.lottie.LottieDrawable
import com.google.android.material.bottomnavigation.BottomNavigationItemView
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
private lateinit var mFragments: MutableMap<Int, Fragment>
private var mLottieJsonMap = mutableMapOf(
R.id.home to "lottie/main_tab_home.json",
R.id.service to "lottie/main_tab_mine.json",
R.id.application to "lottie/main_tab_home.json",
R.id.mine to "lottie/main_tab_mine.json"
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
hideTooltip()
initFragment()
val initialItemId = R.id.home
initShow(initialItemId)
bnvMain.setOnNavigationItemSelectedListener {
initShow(it.itemId)
true
}
}
private fun initFragment() {
val fragment1 = BlankFragment.newInstance(0)
val fragment2 = BlankFragment.newInstance(1)
val fragment3 = BlankFragment.newInstance(2)
val fragment4 = BlankFragment.newInstance(3)
mFragments = mutableMapOf(
R.id.home to fragment1,
R.id.service to fragment2,
R.id.application to fragment3,
R.id.mine to fragment4
)
}
private fun initShow(itemId: Int){
showFragment(itemId)
setLottieDrawable(mLottieJsonMap, itemId)
}
private fun showFragment(menuItemId: Int){
var curFragment = supportFragmentManager.fragments.find {
it.isVisible && it in mFragments.values
}
var targetFragment = mFragments[menuItemId]
supportFragmentManager.beginTransaction().apply {
curFragment?.let { if (it.isVisible) hide(it) }
targetFragment?.let {
if (it.isAdded) show(it) else add(R.id.rlMainContainer, it)
}
}.commit()
}
/* 隐藏长按 BottomNavigationItemView 会出现 Toast 的问题*/
private fun hideTooltip() {
bnvMain.menu.forEach {
val menuItemView = findViewById<BottomNavigationItemView>(it.itemId)
menuItemView.setOnLongClickListener {
true
}
}
}
/*设置 LottieDrawable 到每个 MenuItem,并且设置播放动画*/
private fun setLottieDrawable(lottieJsonMap: MutableMap<Int, String>, itemId: Int) {
bnvMain.menu.forEach {
it.icon = LottieDrawable().apply {
var result =
LottieCompositionFactory.fromAssetSync(this@MainActivity, lottieJsonMap[it.itemId])
composition = result.value
}
if (it.itemId == itemId) {
(it.icon as LottieDrawable).playAnimation()
}
}
}
}
其中main_tab_home.json和main_tab_mine.json需要UI提供
demo下载