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

14
请告诉我如何将自定义按钮的默认背景设置为null。
我的意思是... 我知道我可以定义一个“style”,将android:background设置为“@null”,并要求用户在其布局中明确应用该样式。例如:
<style name="MyButton" parent="@android:style/Widget.Button">
    <item name="android:background">@null</item>
</style>

<com.xxx.widget.MyButton
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    style="@style/MyButton"
    android:text="MyButton" />
上述代码运行良好。但是我该如何在我的类"MyButton"内部应用这种样式,而让用户不必显式地设置样式呢?
例如,如何使以下布局像以前一样工作:
<com.xxx.widget.MyButton
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="MyButton" />

我尝试在构造函数中按如下方式执行此操作,但它不起作用。

public MyButton(Context context, AttributeSet attrs) {
    this(context, attrs, com.xxx.R.style.MyButton);
}

附注:我希望在用户没有明确设置背景时应用这个"null"背景。


我认为你应该更改问题的标题。你可以始终拥有一个默认样式,但稍后可以更改。也许你需要说“最终样式”或类似的东西。 - ikbal
1
请参考https://dev59.com/F2855IYBdhLWcg3wKxHc,了解一些相关提示。 - Steve Pomeroy
有类似的需求:https://dev59.com/h43da4cB1Zd3GeqPwCyQ#31505624 - stefan
3个回答

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

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

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

现在我们可以像这样在布局XML文件中使用自定义视图:
<com.xxx.MyTextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

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

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


这对我有用,谢谢您先生。 - Stack Diego
不应该使用默认参数生成构造函数(即this(context, attrs, 0)),因为0将解析为意外的样式。去掉0即可。 - masterwok

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

-2

这更或多或少是一种廉价的方法,但为什么不将背景设置为透明的正方形呢?就像这样 ->

transparent_square.xml:(将其放入drawable目录中)

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/square"
    android:>

    <solid android:color="#00808080"></solid> // The first two zeros set the alpha
                                              // to 0

</shape>

然后将按钮的背景设置为您的可绘制对象。

按钮:

<Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Send"
        android:id="@+id/sendButton"
        android:layout_weight="1"
        android:background="@drawable/transparent_square"/>

抱歉,我认为这并没有回答问题。@Henry正在询问如何在不在Button的xml中指定的情况下默认执行此操作。 - Smeagol

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接