How to create TextInputLayout with OutlineBox programmatically
Asked Answered
K

3

14

I want to create TextInputLayout with Widget.MaterialComponents.TextInputLayout.OutlinedBox style. I tried many ways but couldn't get the required result. Here is my code.

TextInputLayout textInputLayout = new TextInputLayout(getActivity(),null,R.style.Widget_MaterialComponents_TextInputLayout_OutlinedBox);
textInputLayout.setHint("My Hint");
TextInputEditText editText = new TextInputEditText(textInputLayout.getContext());
textInputLayout.addView(editText);
parentView.addView(textInputLayout);

I also tried:

TextInputLayout textInputLayout = new TextInputLayout(getActivity(),null,TextInputLayout.BOX_BACKGROUND_OUTLINE);

I want to create view like this .enter image description here

Kazan answered 25/10, 2018 at 12:17 Comment(6)
Create custom square drawableLatria
its not only about the background @naveen but this style also gives hint move on border when we start writing in edittext. also manages focus change listener etc automatically.Kazan
You could use view with help the LayoutInflater.inflate() as temporary solutionProwl
you need to use new material design components codelabs.developers.google.com/codelabs/mdc-101-java/#3Intercommunion
If you can bring it to an answer, it would be great!Tufa
@Kerooker check my comment on below answer i.e. Nilesh Rathod's solution. Thankyou. let me know if you need any further help.Kazan
M
26

UPDATE

Thanks to @Mike M.

You need to use TextInputLayout.setBoxBackgroundMode() method to use OutlineBox style

setBoxBackgroundMode (int boxBackgroundMode)

  • Set the mode for the box's background (filled, outline, or none).

Then you need to use TextInputLayout.BOX_BACKGROUND_OUTLINE) Constants

NOTE: To get the corner in your OutlineBox of TextInputLayout you need to use setBoxCornerRadii() method

SAMPLE CODE

public class MainActivity extends AppCompatActivity {

    LinearLayout parentView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        parentView = findViewById(R.id.parentView);

        TextInputLayout emailTextInputLayout = new TextInputLayout(this, null, R.style.Widget_MaterialComponents_TextInputLayout_OutlinedBox);

        emailTextInputLayout.setHint("Please Enter Email Address");
        emailTextInputLayout.setBoxBackgroundMode(TextInputLayout.BOX_BACKGROUND_OUTLINE);
        emailTextInputLayout.setBoxCornerRadii(5, 5, 5, 5);
        TextInputEditText edtEmail = new TextInputEditText(emailTextInputLayout.getContext());
        emailTextInputLayout.addView(edtEmail);

        parentView.addView(emailTextInputLayout);


        TextInputLayout passTextInputLayout = new TextInputLayout(this, null, R.style.Widget_MaterialComponents_TextInputLayout_OutlinedBox);

        passTextInputLayout.setHint("Please Enter Password");
        passTextInputLayout.setBoxBackgroundMode(TextInputLayout.BOX_BACKGROUND_OUTLINE);
        passTextInputLayout.setBoxCornerRadii(5, 5, 5, 5);
        TextInputEditText edtPass = new TextInputEditText(passTextInputLayout.getContext());
        passTextInputLayout.addView(edtPass);

        parentView.addView(passTextInputLayout);


    }

}

OUTPUT

enter image description here

Based on this answer: https://mcmap.net/q/101373/-how-to-set-the-style-attribute-programmatically-in-android

  • Dynamic style change is not currently supported. You must set the style before the view is created (in XML).

That's the reason that TextInputLayout does not programmatically accept setting the outline boxed style.

Here is the simple solution:

You can use LayoutInflater

  • Instantiates a layout XML file into its corresponding View objects.

DEMO

Create a new layout

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.TextInputLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/userIDTextInputLayout"
    style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="10dp">

    <android.support.design.widget.TextInputEditText
        android:id="@+id/userIDTextInputEditText"
        android:layout_width="match_parent"
        android:hint="Enter User Name"
        android:layout_height="wrap_content" />
</android.support.design.widget.TextInputLayout>

AndroidX (+Material Components for Android):

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.textfield.TextInputLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/userIDTextInputLayout"
    style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="10dp">

    <com.google.android.material.textfield.TextInputEditText 
        android:id="@+id/userIDTextInputEditText"
        android:layout_width="match_parent"
        android:hint="Enter User Name"
        android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout>

Now using LayoutInflater add that TextInputLayout in your required layout

public class MainActivity extends AppCompatActivity {

    LinearLayout rootView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        rootView = findViewById(R.id.rootView);

        View view = LayoutInflater.from(this).inflate(R.layout.temp_layout, null);
        TextInputLayout userNameIDTextInputLayout=view.findViewById(R.id.userIDTextInputLayout);
        TextInputEditText userNameInputEditText = view.findViewById(R.id.userIDTextInputEditText);
        userNameIDTextInputLayout.setHint("Please Enter User Name");
        rootView.addView(view);
    }
}

OUTPUT

Screenshot of app with an outlined text input

Note

If you want to add a TextInputLayout from XML, then please check out the following answer:

If you want to add more than 5 TextInputLayouts programmatically, then please consider using a RecyclerView. Check out the following answers:

Hope this helps!

Mead answered 26/10, 2018 at 4:59 Comment(13)
Thanks for your help. I'll try your solution i hope it work.Kazan
@DeepakVajpayee welcome let me know if your required any helpMead
your answer work for me with little change. as i am working with androidx so i had to change android.support.design.widget.TextInputLayout to com.google.android.material.textfield.TextInputEditText and android.support.design.widget.TextInputEditText to ** <com.google.android.material.textfield.TextInputEditText**.Kazan
Hey, Nilesh. Just FYI, the latest Material Components TextInputLayout has the setBoxBackgroundMode() method, though it doesn't seem to have been added to the docs yet. We can now do this strictly programmatically with setBoxBackgroundMode(TextInputLayout.BOX_BACKGROUND_OUTLINE). I just tested it, and it's all good, if you'd like to update your answer. Using com.google.android.material:material:1.1.0-alpha02, btw.Argufy
@Kerooker How do you mean? It's not a workable solution for you? Or do you mean you just can't get it to work at all? As I mentioned above, I tested it earlier, and it works as expected for me.Argufy
It's exactly the same for me as the default version, with the exception that it has no underline colorTufa
I'll test it a little more and ask a question with more details.Tufa
@Kerooker Hmm, sounds like possibly the outline color might be blending in with your background. I'm not sure which attribute that outline color comes from, but I'll do some testing and research here in a little while, when I get back to my dev machine.Argufy
@Kerooker Actually, there's a quick way you can test if it's the color that's the problem. There's also now a setBoxStrokeColor() method that takes a color value. You might try calling that with, e.g., Color.MAGENTA, or some other contrasting color, just to check.Argufy
@Kerooker OK, just so you know, setBoxStrokeColor() only changes the focused color of the outline, so you won't see that color until the EditText has focus. The default color for the focused outline is set from your theme's colorAccent attribute, so check what you have for that. Also, the default outline state colors are all various translucent shades of black, so they might not show up very well on dark backgrounds, especially if you don't have the right parent theme for your app theme. Make sure you're using a Theme.MaterialComponents.Argufy
@MikeM. sir yes you are right with the help of setBoxBackgroundMode() and setBoxCornerRadii() we can achieve OutlineBox of TextInputLayout, I have updated my answer BTW sorry for the late reply I was on holiday.Mead
No worries. I was just trying to get you the bounty before it expired. :-) I'm not sure, anyway, if Kerooker ever did get it working for their setup. Oh, well. Cheers!Argufy
@MikeM. so there's no way to set the unfocused line color? This is bad :xTufa
S
1

You can use the method applyStyle defined on the Theme class. In Kotlin, you can access it with the theme property on a Context (or subclass) instance.

The applyStyle function allows you to add a style to the current theme, that defines theme attributes referencing styles. After calling this method, you can pass the attribute as the third parameter of a View, like TextInputLayout, which will apply the desired styles while respecting the theme.

I used this technique in Splitties (a library which I authored), and there's some documentation plus examples that should help you: https://github.com/LouisCAD/Splitties/blob/v3.0.0-alpha02/views-dsl/README.md#using-styles-defined-in-xml

I did not yet add first class support for themes from Material Components in Splitties Views DSL, but you can do it yourself, and you can even open an issue to discuss it, or contribute so it gets integrated sooner.

Splenetic answered 14/1, 2019 at 13:38 Comment(0)
G
1

This is how i did it, notice that you have to pass the context of TextInputLayout to TextInputEditText so that the style is passed on correctly.

[ src: https://material.io/components/text-fields/android#filled-text-field ]

val lp = LinearLayout.LayoutParams(
    LinearLayout.LayoutParams.MATCH_PARENT,
    LinearLayout.LayoutParams.WRAP_CONTENT
)

val etInputLayout = TextInputLayout(context)
lp.setMargins(16, 16, 16, 16)
etInputLayout.layoutParams = lp
etInputLayout.boxBackgroundMode = TextInputLayout.BOX_BACKGROUND_OUTLINE
etInputLayout.boxBackgroundColor = Color.WHITE
etInputLayout.setBoxCornerRadii(8f, 8f, 8f, 8f)

val etInput = TextInputEditText(etInputLayout.context)
etInput.layoutParams = lp
etInputLayout.addView(etInput, lp)
Gamopetalous answered 27/3, 2021 at 11:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.