android-layout - 在合并布局根标签的自定义 View 中应用样式

标签 android-layout android-custom-view android-styles android-textinputlayout android-textinputedittext

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

这是要重用的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>
TextInputLayoutAppearance是我在 styles.xml 中创建的自定义样式

这是我的自定义 View 的类:
 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)
    }
}

这里是 view_outlined_textinput我已经从上面的原始 xml 改编,用于自定义 View :
<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>

2 这里要注意的事情:
  • 布局使用合并标签来避免 View 层次结构中的冗余 View 。
  • 应用自定义样式至关重要。使用 style= 语法在原始 xml 中应用样式。但是,由于合并标签被用于自定义 View ,因此不能那样做。

  • 我尝试按如下方式设置样式,但没有奏效:
    class OutlinedTextInput @JvmOverloads constructor(
        context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = R.style.TextInputLayoutAppearance
    ) : TextInputLayout(context, attrs, defStyleAttr) {
    

    我假设上述解决方案应该作为构造函数中的第三个参数传递样式。

    另一种选择是在 init {} 中以编程方式设置所有属性。我的自定义 View ,但这违背了在样式文件中声明样式的目的。

    我有什么选择?

    最佳答案

    目前有 4 个构造函数用于 View

  • 公共(public) View (上下文上下文)-> 从代码创建 View 时使用的简单构造函数。
  • 公共(public) View (上下文上下文,AttributeSet attrs)-> 从 XML 膨胀 View 时调用的构造函数
  • public View (Context context, AttributeSet attrs, int defStyleAttr) -> 从 XML 执行膨胀并从主题属性应用特定于类的基本样式。
  • 公共(public) View (上下文上下文、AttributeSet attrs、int defStyleAttr、int defStyleRes)在 API 级别 21 中添加

  • 第 3 和第 4 构造函数由子类调用,如果它们要指定包含默认样式的属性,或者直接指定默认样式(在四参数构造函数的情况下)

    For example, a Button class's constructor would call this version of the super class constructor and supply R.attr.buttonStyle for defStyleAttr; this allows the theme's button style to modify all of the base view attributes (in particular its background) as well as the Button class's attributes. from the docs



    因此,当您创建自定义 View 并将该 View 添加到 XML 中时,android 将始终调用第二个构造函数,该构造函数看起来像这样
    public TextInputLayout(Context context, AttributeSet attrs) {
        this(context, attrs, attr.textInputStyle);
    }
    

    第三个参数attr.textInputStyle直接从应用程序主题中获取特定样式。

    因此,要实现您正在寻找的结果,您可以执行以下操作。
  • 在您的 attrs.xml添加 <attr name="attribute_name" format="reference" />

  • 例如。 attrs.xml
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    <attr name="attribute_name" format="reference" />
    </resources>
    
  • 在文件 style.xml 中添加您的 AppTheme <item name="attribute_name">@style/your_style</item>

  • 例如。 样式.xml
    <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>
    

  • 最后,在您的自定义 View 第二个构造函数中,您将该属性作为参数传递
    constructor(context: Context, attrs: AttributeSet) : 
      super(
            context,
            attrs,
            R.attr.attribute_name
           )
    

  • 我希望它有帮助!

    关于android-layout - 在合并布局根标签的自定义 View 中应用样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58881601/

    相关文章:

    android - 如何在编辑文本获得焦点时显示软键盘?

    Android:自定义微调器大小问题

    java - 自定义溢出菜单在 Android API 21 和 23+ 中不会给出相同的结果

    android - 使用不忽略夜间限定符的 ContextCompat 以编程方式从资源中获取颜色

    java - 如何从扩展 Fragment 而不是 Activity 的类中正确检索声明到 fragment 布局中的 ImageView?

    没有 CarModeEnabled 的 Android 夜间模式

    java - Android:CustomView 中的 EditText 在触摸时未按预期运行

    android - 将 CardView 高程重置为默认值(静止高程)

    安卓软键盘隐藏分割条

    android - ConstraintLayout 相对于 ImageView 尺寸