日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于 Kotlin 一行代码实现 android 导航栏 BottomBar

發布時間:2025/4/5 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于 Kotlin 一行代码实现 android 导航栏 BottomBar 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

主要功能點

  • 構建者模式鏈式設置導航欄條目
  • 自定義導航欄的字體大小圖片大小
  • 支持純文字類型
  • 支持底部按鈕點擊事件
  • 代碼簡潔不到300行,只有一個類 直接拿來用
  • 看效果是否滿意

    上代碼

    直接先貼代碼BottomBar.kt

    /*** 文件:BottomBar* 時間:2018/8/22.* 備注:頂部導航欄*/import android.annotation.SuppressLint import android.content.Context import android.graphics.* import android.graphics.drawable.BitmapDrawable import android.support.v4.app.Fragment import android.support.v4.content.ContextCompat import android.support.v7.app.AppCompatActivity import android.util.AttributeSet import android.view.MotionEvent import android.view.Viewclass BottomBar : View {private var containerId: Int = 0private val fragmentClassList = ArrayList<Class<*>>()private val titleList = ArrayList<String>()private val iconResBeforeList = ArrayList<Int>()private val iconResAfterList = ArrayList<Int>()private val fragmentList = ArrayList<Fragment>()private var itemCount: Int = 0private val paint = Paint()private val iconBitmapBeforeList = ArrayList<Bitmap?>()private val iconBitmapAfterList = ArrayList<Bitmap?>()private val iconRectList = ArrayList<Rect>()var currentIndex: Int = 0private setprivate var firstCheckedIndex: Int = 0private var titleColorBefore = Color.parseColor("#999999")private var titleColorAfter = Color.parseColor("#ff5d5e")private var titleSizeInDp = 10private var iconWidth = 20private var iconHeight = 20private var titleIconMargin = 5private var titleBaseLine: Int = 0private val titleXList = ArrayList<Int>()private var parentItemWidth: Int = 0private var target = -1private var currentFragment: Fragment? = nullconstructor(context: Context?) : super(context)constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int): super(context, attrs, defStyleAttr)private lateinit var listen:(Int)->Unitfun setClickListen(listen:(Int)->Unit ){this.listen = listen}fun setContainer(containerId: Int): BottomBar {this.containerId = containerIdreturn this}fun setTitleBeforeAndAfterColor(beforeResCode: String, AfterResCode: String): BottomBar {titleColorBefore = Color.parseColor(beforeResCode)titleColorAfter = Color.parseColor(AfterResCode)return this}fun setTitleSize(titleSizeInDp: Int): BottomBar {this.titleSizeInDp = titleSizeInDpreturn this}fun setIconWidth(iconWidth: Int): BottomBar {this.iconWidth = iconWidthreturn this}fun setTitleIconMargin(titleIconMargin: Int): BottomBar {this.titleIconMargin = titleIconMarginreturn this}fun setIconHeight(iconHeight: Int): BottomBar {this.iconHeight = iconHeightreturn this}fun addItem(fragmentClass: Class<*>, title: String, iconResBefore: Int, iconResAfter: Int): BottomBar {fragmentClassList.add(fragmentClass)titleList.add(title)iconResBeforeList.add(iconResBefore)iconResAfterList.add(iconResAfter)return this}fun setFirstChecked(firstCheckedIndex: Int): BottomBar {this.firstCheckedIndex = firstCheckedIndexreturn this}fun build() {itemCount = fragmentClassList.sizefor (i in 0 until itemCount) {val beforeBitmap = getBitmap(iconResBeforeList[i])iconBitmapBeforeList.add(beforeBitmap)val afterBitmap = getBitmap(iconResAfterList[i])iconBitmapAfterList.add(afterBitmap)val rect = Rect()iconRectList.add(rect)val clx = fragmentClassList[i]var fragment: Fragment? = nulltry {fragment = clx.newInstance() as Fragment} catch (e: InstantiationException) {e.printStackTrace()} catch (e: IllegalAccessException) {e.printStackTrace()}fragmentList.add(fragment!!)}currentIndex = firstCheckedIndexswitchFragment(currentIndex)invalidate()}private fun getBitmap(resId: Int): Bitmap? {if (resId == 0) return nullval bitmapDrawable =ContextCompat.getDrawable(context,resId) as BitmapDrawablereturn bitmapDrawable.bitmap}override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {super.onLayout(changed, left, top, right, bottom)initParam()}private fun initParam() {if (itemCount != 0) {//單個item寬高parentItemWidth = width / itemCountval parentItemHeight = height//圖標邊長val iconWidth = dp2px(this.iconWidth.toFloat())//先指定20dpval iconHeight = dp2px(this.iconHeight.toFloat())//圖標文字marginval textIconMargin = dp2px(titleIconMargin.toFloat() / 2)//標題高度val titleSize = dp2px(titleSizeInDp.toFloat())//這里先指定10dppaint.textSize = titleSize.toFloat()val rect = Rect()paint.getTextBounds(titleList[0], 0, titleList[0].length, rect)val titleHeight = rect.height()//從而計算得出圖標的起始top坐標、文本的baseLineval iconTop = (parentItemHeight - iconHeight - textIconMargin - titleHeight) / 2titleBaseLine = parentItemHeight - iconTop//對icon的rect的參數進行賦值val firstRectX = (parentItemWidth - iconWidth) / 2//第一個icon的左for (i in 0 until itemCount) {val rectX = i * parentItemWidth + firstRectXval temp = iconRectList[i]temp.left = rectXtemp.top = iconToptemp.right = rectX + iconWidthtemp.bottom = iconTop + iconHeight}//標題for (i in 0 until itemCount) {val title = titleList[i]paint.getTextBounds(title, 0, title.length, rect)titleXList.add((parentItemWidth - rect.width()) / 2 + parentItemWidth * i)}}}private fun dp2px(dpValue: Float): Int {val scale = context.resources.displayMetrics.densityreturn (dpValue * scale + 0.5f).toInt()}override fun onDraw(canvas: Canvas) {super.onDraw(canvas)//這里讓view自身替我們畫背景 如果指定的話if (itemCount != 0) {//畫背景paint.isAntiAlias = falsefor (i in 0 until itemCount) {var bitmap: Bitmap? = nullbitmap = if (i == currentIndex) {iconBitmapAfterList[i]} else {iconBitmapBeforeList[i]}if (bitmap == null) continueval rect = iconRectList[i]canvas.drawBitmap(bitmap, null, rect, paint)//null代表bitmap全部畫出}//畫文字paint.isAntiAlias = truefor (i in 0 until itemCount) {val title = titleList[i]if (i == currentIndex) {paint.color = titleColorAfter} else {paint.color = titleColorBefore}val x = titleXList[i]canvas.drawText(title, x.toFloat(), titleBaseLine.toFloat(), paint)}}}@SuppressLint("ClickableViewAccessibility")override fun onTouchEvent(event: MotionEvent): Boolean {when (event.action) {MotionEvent.ACTION_DOWN -> target = withinWhichArea(event.x.toInt())MotionEvent.ACTION_UP -> {if (event.y >= 0 && target == withinWhichArea(event.x.toInt())) {listen(target)switchFragment(target)currentIndex = targetinvalidate()}target = -1}}return true}private fun withinWhichArea(x: Int): Int {return x / parentItemWidth}private fun switchFragment(whichFragment: Int) {val fragment = fragmentList[whichFragment]val frameLayoutId = containerIdif (fragment != null) {val transaction = (context as AppCompatActivity).supportFragmentManager.beginTransaction()if (fragment.isAdded) {if (currentFragment != null) {transaction.hide(currentFragment).show(fragment)} else {transaction.show(fragment)}} else {if (currentFragment != null) {transaction.hide(currentFragment).add(frameLayoutId, fragment)} else {transaction.add(frameLayoutId, fragment)}}currentFragment = fragmenttransaction.commitAllowingStateLoss()}} }

    用法

    private fun initBottomBar() {bottom_bar_activity_main.setContainer(R.id.fl_content_activity_main).setTitleSize(12).setIconHeight(22).setIconWidth(22).setTitleBeforeAndAfterColor("#666666","#ff0054").addItem(FragmentA::class.java, getString(R.string.menu_home), R.mipmap.tab_home_unselect, R.mipmap.tab_home_select).addItem(FragmentB::class.java, getString(R.string.menu_category), R.mipmap.tab_type_unselect, R.mipmap.tab_type_select).addItem(FragmentC::class.java, getString(R.string.menu_coupon), R.mipmap.tab_xd_unselect, R.mipmap.tab_xd_select).addItem(FragmentD::class.java, getString(R.string.menu_broke), R.mipmap.tab_circle_unselect, R.mipmap.tab_circle_select).addItem(FragmentE::class.java, getString(R.string.menu_me), R.mipmap.tab_mine_unselect, R.mipmap.tab_mine_select).build()bottom_bar_activity_main.setClickListen {//TODO 這里可以自己處理點擊事件的邏輯println(it)}}

    是不是用的很爽,這個Demo的地址我放到github了,歡迎star issue
    Demo地址 https://github.com/Liberations/BottomBarDemo

    總結

    以上是生活随笔為你收集整理的基于 Kotlin 一行代码实现 android 导航栏 BottomBar的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。