【问题标题】:How to create TextInputLayout with OutlineBox programmatically如何以编程方式使用 OutlineBox 创建 TextInputLayout
【发布时间】:2019-03-30 01:19:12
【问题描述】:

我想用 Widget.MaterialComponents.TextInputLayout.OutlinedBox 样式创建 TextInputLayout。我尝试了很多方法,但无法获得所需的结果。 这是我的代码。

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);

我也试过了:

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

我想创建这样的视图。

【问题讨论】:

  • 创建自定义方形drawable
  • 它不仅与@naveen 的背景有关,而且当我们开始在edittext 中书写时,这种风格也会在边框上提示移动。还自动管理焦点变化监听器等。
  • 您可以在 LayoutInflater.inflate() 的帮助下使用视图作为临时解决方案
  • 你需要使用新的材料设计组件codelabs.developers.google.com/codelabs/mdc-101-java/#3
  • 如果你能把它带到答案中,那就太好了!

标签: android android-layout material-design android-styles textinputlayout


【解决方案1】:

更新

感谢@Mike M。

你需要使用TextInputLayout.setBoxBackgroundMode()方法来使用OutlineBox样式

setBoxBackgroundMode (int boxBackgroundMode)

  • 设置框的背景模式(填充、轮廓或无)。

那你需要使用TextInputLayout.BOX_BACKGROUND_OUTLINE)常量

注意:要在 TextInputLayout 的 OutlineBox 中获得角点,您需要使用 setBoxCornerRadii() 方法

示例代码

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);


    }

}

输出

基于这个答案:https://stackoverflow.com/questions/3246447/how-to-set-the-style-attribute-programmatically-in-android

  • 目前不支持动态样式更改。您必须在创建视图之前设置样式(在 XML 中)。

这就是TextInputLayout 不以编程方式接受设置轮廓框样式的原因。

这是一个简单的解决方案:

你可以使用LayoutInflater

  • 将布局 XML 文件实例化为其对应的 View 对象。

演示

创建一个新布局

<?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>

现在使用 LayoutInflater 在所需布局中添加 TextInputLayout

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);
    }
}

输出

注意

如果您想从 XML 添加TextInputLayout,请查看以下答案:

如果您想以编程方式添加超过 5 个TextInputLayouts,请考虑使用RecyclerView。查看以下答案:

希望这会有所帮助!

【讨论】:

  • 感谢您的帮助。我会尝试你的解决方案,希望它有效。
  • @DeepakVajpayee 欢迎让我知道您是否需要任何帮助
  • 你的答案对我来说几乎没有变化。因为我正在使用 androidx,所以我不得不将 android.support.design.widget.TextInputLayout 更改为 com.google.android.material.textfield.TextInputEditText android.support.design.widget.TextInputEditText 到 **
  • 嘿,尼勒什。仅供参考,最新的 Material Components TextInputLayout 具有 setBoxBackgroundMode() 方法,尽管它似乎尚未添加到 the docs。我们现在可以使用setBoxBackgroundMode(TextInputLayout.BOX_BACKGROUND_OUTLINE) 严格地以编程方式执行此操作。我刚刚测试了它,一切都很好,如果你想更新你的答案。使用com.google.android.material:material:1.1.0-alpha02,顺便说一句。
  • 不用担心。我只是想在它到期之前给你赏金。 :-) 无论如何,我不确定 Kerooker 是否曾经让它为他们的设置工作。那好吧。干杯!
【解决方案2】:

您可以使用Theme 类上定义的方法applyStyle。在 Kotlin 中,您可以使用 Context(或子类)实例上的 theme 属性访问它。

applyStyle 函数允许您向当前主题添加样式,该样式定义了引用样式的主题属性。调用此方法后,您可以将属性作为View 的第三个参数传递,如TextInputLayout,它将在尊重主题的同时应用所需的样式。

我在 Splitties(我编写的一个库)中使用了这种技术,并且有一些文档和示例可以帮助您:https://github.com/LouisCAD/Splitties/blob/v3.0.0-alpha02/views-dsl/README.md#using-styles-defined-in-xml

我还没有在 Splitties Views DSL 中为 Material Components 的主题添加一流的支持,但您可以自己做,甚至可以打开一个问题来讨论它,或者做出贡献,以便更快地集成。

【讨论】:

    【解决方案3】:

    我就是这样做的,注意你必须将 TextInputLayout 的上下文传递给 TextInputEditText 以便正确传递样式。

    [来源:https://material.io/components/text-fields/android#fill-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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-09
      • 2017-03-11
      • 2020-06-08
      • 1970-01-01
      • 2011-08-26
      • 2014-07-27
      • 2012-09-30
      • 1970-01-01
      相关资源
      最近更新 更多