demand
Implement the following UI effect with an indicator width of 10dp, height of 4DP, and rounded corners of 2DP
Common practices are as follows:
-
Define the indicator tab_indicator.xml
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:width="10dp" android:height="4dp" android:gravity="center"> <shape> <corners android:radius="2dp" /> </shape> </item> </layer-list> Copy the code
-
Define TabLayout and set app:tabIndicator=”@drawable/tab_indicator”
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="wrap_content"
android:layout_height="45dp"
android:layout_gravity="center"
app:tabIndicator="@drawable/tab_indicator"
app:tabIndicatorColor="#3F51B5"
app:tabIndicatorFullWidth="false"
app:tabIndicatorHeight="4dp"
app:tabMode="scrollable"
app:tabRippleColor="@android:color/transparent"
app:tabSelectedTextColor="# 333333"
app:tabTextColor="# 999999" />
Copy the code
The display effect on Android 6.0 and above is as follows:
It looks like this on an Android 5.1 machine:
On Android 5.1, the width of the indicator is the same as the width of the text, rather than the 10DP we wanted
Troubleshoot problems
Android :width/height under the layer-list in the XML file does not work under Android 6.0. When we place the cursor in the tab_indicator. Attribute width is only used in API level 23 and higher (current min is 21)
The solution
Dynamically set the indicator width in the code and add a TabLayout extension method as follows:
/** * sets the indicator to a fixed width */
fun TabLayout.setSelectedTabIndicatorFixWidth(width: Float) {
setSelectedTabIndicator(object : DrawableWrapper(tabSelectedIndicator) {
override fun setBounds(left: Int, top: Int, right: Int, bottom: Int) {
var realLeft = left
var realRight = right
if((right - left).toFloat() ! = width) {val center = left + (right - left).toFloat() / 2
realLeft = (center - width / 2).toInt()
realRight = (center + width / 2).toInt()
}
super.setBounds(realLeft, top, realRight, bottom)
}
})
}
Copy the code
use
tab_indicator.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="2dp" />
</shape>
Copy the code
Layout file
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="wrap_content"
android:layout_height="45dp"
android:layout_gravity="center"
app:tabIndicator="@drawable/tab_indicator"
app:tabIndicatorColor="#3F51B5"
app:tabIndicatorFullWidth="false"
app:tabIndicatorHeight="4dp"
app:tabMode="scrollable"
app:tabRippleColor="@android:color/transparent"
app:tabSelectedTextColor="# 333333"
app:tabTextColor="# 999999" />
Copy the code
tabLayout.setSelectedTabIndicatorFixWidth(dp2px(10f))
Copy the code
The effect
- Android 5.0 & 5.1
- The Android 6.0 +
reference
TabLayout a line of code with a fixed width