diff --git a/app/src/main/java/com/iammert/readablebottombar/MainActivity.kt b/app/src/main/java/com/iammert/readablebottombar/MainActivity.kt index fc86df3..708ee42 100644 --- a/app/src/main/java/com/iammert/readablebottombar/MainActivity.kt +++ b/app/src/main/java/com/iammert/readablebottombar/MainActivity.kt @@ -1,12 +1,24 @@ package com.iammert.readablebottombar -import android.support.v7.app.AppCompatActivity +import android.graphics.Color import android.os.Bundle +import android.support.v7.app.AppCompatActivity +import com.iammert.library.readablebottombar.BottomBarItem +import com.iammert.library.readablebottombar.ReadableBottomBar class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) + + val bottomBar : ReadableBottomBar = findViewById(R.id.dynamic_bottom_bar) + //bottomBar.setTabItems(R.xml.tabs_disabled) + var items = ArrayList() + + items.add(BottomBarItem(0, 0, "Test", 15f, + Color.BLACK, Color.BLACK, getDrawable(R.drawable.ic_home_black_24dp), + ReadableBottomBar.ItemType.Icon)) + bottomBar.setTabItems(items) } } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 55095ec..cc87141 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -2,28 +2,29 @@ + app:rbb_tabs="@xml/tabs" /> + app:rbb_tabs="@xml/tabs" /> + app:rbb_tabs="@xml/tabs" /> \ No newline at end of file diff --git a/app/src/main/res/xml/tabs.xml b/app/src/main/res/xml/tabs.xml index 3771dae..b6f9ec7 100644 --- a/app/src/main/res/xml/tabs.xml +++ b/app/src/main/res/xml/tabs.xml @@ -1,6 +1,7 @@ diff --git a/app/src/main/res/xml/tabs_diabled.xml b/app/src/main/res/xml/tabs_diabled.xml new file mode 100644 index 0000000..38a0cb3 --- /dev/null +++ b/app/src/main/res/xml/tabs_diabled.xml @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/library/src/main/java/com/iammert/library/readablebottombar/BottomBarItem.kt b/library/src/main/java/com/iammert/library/readablebottombar/BottomBarItem.kt index 1e828fd..2b1c6a4 100644 --- a/library/src/main/java/com/iammert/library/readablebottombar/BottomBarItem.kt +++ b/library/src/main/java/com/iammert/library/readablebottombar/BottomBarItem.kt @@ -5,6 +5,7 @@ import android.support.annotation.ColorInt import com.iammert.library.readablebottombar.ReadableBottomBar.ItemType data class BottomBarItem( + val id: Int, val index: Int, val text: String, val textSize: Float, diff --git a/library/src/main/java/com/iammert/library/readablebottombar/BottomBarItemConfig.kt b/library/src/main/java/com/iammert/library/readablebottombar/BottomBarItemConfig.kt index 6106a72..f98190f 100644 --- a/library/src/main/java/com/iammert/library/readablebottombar/BottomBarItemConfig.kt +++ b/library/src/main/java/com/iammert/library/readablebottombar/BottomBarItemConfig.kt @@ -3,7 +3,8 @@ package com.iammert.library.readablebottombar import android.graphics.drawable.Drawable data class BottomBarItemConfig( - val text: String, - val drawable: Drawable, - val index: Int + val id: Int, + val text: String, + val drawable: Drawable, + val index: Int ) \ No newline at end of file diff --git a/library/src/main/java/com/iammert/library/readablebottombar/BottomBarItemView.kt b/library/src/main/java/com/iammert/library/readablebottombar/BottomBarItemView.kt index 5063a61..5d1c739 100644 --- a/library/src/main/java/com/iammert/library/readablebottombar/BottomBarItemView.kt +++ b/library/src/main/java/com/iammert/library/readablebottombar/BottomBarItemView.kt @@ -67,11 +67,15 @@ class BottomBarItemView @JvmOverloads constructor(context: Context, attrs: Attri } fun select() { - animatedView.startAnimation(translateUpAnimation) + translateUpAnimation?.let { + animatedView.startAnimation(it) + } } fun deselect() { - animatedView.startAnimation(translateDownAnimation) + translateDownAnimation?.let { + animatedView.startAnimation(it) + } } private fun initializeAnimations() { diff --git a/library/src/main/java/com/iammert/library/readablebottombar/ConfigurationXmlParser.kt b/library/src/main/java/com/iammert/library/readablebottombar/ConfigurationXmlParser.kt index 7db19ed..28600d4 100644 --- a/library/src/main/java/com/iammert/library/readablebottombar/ConfigurationXmlParser.kt +++ b/library/src/main/java/com/iammert/library/readablebottombar/ConfigurationXmlParser.kt @@ -32,13 +32,19 @@ class ConfigurationXmlParser(private val context: Context, xmlRes: Int) { val attributeCount = parser.attributeCount var itemText: String? = null var itemDrawable: Drawable? = null + var itemId: Int = -1 for (i in 0 until attributeCount) { when (parser.getAttributeName(i)) { + KEY_ID -> itemId = parser.getAttributeIntValue(i, -1) KEY_TEXT -> itemText = getText(parser, i) KEY_DRAWABLE -> itemDrawable = getDrawable(parser, i) } } - return BottomBarItemConfig(text = itemText!!, drawable = itemDrawable!!, index = itemConfigList.size) + return BottomBarItemConfig( + id = itemId, + text = itemText!!, + drawable = itemDrawable!!, + index = itemConfigList.size) } private fun getDrawable(parser: XmlResourceParser, i: Int): Drawable { @@ -50,6 +56,7 @@ class ConfigurationXmlParser(private val context: Context, xmlRes: Int) { } companion object { + const val KEY_ID: String = "id" const val KEY_TEXT: String = "text" const val KEY_DRAWABLE: String = "drawable" diff --git a/library/src/main/java/com/iammert/library/readablebottombar/ReadableBottomBar.kt b/library/src/main/java/com/iammert/library/readablebottombar/ReadableBottomBar.kt index 4f0ecd9..1226695 100644 --- a/library/src/main/java/com/iammert/library/readablebottombar/ReadableBottomBar.kt +++ b/library/src/main/java/com/iammert/library/readablebottombar/ReadableBottomBar.kt @@ -7,13 +7,12 @@ import android.util.AttributeSet import android.view.View import android.view.ViewTreeObserver import android.widget.LinearLayout -import java.lang.IllegalArgumentException class ReadableBottomBar @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : LinearLayout(context, attrs, defStyleAttr) { interface ItemSelectListener { - fun onItemSelected(index: Int) + fun onItemSelected(index: Int, id: Int) } enum class ItemType(val value: Int) { @@ -27,13 +26,18 @@ class ReadableBottomBar @JvmOverloads constructor(context: Context, attrs: Attri } } - private val bottomBarItemList: List + private var bottomBarItemList: List private var tabInitialSelectedIndex = 0 private var tabBackgroundColor: Int = Color.WHITE private var tabIndicatorColor: Int = Color.BLACK private var tabIndicatorHeight: Int = 10 + private var textSize: Float = 15f + private var textColor: Int = Color.BLACK + private var iconColor: Int = Color.BLACK + private var activeItemType: ItemType = ItemType.Icon + private var layoutWidth: Float = 0f private var layoutHeight: Float = 0f @@ -46,11 +50,13 @@ class ReadableBottomBar @JvmOverloads constructor(context: Context, attrs: Attri private var itemSelectListener: ItemSelectListener? = null + private var pendingSelectable: Int? = null + private var indicatorAnimator: ValueAnimator? = ValueAnimator.ofFloat(0f, 0f).apply { duration = ANIMATION_DURATION addUpdateListener { animation -> val marginLeft = animation.animatedValue as Float - val marginParam: LinearLayout.LayoutParams = indicatorView?.layoutParams as LayoutParams + val marginParam: LayoutParams = indicatorView?.layoutParams as LayoutParams marginParam.setMargins(marginLeft.toInt(), marginParam.topMargin, marginParam.rightMargin, marginParam.bottomMargin) indicatorView?.layoutParams = marginParam } @@ -64,10 +70,10 @@ class ReadableBottomBar @JvmOverloads constructor(context: Context, attrs: Attri tabIndicatorHeight = typedArray.getDimensionPixelSize(R.styleable.ReadableBottomBar_rbb_indicatorHeight, 10) tabInitialSelectedIndex = typedArray.getInt(R.styleable.ReadableBottomBar_rbb_initialIndex, 0) - val textSize = typedArray.getDimension(R.styleable.ReadableBottomBar_rbb_textSize, 15f) - val textColor = typedArray.getColor(R.styleable.ReadableBottomBar_rbb_textColor, Color.BLACK) - val iconColor = typedArray.getColor(R.styleable.ReadableBottomBar_rbb_iconColor, Color.BLACK) - val activeItemType = ItemType.getType(typedArray.getInt(R.styleable.ReadableBottomBar_rbb_activeItemType, ItemType.Icon.value)) + textSize = typedArray.getDimension(R.styleable.ReadableBottomBar_rbb_textSize, 15f) + textColor = typedArray.getColor(R.styleable.ReadableBottomBar_rbb_textColor, Color.BLACK) + iconColor = typedArray.getColor(R.styleable.ReadableBottomBar_rbb_iconColor, Color.BLACK) + activeItemType = ItemType.getType(typedArray.getInt(R.styleable.ReadableBottomBar_rbb_activeItemType, ItemType.Icon.value)) val tabXmlResource = typedArray?.getResourceId(R.styleable.ReadableBottomBar_rbb_tabs, 0) val bottomBarItemConfigList = ConfigurationXmlParser(context = context, xmlRes = tabXmlResource!!).parse() @@ -77,6 +83,7 @@ class ReadableBottomBar @JvmOverloads constructor(context: Context, attrs: Attri bottomBarItemList = bottomBarItemConfigList.map { config -> BottomBarItem( + config.id, config.index, config.text, textSize, @@ -114,26 +121,31 @@ class ReadableBottomBar @JvmOverloads constructor(context: Context, attrs: Attri } val item = bottomBarItemList[index] - for (i in 0 until childCount) { - if (TAG_CONTAINER == getChildAt(i).tag) { - val selectedItemView = ((getChildAt(i) as LinearLayout).getChildAt(index) as BottomBarItemView) - if (selectedItemView != currentSelectedView) { - onSelected(item.index, selectedItemView) + if (childCount > 0) { + for (i in 0 until childCount) { + if (TAG_CONTAINER == getChildAt(i).tag) { + val selectedItemView = ((getChildAt(i) as LinearLayout).getChildAt(index) as BottomBarItemView) + if (selectedItemView != currentSelectedView) { + onSelected(item.id, item.index, selectedItemView) + } } } + } else { + pendingSelectable = index } } + private fun drawBottomBarItems() { val itemContainerLayout = LinearLayout(context).apply { - layoutParams = LinearLayout.LayoutParams(layoutWidth.toInt(), layoutHeight.toInt()) + layoutParams = LayoutParams(layoutWidth.toInt(), layoutHeight.toInt()) orientation = HORIZONTAL tag = TAG_CONTAINER } bottomBarItemList.forEach { item -> val bottomBarItem = BottomBarItemView(context).apply { - layoutParams = LinearLayout.LayoutParams(itemWidth.toInt(), itemHeight.toInt() - tabIndicatorHeight) + layoutParams = LayoutParams(itemWidth.toInt(), itemHeight.toInt() - tabIndicatorHeight) setText(item.text) setItemType(item.type) @@ -149,7 +161,7 @@ class ReadableBottomBar @JvmOverloads constructor(context: Context, attrs: Attri return@setOnClickListener } - onSelected(item.index, this) + onSelected(item.id, item.index, this) } } @@ -163,8 +175,12 @@ class ReadableBottomBar @JvmOverloads constructor(context: Context, attrs: Attri override fun onGlobalLayout() { bottomBarItem.select() bottomBarItem.viewTreeObserver.removeGlobalOnLayoutListener(this) - } + pendingSelectable?.let { + selectItem(it) + pendingSelectable = null + } + } } bottomBarItem.viewTreeObserver.addOnGlobalLayoutListener(listener) @@ -177,7 +193,7 @@ class ReadableBottomBar @JvmOverloads constructor(context: Context, attrs: Attri private fun drawIndicator() { indicatorView = View(context).apply { - val indicatorLayoutParams = LinearLayout.LayoutParams(itemWidth.toInt(), tabIndicatorHeight) + val indicatorLayoutParams = LayoutParams(itemWidth.toInt(), tabIndicatorHeight) indicatorLayoutParams.setMargins((tabInitialSelectedIndex * itemWidth).toInt(), 0, 0, 0) layoutParams = indicatorLayoutParams setBackgroundColor(tabIndicatorColor) @@ -186,22 +202,32 @@ class ReadableBottomBar @JvmOverloads constructor(context: Context, attrs: Attri } private fun animateIndicator(currentItemIndex: Int) { - val previousMargin: Float = (indicatorView?.layoutParams as? LinearLayout.LayoutParams)?.leftMargin?.toFloat() + val previousMargin: Float = (indicatorView?.layoutParams as? LayoutParams)?.leftMargin?.toFloat() ?: 0F val currentMargin: Float = currentItemIndex * itemWidth indicatorAnimator?.setFloatValues(previousMargin, currentMargin) indicatorAnimator?.start() } - private fun onSelected(index: Int, bottomBarItemView: BottomBarItemView) { + private fun onSelected(id: Int, index: Int, bottomBarItemView: BottomBarItemView) { animateIndicator(index) currentSelectedView?.deselect() currentSelectedView = bottomBarItemView currentSelectedView?.select() - itemSelectListener?.onItemSelected(index) + itemSelectListener?.onItemSelected(index, id) + } + + + public fun setTabItems(items: List) { + bottomBarItemList = items + post { + drawIndicator() + drawBottomBarItems() + } } + companion object { const val ANIMATION_DURATION = 300L