素材巴巴 > 程序开发 >

Android 底部导航栏(二、自定义View Fragment)

程序开发 2023-09-17 21:57:59

上一片文章用的是BottomNavigationView+Menu+Fragment,但是可能有时候需求不一样,menu的样式不太够,所以需要自定义View来实现。

Android 底部导航栏(一、BottomNavigationView+Menu+Fragment)_&岁月不待人&的博客-CSDN博客_android 底部导航栏

自定义View:实现思路是自定义一个XMl布局,放五个切换的Item,根据需求的样式去绘制。最后加上Fragment的切换,点击监听等等,坏处的话就是自己写的,可能没有封装好的那么完善,很多方法,状态需要自己去写。

直接上代码吧!首先是XML布局代码:


 

展示出来的效果是:

 就是写自定义View:

主要就是绑定布局,为每一个Item添加点击事件,这儿我只做了简单的点击回调

package com.example.lxview.base.widgetimport android.content.Context
 import android.util.AttributeSet
 import android.view.LayoutInflater
 import android.view.View
 import android.widget.LinearLayout
 import androidx.constraintlayout.widget.ConstraintLayout
 import com.example.lxview.Rclass MainBottomNavBar @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : ConstraintLayout(context, attrs, defStyleAttr) {private lateinit var videoContainer: ConstraintLayoutprivate lateinit var navHome: LinearLayoutprivate lateinit var navTools: LinearLayoutprivate lateinit var navPlay: LinearLayoutprivate lateinit var navMe: LinearLayoutprivate lateinit var navRelax: LinearLayoutvar listener:ResultClick?=nullinit {initView()}private fun initView() {View.inflate(context, R.layout.main_act_bottom_nav_bar, this)videoContainer = findViewById(R.id.act_main_bottom_nav_ll)navHome = findViewById(R.id.bottom_bar_home)navTools = findViewById(R.id.bottom_bar_tools)navPlay = findViewById(R.id.bottom_bar_play)navMe = findViewById(R.id.bottom_bar_mine)navRelax = findViewById(R.id.bottom_bar_relax)navHome.setOnClickListener {listener?.click(0)}navTools.setOnClickListener {listener?.click(1)}navPlay.setOnClickListener {listener?.click(2)}navRelax.setOnClickListener {listener?.click(3)}navMe.setOnClickListener {listener?.click(4)}}
 }interface ResultClick{fun click(int: Int)
 }

第三步,在展示的Activity 的 xml文件里引用此布局,上面的FrameLayout用来放置fragment,底部放导航栏。


 
 

第4步:在Activity代码里加上逻辑,继承ResultClick接口,复写click方法,用replaceFragment实现每次点击item时切换fragment

package com.example.lxviewimport android.view.MotionEvent
 import android.widget.FrameLayout
 import com.example.lxview.base.activity.BaseActivity
 import com.example.lxview.base.fragment.BaseFragment
 import com.example.lxview.base.widget.MainBottomNavBar
 import com.example.lxview.home.fragment.*
 import androidx.fragment.app.Fragment
 import androidx.fragment.app.FragmentTransaction
 import com.example.lxview.base.widget.ResultClick/*** author: 李 祥* date:   2022/3/31 1:57 下午* description:*/
 class MainActivity : BaseActivity(),ResultClick{override val contentId: Intget() = R.layout.activity_mainprivate var indicatorView: MainBottomNavBar? = nullprivate lateinit var fragments: Arrayprivate lateinit var curSelectId: Stringprivate lateinit var homeFragment: HomeFragmentprivate lateinit var toolsFragment: ToolsFragmentprivate lateinit var relaxFragment: RelaxFragmentprivate lateinit var meFragment: MineFragmentprivate lateinit var playFragment: PlayFragmentprivate lateinit var container: FrameLayoutoverride fun initView() {indicatorView = findViewById(R.id.navigation)indicatorView?.listener = thiscontainer = findViewById(R.id.fragment_container)homeFragment = HomeFragment()toolsFragment = ToolsFragment()relaxFragment = RelaxFragment()meFragment = MineFragment()playFragment = PlayFragment()curSelectId = homeFragment.id.toString()fragments = arrayOf(homeFragment, toolsFragment, playFragment, relaxFragment, meFragment)fragments.forEach {addFragment(it,it.tag.toString())hideFragment(it)}showFragment(fragments[0])}//添加Fragment到FragmentList中private fun addFragment(fragment: Fragment, tag: String) {val fragmentManager = supportFragmentManagerval transaction: FragmentTransaction = fragmentManager.beginTransaction()transaction.add(R.id.fragment_container, fragment, tag)transaction.commit()}// 清空fragmentList的所有Fragment,替换成新的Fragment,注意Fragment里面的坑private fun replaceFragment(fragment: Fragment, tag: String) {val fragmentManager = supportFragmentManagerval transaction: FragmentTransaction = fragmentManager.beginTransaction()transaction.replace(R.id.fragment_container, fragment, tag)transaction.commit()}//移除指定的Fragmentprivate fun removeFragment(fragment: Fragment) {val fragmentManager = supportFragmentManagerval transaction: FragmentTransaction = fragmentManager.beginTransaction()transaction.remove(fragment)transaction.commit()}//把Fragment设置成显示状态,但是并没有添加到FragmentList中private fun showFragment(fragment: Fragment) {val fragmentManager = supportFragmentManagerval transaction: FragmentTransaction = fragmentManager.beginTransaction()transaction.show(fragment)transaction.commit()}//把Fragment设置成显示状态,但是并没有添加到FragmentList中private fun hideFragment(fragment: Fragment) {val fragmentManager = supportFragmentManagerval transaction: FragmentTransaction = fragmentManager.beginTransaction()transaction.hide(fragment)transaction.commit()}// 效果和show相近,创建视图,添加到containerid指定的Added列表,FragmentList依然保留,但是会引起生命周期的变化private fun attachFragment(fragment: Fragment) {val fragmentManager = supportFragmentManagerval transaction: FragmentTransaction = fragmentManager.beginTransaction()transaction.attach(fragment)transaction.commit()}// 效果和hide相近,清除视图,从containerid指定的Added列表移除,FragmentList依然保留,但是会引起生命周期的变化private fun detachFragment(fragment: Fragment) {val fragmentManager = supportFragmentManagerval transaction: FragmentTransaction = fragmentManager.beginTransaction()transaction.detach(fragment)transaction.commit()}override fun click(int: Int) {//实现fragment切换replaceFragment(fragments[int],fragments[int].tag.toString())}override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {if (ev?.action ==MotionEvent.BUTTON_BACK){application.onTerminate()}return super.dispatchTouchEvent(ev)}override fun onTouchEvent(event: MotionEvent?): Boolean {if (event?.action ==MotionEvent.BUTTON_BACK){application.onTerminate()}return super.onTouchEvent(event)}}

总结:我这上面只实现了简单的点击切换,用自定义View来实现底部导航栏,很自由,可以实现一些稀奇古怪的需求,但是很多方法的回调,切换时的动画,就需要自己去实现,可能会相对复杂一些。所以若是普通的导航栏,还是用Android自带的组件去实现比较好!

eg:使用replaceFragment,会清空掉当前的fragmnet列表,每次都是重新创建fragment,所以在一些界面的状态保存上就会有问题,所以也可以使用hide和show方法来进行点击切换,且不会销毁掉fragment


标签:

上一篇: 基于NGUI的下拉菜单插件制作9.28 下一篇:
素材巴巴 Copyright © 2013-2021 http://www.sucaibaba.com/. Some Rights Reserved. 备案号:备案中。