How to change the new TabLayout indicator color and height
Having the problem that the new TabLayout uses the indicator color from the value colorAccent
, I decided to dig into the android.support.design.widget.TabLayout
implementation, finding that there are no public methods to customize this. However I found this style specification of the TabLayout:
<style name="Base.Widget.Design.TabLayout" parent="android:Widget">
<item name="tabMaxWidth">@dimen/tab_max_width</item>
<item name="tabIndicatorColor">?attr/colorAccent</item>
<item name="tabIndicatorHeight">2dp</item>
<item name="tabPaddingStart">12dp</item>
<item name="tabPaddingEnd">12dp</item>
<item name="tabBackground">?attr/selectableItemBackground</item>
<item name="tabTextAppearance">@style/TextAppearance.Design.Tab</item>
<item name="tabSelectedTextColor">?android:textColorPrimary</item>
</style>
Having this style specification, now we can customize the TabLayout like this:
<android.support.design.widget.TabLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@id/pages_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:tabIndicatorColor="@android:color/white"
app:tabIndicatorHeight="4dp"/>
And problem solved, both the tab indicator color and height can be changed from their default values.
How to change Tab Indicator color programmatically
I use Jeff Gilfelt,s Android Action Bar Style Generator. You can use GUI to style your tabs and at the end you get the source code which you can use, review and modify accordingly. :)
Here's a link.
http://jgilfelt.github.io/android-actionbarstylegenerator/#name=example&compat=holo&theme=light&actionbarstyle=solid&texture=0&hairline=0&neutralPressed=1&backColor=E4E4E4%2C100&secondaryColor=D6D6D6%2C100&tabColor=33B5E5%2C100&tertiaryColor=F2F2F2%2C100&accentColor=33B5E5%2C100&cabBackColor=FFFFFF%2C100&cabHighlightColor=33B5E5%2C100
change the selected tab indicator color of TabLayout(android.support.design.widget)
I can't comment so I'll add it here.
Update the Design Support Library and you'll see the setSelectedTabIndicatorColor()
method.
This is the line in my build.gradle
:
compile 'com.android.support:design:23.1.0'
Android Tab layout: Wrap tab indicator width with respect to tab title
Yes, it's possible to wrap tab indicator as title setting padding to 0
public void wrapTabIndicatorToTitle(TabLayout tabLayout, int externalMargin, int internalMargin) {
View tabStrip = tabLayout.getChildAt(0);
if (tabStrip instanceof ViewGroup) {
ViewGroup tabStripGroup = (ViewGroup) tabStrip;
int childCount = ((ViewGroup) tabStrip).getChildCount();
for (int i = 0; i < childCount; i++) {
View tabView = tabStripGroup.getChildAt(i);
//set minimum width to 0 for instead for small texts, indicator is not wrapped as expected
tabView.setMinimumWidth(0);
// set padding to 0 for wrapping indicator as title
tabView.setPadding(0, tabView.getPaddingTop(), 0, tabView.getPaddingBottom());
// setting custom margin between tabs
if (tabView.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) tabView.getLayoutParams();
if (i == 0) {
// left
settingMargin(layoutParams, externalMargin, internalMargin);
} else if (i == childCount - 1) {
// right
settingMargin(layoutParams, internalMargin, externalMargin);
} else {
// internal
settingMargin(layoutParams, internalMargin, internalMargin);
}
}
}
tabLayout.requestLayout();
}
}
private void settingMargin(ViewGroup.MarginLayoutParams layoutParams, int start, int end) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
layoutParams.setMarginStart(start);
layoutParams.setMarginEnd(end);
layoutParams.leftMargin = start;
layoutParams.rightMargin = end;
} else {
layoutParams.leftMargin = start;
layoutParams.rightMargin = end;
}
}
EDIT:
As of com.android.support:design:28.0.0
, you can adjust the indicator as label easily now setting:
app:tabIndicatorFullWidth="false"
EDIT July 2019:
Use the material dependencycom.google.android.material:material:x.x.x
Changing tab indicator background (for all the tablayout view)
To achieve what you are looking for you can try the following
Create a selector tab_layout_selector
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="false" android:state_pressed="false">
<layer-list>
<!-- Stripe bottom indicator color -->
<item android:top="-5dp" android:left="-5dp" android:right="-5dp">
<shape android:shape="rectangle">
<stroke android:color="@color/red" android:width="4dp"/>
</shape>
</item>
</layer-list>
</item>
</selector>
Finally, in your TabLayout add
<android.support.design.widget.TabLayout
<!-- Whole tab background -->
android:background="@color/white"
<!-- Line color -->
android:tabBackground="@drawable/tab_layout_selector"
.... Others....
/>
Android TabLayout custom indicator width
Try this.
public void setIndicator (TabLayout tabs,int leftDip,int rightDip){
Class<?> tabLayout = tabs.getClass();
Field tabStrip = null;
try {
tabStrip = tabLayout.getDeclaredField("mTabStrip");
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
tabStrip.setAccessible(true);
LinearLayout llTab = null;
try {
llTab = (LinearLayout) tabStrip.get(tabs);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
int left = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, leftDip, Resources.getSystem().getDisplayMetrics());
int right = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, rightDip, Resources.getSystem().getDisplayMetrics());
for (int i = 0; i < llTab.getChildCount(); i++) {
View child = llTab.getChildAt(i);
child.setPadding(0, 0, 0, 0);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1);
params.leftMargin = left;
params.rightMargin = right;
child.setLayoutParams(params);
child.invalidate();
}
}
And then
tab.post(new Runnable() {
@Override
public void run() {
setIndicator(tab,60,60);
}
});
My modification w/o reflection (custom view should be set!).
for (int i = 0; i < tabs.getTabCount(); i++) {
TabLayout.Tab tab = tabs.getTabAt(i);
if (tab != null) {
View customView = tab.getCustomView();
if (customView != null) {
View targetViewToApplyMargin = (View) customView.getParent();
ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) targetViewToApplyMargin.getLayoutParams();
layoutParams.rightMargin = totalTabMargin;
targetViewToApplyMargin.setLayoutParams(layoutParams);
}
}
}
Related Topics
Android Listview Using Viewholder
How to Store a Boolean Value Using Sharedpreferences in Android
How to View the Shared Preferences File Using Android Studio
Add Floating Point Value to Android Resources/Values
How to Simulate Android Killing My Process
Controlling the Camera to Take Pictures in Portrait Doesn't Rotate the Final Images
How to Share a Single Library Source Across Multiple Projects
Permission Denial: Startforeground Requires Android.Permission.Foreground_Service
How to Get Response as String Using Retrofit Without Using Gson or Any Other Library in Android
Getresources().Getcolor() Is Deprecated
How to Use Tools:Overridelibrary in a Build.Gradle File
Why Is Eclipse's Android Device Chooser Not Showing My Android Device
Adding Ripple Effect to Recyclerview Item
Send Post Request Along with Httpheaders on Android
Android Viewmodel Additional Arguments