Change TextInputLayout accent color programmatically - android

I've got a simple TextInputLayout containing an EditText View.
Now I wonder how to change the accent color (underline, hintTextColor when highlighted) programmatically.
I can't seem to find a suitable method inside TextInputLayout.
Any suggestions? Thanks in advance.

IMHO InputTextLayout can not change label color programmatically, because it is set by style. I examined source code of InputTextLayout and wrote this hack helper method which create access to private color member:
public static void setInputTextLayoutColor(EditText editText, #ColorInt int color) {
TextInputLayout til = (TextInputLayout) editText.getParent();
try {
Field fDefaultTextColor = TextInputLayout.class.getDeclaredField("mDefaultTextColor");
fDefaultTextColor.setAccessible(true);
fDefaultTextColor.set(til, new ColorStateList(new int[][]{{0}}, new int[]{ color }));
Field fFocusedTextColor = TextInputLayout.class.getDeclaredField("mFocusedTextColor");
fFocusedTextColor.setAccessible(true);
fFocusedTextColor.set(til, new ColorStateList(new int[][]{{0}}, new int[]{ color }));
} catch (Exception e) {
e.printStackTrace();
}
}
mFocusedTextColor is used for set internal CollapsingTextHelper.mCollapsedTextColor which sets color of label.

You can try this for the text,
InputTextLayout.getEditText().setHighlightColor(yourColor);
InputTextLayout.getEditText().setHintTextColor(yourColor);
and this for the line at the bottom of the EditText
Drawable background = InputTextLayout.getEditText().getBackground();
DrawableCompat.setTint(background, yourColor);
InputTextLayout.getEditText().setBackground(background);
Hope it works!

Related

Android: Setting EditText's default hint color from .java

So I have a LinearLayout and 4 EditText-s in it with grayish hint colors in XML. And I have button that dynamically adds new EditText-s to LinearLayout. The problem is when I use setHint("text") it makes hint color for new created views black.
Also tried setHintTextColor() but the only way it worked for me by setting custom color. Is there a default hint color that I can set by setHintTextColor()?? or maybe some method that does it when it's called?
Code looks like this:
private EditText createNewTextView(String text) {
++x;
final ActionBar.LayoutParams lparams = new ActionBar.LayoutParams(ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.WRAP_CONTENT);
final EditText editText = new EditText(this);
editText.setLayoutParams(lparams);
editText.setHint("Name" + x);
editText.setHintTextColor(getResources().getColor(R.color.hintcolor));
return editText;
}
p.s. I made new color in colors which is called hintcolor
I've been looking for solution, but there was nothing that would help me, or I just didn't understood it. I'm new at android and programming so don't judge please, just explain. Thanks a lot
It may be too late but for the sake of others who have the same problem, I solved it by making a method to get default textColorHint.It returns the color of the hint text for all the states (disabled, focussed, selected...) that specified in the current theme.
int getHintTextColor(Context context) {
int[] hintTextColor = new int[] { android.R.attr.textColorHint };
int indexOfAttrTextColorHint = 0;
TypedArray ta = context.obtainStyledAttributes(hintTextColor);
int textColor = ta.getColor(indexOfAttrTextColorHint, 0xFF808080);
ta.recycle();
return textColor;
}
I hope this helps.

Android TextInputLayout Styling programmatically

I'm working on an app that has full UI customization. If you look at a EditText wrapped in an TextInputLayout, the EditText's default text hint color and line color are the same as the color textPrimaryColor defined in styles. When the EditText receives focus however, the line becomes the color of the accent defined in styles, the hint goes through the floating hint animation and changes to the accent color. It's pretty easy to do with styles.xml and themes.xml, however, I can't quite get it programmatically.
The current method I have set up is this:
public static void setInputTextLayoutColor(final int accent, final int text, TextInputLayout textInputLayout, AppCompatEditText edit) {
edit.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
AppCompatEditText editText = (AppCompatEditText) v;
editText.getBackground().clearColorFilter();
if(hasFocus) editText.getBackground().setColorFilter(accent, PorterDuff.Mode.SRC_IN);
else editText.getBackground().setColorFilter(text, PorterDuff.Mode.SRC_IN);
}
});
setCursorColor(edit, accent);
try {
Field field = textInputLayout.getClass().getDeclaredField("mFocusedTextColor");
field.setAccessible(true);
int[][] states = new int[][]{
new int[]{}
};
int[] colors = new int[]{
accent
};
ColorStateList myList = new ColorStateList(states, colors);
field.set(textInputLayout, myList);
Field fDefaultTextColor = TextInputLayout.class.getDeclaredField("mDefaultTextColor");
fDefaultTextColor.setAccessible(true);
fDefaultTextColor.set(textInputLayout, myList);
Method method = textInputLayout.getClass().getDeclaredMethod("updateLabelState", boolean.class);
method.setAccessible(true);
method.invoke(textInputLayout, true);
} catch (Exception e) {
e.printStackTrace();
}
}
The problem with this method is that A) the hint text is colored immediately to the accent color, it doesn't color to the accent when focus is received B) The EditText line starts off with the right color, but when it receives focus, it colorizes to accent defined in styles, not the programatically set color.
This is the non-focused picture (in reference to the "Event name" field). Here, the color of "event name" should be gray / white (like the text"):
This is the focused picture, here, everything is right except the color of the line, which should be green as well.
Wasn't able to figure out dynamically changing the hint color, but I got the line color to change with a listener:
AppCompatEditText edit = (AppCompatEditText)findViewById(R.id.event_create_name_edit);
edit.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
AppCompatEditText edit2 = (AppCompatEditText)v;
if(hasFocus) edit2.setSupportBackgroundTintList(ColorStateList.valueOf(rui.getAccent()));
else edit2.setSupportBackgroundTintList(ColorStateList.valueOf(rui.getText()));
}
});

Programmatically set TextInputLayout Hint Text Color and Floating Label Color

I use a TextInputLayout, I would want to programmatically set the hint text color and the floating label color if the input field is mandatory. Before moving to TextInputLayout I used to set the hint text color programmatically using the following
textField.setHintTextColor(Color.RED);
Can someone guide me on how to set the hint text color and the floating label color programmatically for a TextInputLayout.
In the screenshot attached i would want the hint text Address 1 to be in red when not focused and the on focus the floating label Address 1 should be in red.
I changed focused color with reflection. Here's the snippet it may help someone.
private void setUpperHintColor(int color) {
try {
Field field = textInputLayout.getClass().getDeclaredField("mFocusedTextColor");
field.setAccessible(true);
int[][] states = new int[][]{
new int[]{}
};
int[] colors = new int[]{
color
};
ColorStateList myList = new ColorStateList(states, colors);
field.set(textInputLayout, myList);
Method method = textInputLayout.getClass().getDeclaredMethod("updateLabelState", boolean.class);
method.setAccessible(true);
method.invoke(textInputLayout, true);
} catch (Exception e) {
e.printStackTrace();
}
}
EDIT 2018-08-01:
If you are using design library v28.0.0 and later, fields had changed from mDefaultTextColorto defaultHintTextColor and from mFocusedTextColor to focusedTextColor.
Check decompiled class for other fields.
With the Material Components library you can use:
In the layout:
<com.google.android.material.textfield.TextInputLayout
app:hintTextColor="#color/mycolor"
android:textColorHint="#color/text_input_hint_selector"
.../>
in a style:
<style name="..." parent="Widget.MaterialComponents.TextInputLayout.FilledBox">
<!-- The color of the label when it is collapsed and the text field is active -->
<item name="hintTextColor">?attr/colorPrimary</item>
<!-- The color of the label in all other text field states (such as resting and disabled) -->
<item name="android:textColorHint">#color/mtrl_indicator_text_color</item>
</style>
in the code:
// Sets the text color used by the hint in both the collapsed and expanded states
textInputLayout.setDefaultHintTextColor(...);
//Sets the collapsed hint text color
textInputLayout.setHintTextColor(....);
Please, take a good look at the documentation here: TextInputLayout Methods
There is a method :
setHintTextAppearance(int resId)
Which takes a resource id that could be a style resource!
I would try this and see how it goes!
I hope it helps you!
Normally TextInputLayout hint text color comes from app's colorAccent.
But if you want to change then you can use style for that.
<android.support.design.widget.TextInputLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:theme="#style/TextLabel">
</android.support.design.widget.TextInputLayout>
#style
<style name="TextLabel" parent="TextAppearance.AppCompat">
<!-- Hint color and label color in FALSE state -->
<item name="android:textColorHint">#color/Color Name</item>
<item name="android:textSize">20sp</item>
<!-- Label color in TRUE state and bar color FALSE and TRUE State -->
<item name="colorAccent">#color/Color Name</item>
<item name="colorControlNormal">#color/Color Name</item>
<item name="colorControlActivated">#color/Color Name</item>
</style>
But if you want to add red color then how you can differentiate with error color means basic standard error have Red color.
textField.setHintTextColor(Color.RED); Can someone guide me on how to
set the hint text color and the floating label color programmatically
for a TextInputLayout.
setHintTextColor works for API 23+
For Changing the both Focused Color and Default Text Color for TextInput Layout
private void setInputTextLayoutColor(int color, TextInputLayout textInputLayout) {
try {
Field field = textInputLayout.getClass().getDeclaredField("mFocusedTextColor");
field.setAccessible(true);
int[][] states = new int[][]{
new int[]{}
};
int[] colors = new int[]{
color
};
ColorStateList myList = new ColorStateList(states, colors);
field.set(textInputLayout, myList);
Field fDefaultTextColor = TextInputLayout.class.getDeclaredField("mDefaultTextColor");
fDefaultTextColor.setAccessible(true);
fDefaultTextColor.set(textInputLayout, myList);
Method method = textInputLayout.getClass().getDeclaredMethod("updateLabelState", boolean.class);
method.setAccessible(true);
method.invoke(textInputLayout, true);
} catch (Exception e) {
e.printStackTrace();
}
}
EDIT : To Change AppCompactEditText line color
You need to set the backgroundTintList (or supportBackgroundTintList) on the EditText to an instance of ColorStateList containing only the color you wish to change the tint to. An easy way to do this in a backwards-compatible way looks like this:
ColorStateList colorStateList = ColorStateList.valueOf(color)
editText.setSupportBackgroundTintList(colorStateList)
This will give the EditText the desired underline color.
Let me share my experience on this. I also tried all solutions given in every related question to this one. i.e. Change hint color of child widget to TextInputLayout
I am glad to share the answer to this question with a little detail.
All we need to know is:-
Adding below line to style of either TextInputLayout or its child widget, is not much a help.
<item name="android:textColorHint">#color/white</item>
as it will use colorAccent whenever the focus is received/granted to editable widget.
The actual answer to this problem is to add that style line in Application's style tag, by which it will set hint color when that or any editable area is not in focus. (That is the point we miss everytime).
Please let me know if we have other information on this.
Thanks!
I was facing the quite same problem but with mutable hints and colored symbol. I'm made this trick with data binding and Spannable in this way.
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/ti_last_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="8dp"
app:boxStrokeWidth="0dp"
app:boxStrokeWidthFocused="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/et_last_name"
style="#style/EditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:onFocusChangeListener="#{viewModel.onFocusChangeListener(#string/last_name)}"
tools:hint="#string/last_name" />
</com.google.android.material.textfield.TextInputLayout>
viewModel.onFocusChangeListener defined in this way
fun onFocusChangeListener(hint: String) =
OnFocusChangeListener { view, isFocused ->
(view.parent.parent as TextInputLayout).apply {
val editText = (view as TextInputEditText)
if (isFocused) {
this.hintTextColor = ColorStateList.valueOf(this.getColor(R.color.black))
editText.hint = ""
this.hint = hint
} else {
if (!editText.text.isNullOrBlank()) {
this.defaultHintTextColor = ColorStateList.valueOf(this.getColor(R.color.black))
editText.hint = ""
this.hint = hint
} else {
this.hintTextColor = ColorStateList.valueOf(this.getColor(R.color.hint_color))
val builder = SpannableStringBuilder()
builder.append(hint)
val start = builder.length
val end = start + 1
builder.append("\u2981")
builder.setSpan(
ForegroundColorSpan(Color.RED),
start,
end,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
builder.setSpan(
SuperscriptSpan(),
start,
end,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
editText.hint = builder
this.hint = ""
}
}
}
}
It's allow to use different hints and colors for focused/not focused states and has colored span.
this.getColor() it's just extension
fun View.getColor(color: Int): Int {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
this.context.resources.getColor(color, context.theme)
} else {
this.context.resources.getColor(color)
}
I was able to get the FloatingLabel in red using the following
textInputLayout.setErrorEnabled(true);
textInputLayout.setError(" ");

CollapsingToolbarLayout's setCollapsedTitleTextColor and setExpandedTitleColor don't do anything

I'm trying to set the expanded and collapsed CollapsingToolbarLayout's title text color to be different, but no matter what I do, it is always white.
Here is the code in question:
mCollapsingToolbar.setCollapsedTitleTextColor(getResources.getColor(R.color.foo));
mCollapsingToolbar.setExpandedTitleColor(getResources.getColor(R.color.bar));
In my layout XML file, I'm not specifying any color styles on either the AppBarLayout, the CollapsingToolbarLayout, or the Toolbar itself.
Is there some sort of interference with my Activity's theme settings?
Thanks!
I think you need to try below code:
private void changeCollapsedTitleTextColor(CollapsingToolbarLayout collapsingToolbarLayout) {
try {
final Field field = collapsingToolbarLayout.getClass().getDeclaredField("mCollapsingTextHelper");
field.setAccessible(true);
final Object object = field.get(collapsingToolbarLayout);
final Field tpf = object.getClass().getDeclaredField("mTextPaint");
tpf.setAccessible(true);
((TextPaint) tpf.get(object)).setColor(getResources().getColor(R.color.your_color));
} catch (Exception ignored) {
}
}
I found here.
I hope it may help you.

Android NumberPicker change text color

I'm new to Android and I'm implementing NumberPicker to one of my activities in my app. Below is the excerpt of my code:
picker = (NumberPicker)findViewById(R.id.order_confirm_bring_time_minute_picker);
picker.setMinValue(15);
picker.setMaxValue(120);
picker.setWrapSelectorWheel(false);
setNumberPickerTextColor(picker, android.R.color.black);
public boolean setNumberPickerTextColor(NumberPicker numberPicker, int color)
{
final int count = numberPicker.getChildCount();
for(int i = 0; i < count; i++){
View child = numberPicker.getChildAt(i);
if(child instanceof EditText){
try{
Field selectorWheelPaintField = numberPicker.getClass()
.getDeclaredField("mSelectorWheelPaint");
selectorWheelPaintField.setAccessible(true);
((Paint)selectorWheelPaintField.get(numberPicker)).setColor(color);
((EditText)child).setTextColor(color);
numberPicker.invalidate();
return true;
}
catch(NoSuchFieldException e){
Log.d("setNumberPickerTextColor", "NoSuchFieldException");
}
catch(IllegalAccessException e){
Log.d("setNumberPickerTextColor", "IllegalAccessException");
}
catch(IllegalArgumentException e){
Log.d("setNumberPickerTextColor", "IllegalArgumentException");
}
}
}
return false;
}
I've looked into this post for the setNumberPickerTextColor method. But it does not seem to work as I set my color to be changed to black, but it is not visible anymore. If I do not use the setNumberPickerTextColor method, then my default color is white, which can be seen when I highlight the text in the EditText field of the NumberPicker.
This is a screenshot of the NumberPicker when the color is not changed.
This is a screenshot of the NumberPicker when the color is changed to black or any other color (I have tested and they give the same result).
Would there be a way to customize the text color in my NumberPicker? Also, I know it is a different question, but the colors of the top and bottom 'bar' as well because they do not fit the color theme of my app. Thanks in advance for help.
You need to pass the resolved color to the setTextColor method, not the resource id.
((EditText)child).setTextColor(getResources().getColor(color));

Categories

Resources