基于 Kotlin 一行代码实现 android 导航栏 BottomBar
生活随笔
收集整理的這篇文章主要介紹了
基于 Kotlin 一行代码实现 android 导航栏 BottomBar
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
主要功能點
看效果是否滿意
上代碼
直接先貼代碼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的參數(shù)進行賦值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
總結(jié)
以上是生活随笔為你收集整理的基于 Kotlin 一行代码实现 android 导航栏 BottomBar的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: DP PX转换
- 下一篇: “美积电”?“投名状”?台积电和英特尔达