Reputation: 321
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:
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>
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
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
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
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:
Upvotes: 12