user123456789
user123456789

Reputation: 321

Android: Programmatically adding TextInputLayout

I am trying to add a TextInputLayout with an EditText to a LinearLayout programmatically. My approach:

TextInputLayout textInputLayout = new TextInputLayout(new ContextThemeWrapper(getContext(), R.style.Widget_MaterialComponents_TextInputLayout_OutlinedBox));
textInputLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
textInputLayout.setHintTextAppearance(R.style.Base_Widget_MaterialComponents_TextInputLayout_TextInputLayout);

TextInputEditText editText = new TextInputEditText(getContext());
editText.setHint("test");

textInputLayout.addView(editText, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
linearLayout.addView(textInputLayout);

However, the result looks extremly buggy:

buggy view


Weirdly enough, adding the same TextInputLayout via XML works:

<com.google.android.material.textfield.TextInputLayout
    style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="kommentar"
    app:hintTextAppearance="@style/Base.Widget.MaterialComponents.TextInputLayout.TextInputLayout">

    <com.google.android.material.textfield.TextInputEditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</com.google.android.material.textfield.TextInputLayout>

working view via xml


Now, I need to add that the programmatical approach worked before upgrading to Material 1.1. I am using material components only. How can I fix this?

Upvotes: 5

Views: 3373

Answers (3)

ninja_expert
ninja_expert

Reputation: 1

I came accross the same issue. the accepted answer was still not rendering the layout correctly I then saw the following snippet in the docs... lol

Using text fields programmatically

If you construct the TextInputEditText child of a TextInputLayout programmatically, you should use TextInputLayout's context to create the view. This will allow TextInputLayout to pass along the appropriate styling to the edit text.

val textInputLayout = TextInputLayout(context)
val editText = TextInputEditText(textInputLayout.context)

sources: https://developer.android.com/reference/com/google/android/material/textfield/TextInputLayout https://github.com/material-components/material-components-android/blob/master/docs/components/TextField.md

Upvotes: 0

Seven
Seven

Reputation: 3252

I spent hours trying to achieve the same thing and when I was about to give up I found this Material Components GitHub issue. Quoting gabrielemariotti's answer below, which is for a MaterialButton, but the same applies to TextInputLayout, and probably other Material Components.

If you want to create a custom button with a custom style you have to:

  • define an attribute in attrs.xml <attr name="myButtonStyle" format="reference"/>

  • assign in your app theme a value to this new attr:

    <style name="AppTheme" parent="Theme.MaterialComponents.DayNight">
        <item name="myButtonStyle">@style/AccentButtonStyle</item>
    </style>

with:

    <style name="AccentButtonStyle" parent="Widget.MaterialComponents.Button">
        <item name="backgroundTint">@color/...</item>
        <item name="icon">@drawable/....</item>
        <item name="iconTint">@color/....</item>
    </style>

and then use this constructor:

class AccentButton @JvmOverloads constructor(
        context: Context,
        attrs: AttributeSet? = null,
        @AttrRes defStyleAttr: Int = R.attr.myButtonStyle
  ) : MaterialButton(context, attrs, defStyleAttr) {
}

Upvotes: 1

Md. Asaduzzaman
Md. Asaduzzaman

Reputation: 15423

With the style attribute you have to use setBoxBackgroundMode() method to use OutlineBox style. Beside this, you should have use TextInputLayout's context to create TextInputEditText. Check below:

textInputLayout.setBoxBackgroundColor(ContextCompat.getColor(getContext(), android.R.color.white));
textInputLayout.setBoxBackgroundMode(TextInputLayout.BOX_BACKGROUND_OUTLINE);

//Must use context of textInputLayout
TextInputEditText editText = new TextInputEditText(textInputLayout.getContext());

Output:

enter image description here

Upvotes: 12

Related Questions