Set TextInputLayout theme programmatically Set TextInputLayout theme programmatically xml xml

Set TextInputLayout theme programmatically


There is no way to change theme of any view or any layout at runtime. Because of themes and styles are applied during creation of view, recursively. (Themes also applies child views of layouts)

But, you can change that theme before creation of view using XML layout or programmatically.

Programmatically:

Method 1 - Create TextInputLayout programmatically with wrapping Context with android.view.ContextThemeWrapper and use.

TextInputLayout layout = new TextInputLayout(new ContextThemeWrapper(getContext(), R.style. TextInputLayoutTheme));

Method 2 - Extend TextInputLayout and use your own layout. Pass ContextThemeWrapper as context.

public class MyTextInputLayout extends TextInputLayout {    public MyTextInputLayout(Context context) {        super(new ContextThemeWrapper(context, R.style.AppTheme));    }    public MyTextInputLayout(Context context, AttributeSet attrs) {        super(new ContextThemeWrapper(context, R.style.AppTheme), attrs);    }    public MyTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) {        super(new ContextThemeWrapper(context, R.style.AppTheme), attrs, defStyleAttr);    }}

Now, you can use MyTextInputLayout in your XML layout

With XML Layout:

1) In attrs.xml file, create new attribute named textInputLayoutTheme

<attr name="textInputLayoutTheme" format="reference"/>

2) In your AppTheme in styles.xml file set your @style/TextInputLayoutTheme as textInputLayoutTheme.

<resources>    <style name="AppTheme" parent="PARENT_THEME">        <item name="textInputLayoutTheme">@style/TextInputLayoutTheme</item>    </style>    <style name="AppTheme.Secondary">        <item name="textInputLayoutTheme">@style/TextInputLayoutTheme_Secondary</item>    </style></resources>

3) In your layout.xml file, set ?attr/textInputLayoutTheme as a TextInputLayout theme

<android.support.design.widget.TextInputLayout    android:id="@+id/label"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:layout_gravity="bottom"    android:paddingTop="16dp"    android:theme="@?attr/textInputLayoutTheme"    app:errorTextAppearance="@style/Error">

Now, when you change your application theme from AppTheme to AppTheme.Secondary TextInputLayoutTheme_Secondary will be used as a theme of your TextInputLayout instead of TextInputLayoutTheme.


Unfortunately the accepted answer is not working for me.

My solution was to wrap TextInputLayout in a custom layout.

view_input_layout_wrapper.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:theme="@style/AppThemeMaterial"    android:layout_width="match_parent"    android:layout_height="match_parent">    <com.google.android.material.textfield.TextInputLayout        android:id="@+id/til"        style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"        android:layout_width="match_parent"        android:layout_height="wrap_content">    <com.google.android.material.textfield.TextInputEditText        android:id="@+id/edit_text"        android:layout_width="match_parent"        android:layout_height="wrap_content" />    </com.google.android.material.textfield.TextInputLayout></FrameLayout>

TextInputLayoutWrapper

class TextInputLayoutWrapper(context: Context) : FrameLayout(context) {    var inputLayout: TextInputLayout        private set    init {        inflate(context, R.layout.view_input_layout_wrapper, this)        inputLayout = findViewById(R.id.til)    }}

Implementation in the view (fragment/activity):

private fun addNewField(fieldName: String) {    val textInputLayoutWrapper = TextInputLayoutWrapper(        requireContext()    ).apply {        inputLayout.hint = fieldName    }    fieldsContainerViewGroup.addView(textInputLayoutWrapper)       }

NOTE: My app theme is not material theme, so I must add theme="@style/AppThemeMaterial" in the root ViewGroup of the TextInputLayout.

<style name="AppThemeMaterial" parent="Theme.MaterialComponents.Light">    <item name="colorPrimary">@color/colorPrimary</item>    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>    <item name="colorAccent">@color/colorAccent</item>    <item name="android:windowBackground">@android:color/black</item></style>