Android layout 在布局根标记为“合并”的自定义视图中应用样式

Android layout 在布局根标记为“合并”的自定义视图中应用样式,android-layout,android-custom-view,android-styles,android-textinputlayout,android-textinputedittext,Android Layout,Android Custom View,Android Styles,Android Textinputlayout,Android Textinputedittext,我有一个TextInputLayout,带有一个需要大量重用的自定义样式,因此我试图将其转换为自定义视图 以下是要重用的xml: <com.google.android.material.textfield.TextInputLayout style="@style/TextInputLayoutAppearance" android:layout_width="match_parent" android:layout_height="wra

我有一个
TextInputLayout
,带有一个需要大量重用的自定义样式,因此我试图将其转换为自定义视图

以下是要重用的xml:

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

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

    </com.google.android.material.textfield.TextInputLayout>
以下是我从上面的原始xml改编而来的用于自定义视图的
视图\u概述\u textinput

 class OutlinedTextInput @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : TextInputLayout(context, attrs, defStyleAttr) {

    init {
        LayoutInflater.from(context).inflate(R.layout.view_outlined_textinput, this, true)
    }
}
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:parentTag="com.google.android.material.textfield.TextInputLayout">

    <com.google.android.material.textfield.TextInputEditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</merge>
我假设上面的解决方案应该起作用,因为构造函数中的第三个参数是传递样式

另一个选项是在自定义视图的
init{}
中以编程方式设置所有属性,但这与在样式文件中声明样式的目的背道而驰


我的选项是什么?

当前视图有4个构造函数

  • 公共视图(上下文)->从代码创建视图时使用的简单构造函数

  • 公共视图(上下文,AttributeSet attrs)->从XML扩展视图时调用的构造函数

  • 公共视图(Context-Context,AttributeSet-attrs,int-defStyleAttr)->从XML执行膨胀,并从主题属性应用特定于类的基本样式

  • 公共视图(上下文上下文、属性集属性、int-defStyleAttr、int-defStyleRes)添加到API级别21中

  • 如果子类希望指定包含默认样式的属性,或直接指定默认样式(对于四参数构造函数),则子类将调用第三和第四构造函数

    例如,Button类的构造函数将调用此版本的超类构造函数,并为defStyleAttr提供R.attr.buttonStyle;这允许主题的按钮样式修改所有基本视图属性(特别是其背景)以及按钮类的属性

    因此,当您创建自定义视图并将该视图添加到XML中时,android将始终调用第二个构造函数,其外观如下所示

    public TextInputLayout(Context context, AttributeSet attrs) {
        this(context, attrs, attr.textInputStyle);
    }
    
    第三个参数是直接从应用程序主题获取特定样式

    因此,为了达到你想要的结果,你可以做以下几点

  • attrs.xml中添加
  • 例如,attrs.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    <attr name="attribute_name" format="reference" />
    </resources>
    
    <resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        ...
        <item name="attribute_name">@style/your_style</item>
         ...
    </style>
    

  • 最后,在自定义视图的第二个构造函数中,将该属性作为参数传递

    constructor(context: Context, attrs: AttributeSet) : 
      super(
            context,
            attrs,
            R.attr.attribute_name
           )
    

  • 我希望有帮助

    成功了!谢谢这是主题级设置,如果我想在特定布局中为视图提供样式,该怎么办?
    constructor(context: Context, attrs: AttributeSet) : 
      super(
            context,
            attrs,
            R.attr.attribute_name
           )