android:textAllCaps="false" not working for TabLayout design Support - android

I have set android:textAllCaps="false" in my android.support.design.widget.TabLayout thought it is showing the Tab Title in All caps only.
How can I remove all caps?

UPDATE FOR DESIGN LIBRARY 23.2.0+
The original answer doesn't work with design library 23.2.0 or later. Thanks for #fahmad6 pointed out in comment, in case someone missed that comment, I'll put it here. You need to set both textAllCaps and android:textAllCaps to false to disable all capitalize setting.
<style name="MyCustomTextAppearance" parent="TextAppearance.Design.Tab">
<item name="textAllCaps">false</item>
<item name="android:textAllCaps">false</item>
</style>
ORIGINAL ANSWER
By default, tabs are created by TabLayout sets the textAllCaps property to be true, you have to define a style making this flag false.
<style name="MyCustomTabLayout" parent="Widget.Design.TabLayout">
<item name="tabTextAppearance">#style/MyCustomTextAppearance</item>
</style>
<style name="MyCustomTextAppearance" parent="TextAppearance.Design.Tab">
<item name="textAllCaps">false</item>
</style>

#Paresh Mayani answer is correct however you can create only tab style
<style name="MyCustomTextAppearance" parent="TextAppearance.Design.Tab">
<item name="textAllCaps">false</item>
</style>
And use it using
<android.support.design.widget.TabLayout
app:tabTextAppearance="#style/MyCustomTextAppearance"
.../>

use this attribute app:tabTextAppearance="#android:style/TextAppearance.Widget.TabWidget"
It will work.
<android.support.design.widget.TabLayout
android:id="#+id/tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
app:tabGravity="fill"
app:tabTextAppearance="#android:style/TextAppearance.Widget.TabWidget"
app:tabIndicatorColor="#color/colorPrimary"
app:tabMode="fixed"
app:tabPaddingStart="0dp" />

https://stackoverflow.com/a/34678235/1025379
<android.support.design.widget.TabLayout
app:tabTextAppearance="#android:style/TextAppearance.Widget.TabWidget"
/>

In my case two variants work:
1) By Bogdan (susemi99):
<android.support.design.widget.TabLayout
app:tabTextAppearance="#android:style/TextAppearance.Widget.TabWidget"
/>
2) By Paresh Mayani. I wanted to have android:textAllCaps="false" and android:textSize="15sp" simultaneously, so his old method works.
In styles.xml write (parent may vary, for instance, "#android:style/TextAppearance.Widget.TabWidget", "TextAppearance.Design.Tab"):
<style name="TabLayout" parent="Widget.Design.TabLayout">
<item name="tabIndicatorColor">#color/color_blue</item>
<item name="tabSelectedTextColor">#color/color_blue</item>
<item name="tabTextColor">#color/black</item>
<item name="tabTextAppearance">#style/TabLayoutTextAppearance</item>
</style>
<style name="TabLayoutTextAppearance" parent="TextAppearance.Design.Tab">
<item name="android:textSize">15sp</item>
<item name="textAllCaps">false</item>
<item name="android:textAllCaps">false</item>
</style>
Apply this style in layout:
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="#style/TabLayout"
/>

For those who can't get working other answers.
Defining a style is working fine when you have single line tab text.
If you take a close look into the TabLayout, you'll see that it's using a field design_tab_text_size_2line when the tabs has more than one line.
The only way I could find to effect this field is to override it in your dimen file.
So put this in your values/dimens.xml
<dimen name="design_tab_text_size_2line" tools:override="true">10sp</dimen>
Hope it helps.

This works for me in just one line
<android.support.design.widget.TabLayout
app:tabTextAppearance="#android:style/TextAppearance.Widget.TabWidget"/>

Here is simple solution....Enjoy
for (int tabIndex = 0; tabIndex <tabLayout.getTabCount() ; tabIndex++) {
TextView tabTextView = (TextView)(((LinearLayout)((LinearLayout)tabLayout.getChildAt(0)).getChildAt(tabIndex)).getChildAt(1));
tabTextView.setAllCaps(false);
}

Change: <item name="android:textAllCaps">false</item>
With: <item name="textAllCaps">false</item>

This Worked For Me...
<style name="TabLayoutStyle" parent="Widget.Design.TabLayout">
<item name="tabTextAppearance">#style/TabTextAppearance</item>
</style>
<style name="TabTextAppearance" parent="TextAppearance.Design.Tab">
<item name="textAllCaps">false</item>
</style>

In versions priror to 14, you need to set (as commented by Paresh Mayani):
<style name="MyCustomTabLayout" parent="Widget.Design.TabLayout">
<item name="tabTextAppearance">#style/MyCustomTextAppearance</item>
</style>
<style name="MyCustomTextAppearance" parent="TextAppearance.Design.Tab">
<item name="textAllCaps">false</item>
</style>
But, in case of android version is equal or greater than 14, you need to set:
<item name="android:textAllCaps">false</item>
So, if you need to be compatible with versions before and after 14, you also need to create a folder values-v14, and a file styles.xml in that folder with the content:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
<style name="MyCustomTextAppearance" parent="TextAppearance.Design.Tab">
<item name="android:textAllCaps">false</item>
</style>
</resources>

Try following method and you can implement all the methods of TextView in TabLayout
private void setCustomTab() {
ViewGroup vg = (ViewGroup) mTabLayout.getChildAt(0);
int tabsCount = vg.getChildCount();
for (int j = 0; j < tabsCount; j++) {
ViewGroup vgTab = (ViewGroup) vg.getChildAt(j);
int tabChildsCount = vgTab.getChildCount();
for (int i = 0; i < tabChildsCount; i++) {
View tabViewChild = vgTab.getChildAt(i);
if (tabViewChild instanceof TextView) {
((TextView) tabViewChild).setTypeface(ResourcesCompat.getFont(this,R.font.montserrat_medium));
((TextView) tabViewChild).setAllCaps(false);
}
}
}
}
Hope it helps.

Here the Simple solution to Avoid Capitalize and change font size , font family on TabLayout design in Android 100% Working
Add following style on res/values/stye.xml
<style name="MyCustomTextAppearance" parent="TextAppearance.Design.Tab">
<item name="textAllCaps">false</item>
<item name="android:textSize">16sp</item>
<item name="android:fontFamily">#font/poppins_semi_bold</item>
</style>
Call this style in your tab layout as app:tabTextAppearance="#style/MyCustomTextAppearance"
<com.google.android.material.tabs.TabLayout
android:id="#+id/tab_tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabIndicatorColor="#FFF"
app:tabTextAppearance="#style/MyCustomTextAppearance"
app:tabIndicatorHeight="3dp"
android:layout_marginBottom="#dimen/_5sdp"
app:tabSelectedTextColor="#color/text_app_color"
app:tabTextColor="#color/text_app_color_1"
app:tabMode="auto" />
</com.google.android.material.appbar.AppBarLayout>

You can also do this in your Java code. If you are using a SlidingTabLayout look at this sample:
protected TextView createDefaultTabView(Context context){
TextView textView = new TextView(context);
textView.setGravity(Gravity.CENTER);
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP);//see line 38 above change the value their in TAB_VIEW_TEXT_SIZE_SP.
textView.setTypeface(Typeface.DEFAULT);//From DEFAULT_BOLD
textView.setTextColor(Color.parseColor("#536DFE"));//Text color of the words in the tabs. Indigo A200
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
// If we're running on Honeycomb or newer, then we can use the Theme's
// selectableItemBackground to ensure that the View has a pressed state
TypedValue outValue = new TypedValue();
getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground, outValue, true);
textView.setBackgroundResource(outValue.resourceId);
}
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH){
// If we're running on ICS or newer, enable all-caps to match the Action Bar tab style
textView.setAllCaps(true);
}
int padding = (int)(TAB_VIEW_PADDING_DIPS * getResources().getDisplayMetrics().density);
textView.setPadding(padding, padding, padding, padding);
return textView;
}
Notice that textView.setAllCaps() has true as the perimeter:
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH){
// If we're running on ICS or newer, enable all-caps to match the Action Bar tab style
textView.setAllCaps(true);
}
When I changed this to (false) it solved the problem for me:
textView.setAllCaps(false);
Also my string resource file that I use for the tabs looks like this:
<string name="tab_title">Title with capital and smaller case</string>
However if it had all caps like >TITLE WITH ALL CAPS< you would still of course get all caps in your tabs.
I made no other changes.
It is noteworthy that you can set textView.setAllCaps(false) too, but this made no difference in my case. I just commented out textView.setAllCaps(true).

Changing attributes in XML file doesn't work in Android 11 (SDK 30). Here is code that I use to setup tabs individually using a tab label. It's safer than setting new styles for all text fields in the tabs or relying on the existing tab layout, because the current tab design can be changed by Android. This method assumes that a tab text has been set before the function below is called. Second parameter in the call, txt is a tab label.
private fun setTabStyle(tabs: TabLayout, txt: String) {
val av = ArrayList<View?>()
tabs.findViewsWithText(av, txt, View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION )
if (av.count() > 0) {
val avt = ArrayList<View?>()
(av[0] as? ViewGroup)?.let {
for ( i in 0 until it.childCount) {
val tv = it.getChildAt(i) as? TextView
tv?.let {t ->
if (tv.text == txt) {
t.isAllCaps = false
t.setTextSize(TypedValue.COMPLEX_UNIT_SP, 11.toFloat())
}
}
}
}
}
}

Long story short (programmatically)...
/**
* #param view Target TabLayout view
* #param caps Present the text caps style
*/
public static void setAllCaps(View view, boolean caps) {
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++)
setAllCaps(((ViewGroup) view).getChildAt(i),caps);
} else if (view instanceof TextView) ((TextView) view).setAllCaps(caps);
}
Call setAllCaps like this :
tabLayout.addTab(tabLayout.newTab().setText("Recent"));
tabLayout.addTab(tabLayout.newTab().setText("New"));
setAllCaps(tabLayout,false);

It'll work if you only add one of these calls.
app:tabTextAppearance="#android:style/TextAppearance.Widget.TabWidget"
app:tabTextAppearance="#style/TextAppearance.AppCompat.Medium"
app:tabTextAppearance="#style/TextAppearance.AppCompat.Small"

Just add this to your custom style file
<item name="android:textStyle">normal</item>
I read all the above solutions and all lead to this.

Related

Change Chip Widget style programmatically not working - Android

I'm doing a list with Chips. I want this chips can be selected, so, taking a look to https://material.io/develop/android/components/chip/ I see I can have a "Choice Chip".
As I need to create and add dynamically I have to configure with specific colors, color ripplem, ...
So what I have to configure it is:
val chip = Chip(context, null, R.style.CustomChipChoice)
chip.isClickable = true
chip.isCheckable = true
chip.isCheckedIconVisible=false
chip.height = ScreenUtils.dpToPx(40)
chip.chipCornerRadius = (ScreenUtils.dpToPx(20)).toFloat()
chip.chipStrokeWidth = (ScreenUtils.dpToPx(2)).toFloat()
chip.setTextAppearanceResource(R.style.ChipTextStyle)
return chip
What I try with R.style.CustomChipChoice is:
CustomChipChoice style
<style name="CustomChipChoice" parent="#style/Widget.MaterialComponents.Chip.Choice">
<item name="chipBackgroundColor">#color/background_color_chip_state_list</item>
<item name="chipStrokeColor">#color/background_color_chip_state_list</item>
<item name="rippleColor">#color/topic_social_pressed</item>
</style>
background_color_chip_state_list
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/topic_social_selected" android:state_checked="true" />
<item android:color="#color/topic_social_pressed" android:state_pressed="true" />
<item android:color="#color/topic_unselected_background" />
</selector>
stroke_color_chip_state_list
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/topic_social_pressed" android:state_checked="true"/>
<item android:color="#color/grey_material2" android:state_checked="false"/>
</selector>
As you can see, I make the chip, clickable and checkable (hiding the check icon I don't need).
But when I test it, the colors are not set. The chips just look as default colors (grey's scale)
Where can I apply or how, this custom style?
P.S:
I have done a fast test, to see if my CustomStyle was malformed/etc..
I added a view via xml and worked perfectly...
<android.support.design.chip.Chip
android:id="#+id/test"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/CustomChipChoice"
android:checkable="true"
android:clickable="true"
app:checkedIconVisible="false"
android:text="Chip Test"/>
You can't use the constructor val chip = Chip(context, null, R.style.CustomChipChoice) because the 3rd parameter isn't the style but the attribute in the theme as R.attr.chipStyle.
The Chip hasn't a constructor with 4 parameters as other components because it extends AppCompatCheckbox which does not support a 4 parameter constructor.
However you can use something different.
1st option:
Just use a xml layout (single_chip_layout.xml) to define the single Chip with your favorite style:
<com.google.android.material.chip.Chip
xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/CustomChipChoice"
...
/>
with
<style name="CustomChipChoice" parent="#style/Widget.MaterialComponents.Chip.Choice">
...
</style>
Then instead of val chip = Chip(context, null, R.style.CustomChipChoice) use:
val chip = layoutInflater.inflate(R.layout.single_chip_layout, chipGroup, false) as Chip
In java:
Chip chip =
(Chip) getLayoutInflater().inflate(R.layout.single_chip_layout, chipGroup, false);
2nd option:
Another option is to use the setChipDrawable method to override the ChipDrawable inside the Chip:
Chip chip = new Chip(this);
ChipDrawable chipDrawable = ChipDrawable.createFromAttributes(this,
null,
0,
R.style.Widget_MaterialComponents_Chip_Choice);
chip.setChipDrawable(chipDrawable);
In order to set the chip style in code you can try the following:
val chip = Chip(context)
val drawable = ChipDrawable.createFromAttributes(context, null, 0, R.style.Widget_MaterialComponents_Chip_Choice)
chip.setChipDrawable(drawable)
the CustomChipChoice is not a style it is just a reference to a style. therefore change R.style.CustomChipChoice to it : R.attr.CustomChipChoice
val newChip = Chip(context, null, R.attr.CustomChipChoice)
but before it you should add this CustomChipChoicein values.xml file in your project.
for this. if your project does not have the values.xml create it in values directory.
then add CustomChipChoice like this.
values.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="CustomChipChoice" format="reference" />
</resources>
now in styles.xml add your style like this.
styles.xml
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
.
.
<item name="CustomChipChoice">#style/CustomChipChoiceStyle</item>
.
.
</style>
now that CustomChipChoice attr references to this style
and now you can create your custom style in styles.xml file.
styles.xml
<style name="CustomChipChoiceStyle" parent="#style/Widget.MaterialComponents.Chip.Action">
.
<item name="checkedIconVisible">false</item>
<item name="android:focusable">true</item>
<item name="android:clickable">true</item>
<item name="chipBackgroundColor">#color/colorWhite</item>
<item name="chipIcon">#drawable/ic_filter</item>
<item name="chipIconVisible">true</item>
<item name="textStartPadding">0dp</item>
<item name="textEndPadding">0dp</item>
.
.
<item name="android:textAppearance">#style/ChipTextStyleAppearance</item>
</style>
if you want to change text appearance of chip. here is ChipTextStyleAppearance. you can add it like this.
styles.xml
<style name="ChipTextStyleAppearance">
<item name="android:fontFamily">#font/main_font</item>
<item name="android:textSize">13dp</item>
<item name="android:textColor">#ffffff</item>
</style>
dont forget to add the AppTheme in androidManifest.xml on application or activity tags.
androidManifest.xml
<application
.
.
android:theme="#style/AppTheme">
<activity
.
.
android:theme="#style/AppTheme" />
There's another very simple approach to this.
styles.xml
<style name="Widget.MyApp.Chip" parent="Widget.MaterialComponents.Chip.Choice">
<item name="android:textAppearance">#style/TextAppearance.MyApp.Chip</item>
<item name="chipIconTint">?attr/colorPrimary</item>
</style>
theme.xml
<style name="Theme.MyApp.MyTheme" parent="Base.Theme.MyApp">
<item name="chipStyle">#style/Widget.MyApp.Chip</item>
</style>
With this, all chips in activities that have the theme Theme.MyApp.MyActivity applied to it will follow this custom style whether the chip has been added through xml or programmatically.
Kotlin
xml
<com.google.android.material.chip.ChipGroup
android:id="#+id/chipGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
</com.google.android.material.chip.ChipGroup>
Class
data class Parametro(
var idParametro: Long,
var nombreParametro: String? )
Main
listParametro.forEach { it->
val chip = Chip(context)
chip.id= it.idParametro.toInt()
chip.text= it.nombreParametro
chip.isClickable = true
chip.isCheckable = true
chip.setOnCheckedChangeListener { buttonView, isChecked ->
Log.i("checkedChipIds","${buttonView.id} $isChecked")
}
mBinding.chipGroup.addView(chip)
}
it works for me :)

Android Tab Layout not taking up full width with custom view

Android TabLayout tabPaddingTop and tabPaddingBottom not being removed
Please refer to the above issue as well.
Even since i updated my design library to "23.2.0", Tab layout is all messed up.
The below image is my Tab Layout.
Xml Part :-
<android.support.design.widget.TabLayout
android:id="#+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabIndicatorColor="#android:color/white"
app:tabIndicatorHeight="#dimen/dp2"
app:tabMode="fixed"
app:tabSelectedTextColor="#android:color/white"
app:tabTextAppearance="#style/MyCustomTabTextAppearance" />
styles xml :-
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/color_156084</item>
</style>
<style name="MyCustomTabTextAppearance" parent="TextAppearance.Design.Tab">
<item name="android:textSize">#dimen/sp14</item>
<item name="android:textColor">#android:color/white</item>
<item name="textAllCaps">false</item>
</style>
I have set padding to -1dp and even did tabGravity to fill but nothing is working.
This code used to work in earlier versions but now if i am downgrading it, i am getting a no class def found error on TintManager.
Setting different values or layout params did not work, so the only solution I got was to add the following, after you add the tabs to your tab layout,
final ViewGroup test = (ViewGroup)(tabs.getChildAt(0));//tabs is your Tablayout
int tabLen = test.getChildCount();
for (int i = 0; i < tabLen; i++) {
View v = test.getChildAt(i);
v.setPadding(0, 0, 0, 0);
}
Try adding below attributes to TabLayout:
app:tabPaddingStart="-1dp"
app:tabPaddingEnd="-1dp"
Hope it'll work.
Instead of dealing with TabLayout subviews, you can access TabLayout.Tab view directly and set the padding to 0 just like the code below.
for (int i = 0; i < tabLayout.getTabCount(); i++) {
View tabView = tabLayout.getTabAt(i).view;
tabView.setPadding(0, 0, 0, 0);
}
I'm doing this in the onCreateView callback and it works perfectly.
Just pass your tabLayout to this method and it's done!
private void setTabLayoutMatchParent(TabLayout tabLayout) {
final ViewGroup tabLayoutChild = (ViewGroup)(tabLayout.getChildAt(0));
int tabLen = tabLayoutChild.getChildCount();
for (int j = 0; j < tabLen; j++) {
View v = tabLayoutChild.getChildAt(j);
v.setPadding(0, 0, 0, 0);
}
}
I was stuck for hours until I found the method tab.setCustomView(idRes). Changing from inflated to this worked for me. Alernatively, if you are inflating you can use TabLayout.TabView as root viewgroup.
Apart from this, I am not sure if it is helpful but I used minWidth to the custom view layout.
This is what I wanted
There are attributes in TabLayout : app:tabPaddingStart and app:tabPaddingEnd
You can set -1 to both of them in order to remove padding start and end in custom view of TabLayout.
<com.google.android.material.tabs.TabLayout
android:id="#+id/tlEmojis"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:tabPaddingStart="-1dp"
app:tabPaddingEnd="-1dp"
app:tabMaxWidth="#dimen/dimen_48dp"
app:tabMode="scrollable" />
Try adding TabLayout in LinearLayout like:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="#+id/sliding_tabs"
style="#style/MyCustomTabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFF" />
</LinearLayout>
In Styles.xml add:
<style name="MyCustomTabLayout" parent="Widget.Design.TabLayout">
<item name="tabTextAppearance">#style/MyCustomTextAppearance</item>
</style>
<style name="MyCustomTextAppearance" parent="TextAppearance.Design.Tab">
<item name="textAllCaps">false</item>
</style>
In my case the problem was giving fixed height to the custom layout that i use for tabs.
Using match_parent fixed my issue.

How to prevent my snackbar text from being truncated on Android?

I am displaying a snackbar with a fairly long text message and on the phone in portrait mode it looks fine.
But on the tablet it seems to only allow 1 line of text so it gets ellipsis-ed
Is there anyway I can get it to be 2 line in tablet landscape?
What's important and not stated in other answers is that you need to use Snackbar's view.
So:
Snackbar snackbar = Snackbar.make(rootView, R.string.message, Snackbar.LENGTH_LONG);
View snackbarView = snackbar.getView();
TextView snackTextView = (TextView) snackbarView.findViewById(com.google.android.material.R.id.snackbar_text);
snackTextView.setMaxLines(2);
snackbar.show();
Note: This may also help with devices with lower screen density.
P.S If you're not using AndroidX (which is recommended), and are still using the legacy support libraries, please use android.support.design.R.id.snackbar_text instead of com.google.android.material.R.id.snackbar_text for getting the Snackbar's internal TextView.
You can reference the SnackBar's TextView like this:
TextView tv = (TextView) view.findViewById(android.support.design.R.id.snackbar_text);
And then operate on the TextView itself by changing its max lines:
tv.setMaxLines(3)
Based on Snackbar source code you can see that on devices with width more or equal than 600 dp they change max lines to 1. So You can also just add:
<integer name="design_snackbar_text_max_lines">3</integer>
into your res\values\*.xml values
A more elaborate and thorough example with context would be this:
// Create on click listener
final OnClickListener positiveButtonClickListener = new OnClickListener()
{
#Override
public void onClick(View v)
{
// Do your action - e.g. call GooglePlay to update app
openGooglePlayAppUpdate();
}
};
// Create snack bar instance
Snackbar sBar = Snackbar.make(findViewById(R.id.some_view_to_bind), // You bind here e.g. layout, or form view
R.string.snack_bar_message,
Snackbar.LENGTH_INDEFINITE)
// Set text and action to the snack bar
.setAction(android.R.string.ok, positiveButtonClickListener);
// Now get text view of your snack bar ...
TextView snckBarTv = (TextView) offerUpdate.getView().findViewById(android.support.design.R.id.snackbar_text);
snckBarTv.setMaxLines(5); // ... and set max lines
sBar.show(); // and finally display snack bar !
For those using Kotlin you can make use of extensions
fun Snackbar.setMaxLines(lines: Int): Snackbar = apply {
view.findViewById<TextView>(com.google.android.material.R.id.snackbar_text).maxLines = lines
}
For me, the best solution was auto-size within 2 lines:
<style name="ThemeOverlay.MyApp.SnackBar.Text" parent="#style/Widget.MaterialComponents.Snackbar.TextView" >
<item name="autoSizeStepGranularity">0.5dp</item>
<item name="autoSizeMaxTextSize">16dp</item>
<item name="autoSizeMinTextSize">10dp</item>
<item name="autoSizeTextType">uniform</item>
</style>
You can also increase the max number of lines or change any other TextView attribute:
<style name="ThemeOverlay.MyApp.SnackBar.Text" parent="#style/Widget.MaterialComponents.Snackbar.TextView" >
<item name="android:maxLines">3</item>
</style>
And customize the button and paddings:
<style name="ThemeOverlay.MyApp.SnackBar.Button" parent="#style/Widget.MaterialComponents.Button.TextButton.Snackbar" >
<item name="android:paddingStart">16dp</item>
<item name="android:paddingEnd">16dp</item>
<item name="android:textSize">14dp</item>
<item name="android:textAllCaps">false</item>
<item name="android:letterSpacing">0.0</item>
</style>
<style name="ThemeOverlay.MyApp.SnackBar" parent="#style/Widget.MaterialComponents.Snackbar" >
<item name="android:paddingStart">8dp</item>
<item name="android:paddingEnd">8dp</item>
</style>
Your theme:
<style name="Theme.MyApp" parent="#style/Theme.MaterialComponents.DayNight.NoActionBar">
<item name="snackbarStyle">#style/ThemeOverlay.MyApp.SnackBar</item>
<item name="snackbarButtonStyle">#style/ThemeOverlay.MyApp.SnackBar.Button</item>
<item name="snackbarTextViewStyle">#style/ThemeOverlay.MyApp.SnackBar.Text</item>
</style>

How to programmatically change the primary color in Android L?

Is there a way to change programmatically the primary colors. I would like to do it in code depending on the screen/state of the app.
Currently I can only set the colors in the theme (static) :
<item name="android:colorPrimary">#color/primary_color</item>
<item name="android:colorPrimaryDark">#color/dark_color</item>
<item name="android:colorBackground">#android:color/white</item>
<item name="android:colorAccent">#color/primary_color</item>
<item name="android:colorControlHighlight">#color/primary_color</item>
You can, of course, implement custom subclasses of View that have methods for setting colors.
You can also define multiple themes with you various color schemes.
Views look up theme information from the context when they are created. So to change the styles applied from a theme you will have to recreate your view hierarchy with a context that uses the right theme.
One way to do that, is to create a new ContextThemeWrapper and then get a LayoutInflator that uses that theme wrapper, remove the old version of your layout and re-inflate your layout.
Roughly:
ContextThemeWrapper themeWrapper = new ContextThemeWrapper(this, R.style.AppThemeWithColorScheme2);
LayoutInflater layoutInflater = LayoutInflater.from(themeWrapper);
viewContainer.removeAllViews();
layoutInflater.inflate(R.layout.my_layout, viewContainer, true );
If you are using Action Bar, that may be a bit more tricky, because the Action Bar is created once per activity.
USe this code for setting toolbarcolor and status bar (darker toolbar color)
toolbar.setBackgroundColor(toolbarColor);
factor=0.8f;
int a = Color.alpha(toolbarcolor);
int r = Math.round(Color.red(toolbarcolor) * factor);
int g = Math.round(Color.green(toolbarcolor) * factor);
int b = Math.round(Color.blue(toolbarcolor) * factor);
int statusColor=Color.argb(a,
Math.min(r, 255),
Math.min(g, 255),
Math.min(b, 255));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = MainActivity.this.getWindow();
window.setStatusBarColor(statusColor);
}
This is most practical with no error, there is no need to do any extra coding, just go to android tree project
res > values > colors then edit these codes:
<resources>
<color name="colorPrimary">#008577</color>
<color name="colorPrimaryDark">#00574B</color>
<color name="colorAccent">#D81B60</color>
</resources>
add these under style:
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
add into manifest just after ".MainActivity" :
android:theme="#style/AppTheme.NoActionBar">
This change everything in text
<item name="android:textColorPrimary">#color/textGrey</item>
<item name="android:textColorSecondary">#color/textGrey</item>
<item name="android:textColorTertiary">#color/textGrey</item>
<item name="android:listDivider">#color/textGrey</item>

Customizing android.widget.SearchView

Is it possible to customize layout of android.widget.SearchView (I'm using it in actionBar)?
I want to change icon and TextField background.
I've found the only one way to do that- to use reflections.
SearchView mSearchView = (SearchView)menu.findItem(R.id.search).getActionView();
try
{
Field searchField = SearchView.class.getDeclaredField("mSearchButton");
searchField.setAccessible(true);
ImageView searchBtn = (ImageView)searchField.get(mSearchView);
searchBtn.setImageResource(R.drawable.search_img);
searchField = SearchView.class.getDeclaredField("mSearchPlate");
searchField.setAccessible(true);
LinearLayout searchPlate = (LinearLayout)searchField.get(mSearchView);
((ImageView)searchPlate.getChildAt(0)).setImageResource(R.drawable.search_img);
searchPlate.setBackgroundResource(R.drawable.edit_text_bkg);
}
catch (NoSuchFieldException e)
{
Log.e(TAG,e.getMessage(),e);
}
catch (IllegalAccessException e)
{
Log.e(TAG,e.getMessage(),e);
}
If you use Appcompat v7, there is a way to do it without using reflection:
Declare the following style, and customize only those properties you need to customize, remove the rest (so they are inerhited from the parent style):
<style name="Widget.AppCompat.SearchView.CustomSearchView" parent="#style/Widget.AppCompat.SearchView">
<item name="layout">#layout/abc_search_view</item>
<item name="queryBackground">#drawable/abc_textfield_search_material</item>
<item name="submitBackground">#drawable/abc_textfield_search_material</item>
<item name="closeIcon">#drawable/abc_ic_clear_mtrl_alpha</item>
<item name="goIcon">#drawable/abc_ic_go_search_api_mtrl_alpha</item>
<item name="voiceIcon">#drawable/abc_ic_voice_search_api_mtrl_alpha</item>
<item name="commitIcon">#drawable/abc_ic_commit_search_api_mtrl_alpha</item>
<item name="suggestionRowLayout">#layout/abc_search_dropdown_item_icons_2line</item>
<item name="searchIcon">#drawable/ic_action_search</item>
</style>
Now, in your theme, use the same property:
<item name="searchViewStyle">#style/Widget.AppCompat.SearchView.Bonial</item>
Of course, your theme must inherit from one of the AppCompat themes, in my case, it was something like this:
<style name="Theme.MyActionBarActivity" parent="#style/Theme.AppCompat.Light">
Also your activities should extend ActionBarActivity and use the "support" version of the action bar methods. More info here.
I also read an article of a guy that declared the styles in some other way, but also using AppCompat v7:
http://www.jayway.com/2014/06/02/android-theming-the-actionbar/
If you are using android native SearchView and you want to change small search icon, which appears when searchView is expanded, then you are in trouble. Because attribute searchViewSearchIcon is internal, and can't be modified using styles.
Code snippet from SearchView class:
private int getSearchIconId() {
TypedValue outValue = new TypedValue();
getContext().getTheme().resolveAttribute(com.android.internal.R.attr.searchViewSearchIcon,
outValue, true);
return outValue.resourceId;
}
In ActionBarSherlock:
<style name="Your_Theme" parent="#style/Theme.Sherlock">
<item name="searchViewSearchIcon"> #drawable/ic_menu_search </item>
</style>
In Holo:
<style name="Your_Theme" parent="#style/Theme.Light">
<item name="android:searchViewSearchIcon"> #drawable/ic_search </item>
</style>

Categories

Resources