在自定义视图中提供默认样式(属性)

Hen*_*nry 10 android styles background view widget

请告诉我,如何将自定义按钮的默认背景设置为null.

我的意思是......我知道我可以定义一个"样式",它将android:background设置为"@null",并要求用户在其布局中明确应用该样式.例如:

<style name="MyButton" parent="@android:style/Widget.Button">
    <item name="android:background">@null</item>
</style>
Run Code Online (Sandbox Code Playgroud)

<com.xxx.widget.MyButton
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    style="@style/MyButton"
    android:text="MyButton" />
Run Code Online (Sandbox Code Playgroud)

上面的代码运行良好.但是如何在内部"MyButton"类中应用此样式并让用户不要显式设置样式?

例如,如何使以下布局像以前一样工作:

<com.xxx.widget.MyButton
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="MyButton" />
Run Code Online (Sandbox Code Playgroud)

我尝试在构造函数中执行此操作,如下所示,但它不起作用.

public MyButton(Context context, AttributeSet attrs) {
    this(context, attrs, com.xxx.R.style.MyButton);
}
Run Code Online (Sandbox Code Playgroud)

PS.我想在用户未明确设置背景时应用此"null"背景.

Fal*_*ana 6

这里的聚会真的很晚了。但如果有人偶然发现同样的问题,这是我的解决方案。

假设我们想要一个扩展TextInputLayout. 该类通常如下所示:

class MyTextInputLayout: TextInputLayout {
    constructor(context: Context) : this(context, null)
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int)
        : super(context, attrs, defStyleAttr)
}
Run Code Online (Sandbox Code Playgroud)

现在,为了使用我们的自定义样式作为默认样式,请将第三个构造函数(具有三个参数的构造函数)更改为:

class MyTextInputLayout: TextInputLayout {
    constructor(context: Context) : this(context, null)
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int)
        : super(ContextThemeWrapper(context, R.style.MyTextInputLayoutStyle), attrs, defStyleAttr)
}
Run Code Online (Sandbox Code Playgroud)

现在我们可以在布局 XML 文件中使用自定义视图,如下所示:

<com.xxx.MyTextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
Run Code Online (Sandbox Code Playgroud)

我们不再需要style="@style/MyTextInputLayoutStyle"在组件中定义。

简而言之,我们需要用context包装我们的样式的构造函数替换传递给超级构造函数的构造函数。这样我们就不需要在现有主题中定义 R.attr.MyTextInputLayoutStyle 了。当您想要将自定义视图用作库时很有用。


Kar*_*ela 2

在 MyButton() 构造函数中,为什么不调用 setBackground(null) ?