日韩性视频-久久久蜜桃-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的全部內容,希望文章能夠幫你解決所遇到的問題。

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

    主站蜘蛛池模板: 美女视频一区二区 | 91一区二区三区在线 | 亚洲乱码精品 | 亚洲最新网址 | 五色天婷婷 | 亚洲色图另类图片 | 天堂在线中文网 | 欧美一级片黄色 | 国内毛片毛片毛片毛片毛片 | 国产又大又黄的视频 | 午夜在线视频免费观看 | 亚洲综合日韩精品欧美综合区 | 99免费在线观看视频 | 老汉av网站 | 亚洲第一色区 | 亚洲午夜在线播放 | 亚洲成人动漫在线观看 | 亚洲无限码 | 伊人免费视频 | 实拍澡堂美女洗澡av | 国产中文字幕免费 | 亚洲精品国产精品国自产在线 | 亚洲精品一区二区三区在线观看 | 男人深夜影院 | 午夜精品久久久久久久99老熟妇 | 在线视频第一页 | 成人免费在线观看网站 | 色婷婷狠狠18禁久久 | 国产日韩成人内射视频 | 免费中文字幕日韩 | 嫩草国产精品 | youjizz.com在线观看 | 艹男人的日日夜夜 | 国产精品女人精品久久久天天 | 欧美黑人一区二区三区 | 久久久国产精品一区二区三区 | 91大神在线免费观看 | av在线播放一区二区三区 | 日本不卡中文字幕 | 特级丰满少妇一级aaaa爱毛片 | 欧美精品激情 | 国产免费自拍 | 成人看| 黄色国产一级片 | 久久理论电影 | 色播导航 | 性爽爽| 欧美色综合 | 亚洲综合丁香 | 欧美性生活一区二区三区 | youjizz.com中国 | 另类激情亚洲 | 国产精品99久久久久久动医院 | 爱情岛论语亚洲入口 | 亚洲最大福利网站 | 国产伦精品一区二区三区视频孕妇 | 亚洲激情网 | 亚洲精品成人无码熟妇在线 | 99久久影院 | 亚洲精品视频一区二区三区 | 福利在线播放 | 国产又粗又猛又黄又爽视频 | 日韩第九页 | 久久全国免费视频 | 亚洲熟女乱色一区二区三区 | 日韩中文字幕在线免费观看 | 色婷婷视频在线 | 日韩欧美成人一区二区三区 | 亚洲午夜在线播放 | 神马久久影院 | 在线观看国产小视频 | 色狠狠一区 | 四虎色| 亚洲第一免费网站 | 欧美二区在线 | 国产精品99久久久久久动医院 | 特大黑人巨交吊性xx | 青青草国产成人99久久 | 看黄色的网站 | 日本熟妇色xxxxx日本免费看 | 538在线精品视频 | 动漫同人高h啪啪爽文 | 亚洲精品在线播放视频 | 欧美少妇一级片 | 天天干天天色天天 | 久久这里只有精品99 | 欧美特黄aaaaaa | 开心色站 | www.日韩高清 | 9人人澡人人爽人人精品 | 日韩69| av自拍偷拍| av女人的天堂 | 激情91视频 | 国产乱码精品一区二区三区忘忧草 | 好男人网站 | 日本免费一级片 | 中文字幕有码av | 亚洲涩情 |