以编程方式将样式应用于MaterialButton

时间:2018-09-19 08:42:46

标签: android material-design

我正在尝试创建一个自MaterialButton扩展的自定义视图,并在代码中应用样式,因此我不需要在xml中进行操作。

class CustomRedButton @JvmOverloads constructor(
    context: Context, 
    attrs: AttributeSet? = null, 
    defStyleAttr: Int = 0
) : MaterialButton(ContextThemeWrapper(context, R.style.ButtonRedStyle), attrs, defStyleAttr) 

样式是:

<style name="ButtonRedStyle" 
    parent="Widget.MaterialComponents.Button.TextButton">
    <item name="backgroundTint">@color/red</item>
    <item name="rippleColor">@color/grey</item>
    <item name="strokeWidth">1dp</item>
    <item name="strokeColor">@color/black</item>
</style>

一切正常,但拥有backgroundTint属性。由于某种原因,背景颜色没有改变,并且具有主题的原色。但是,如果我尝试将样式应用于xml中的MaterialButton,则确实会更改颜色。

有什么想法为什么会发生或者我如何实现?

4 个答案:

答案 0 :(得分:4)

我也面临着同样的问题。到目前为止,我发现的唯一解决方法是以编程方式将色调设置为:

$questions = array();
$answers = array();
while ($row = $queryFaq->fetch(PDO::FETCH_ASSOC)) 
{
    $questions[] = $row['text']
    $answers[] = $row['id_answer'];
}

$answer = reset($answers);
foreach($questions as $question)
{
  echo 'Question: ' . sanitize($question);
  echo 'Answer:' . sanitize($answer);
  $answer = next($answers);
}

答案 1 :(得分:4)

使用

MaterialButton(ContextThemeWrapper(context, R.style.ButtonRedStyle), attrs, defStyleAttr)

您要对默认样式应用 themeoverlay ,而不是应用其他样式。

这意味着:

<style name="ButtonRedTheme" parent="...">
    <item name="colorPrimary">@color/...</item>
    <item name="colorOnPrimary">@color/...</item>
    <item name="colorSecondary">@color/...</item>
</style>

如果要应用不同的样式,则必须:

  • attrs.xml中定义自定义属性
    <attr name="myButtonStyle" format="reference"/>
  • 在您的应用主题中为此属性添加样式:
   <style name="AppTheme" parent="Theme.MaterialComponents.DayNight">
        <item name="myButtonStyle">@style/CustomButtonStyle</item>
   </style>
  • 定义自定义样式:
    <style name="CustomButtonStyle" parent="Widget.MaterialComponents.Button.*">
        <item name="backgroundTint">@color/...</item>
        <item name="rippleColor">@color/grey</item>
        <item name="strokeWidth">1dp</item>
        <item name="strokeColor">@color/black</item>
    </style>

最终使用:

val customButton = MaterialButton(context, null, R.attr.myButtonStyle)

答案 2 :(得分:0)

如果要更改 CustomView 的样式,则必须将其传递给第三个参数 defStyleAttr 来将其传递给构造函数像这样:

class CustomRedButton @JvmOverloads constructor(
    context: Context, 
    attrs: AttributeSet? = null, 
    defStyleAttr: Int = R.style.ButtonRedStyle // Just default style like this
) : MaterialButton(context, attrs, defStyleAttr)

您可以像这样以编程方式对其进行初始化

CustomRedButton(this, null, R.style.ButtonRedStyle) // Initialization, ('this' is context)

有关更多详细信息,请参见here

答案 3 :(得分:0)

对于TextButton,不应有背景(仅文本具有颜色)。对于彩色按钮,应使用默认的填充按钮样式,即Widget.MaterialComponents.Button

并且当用作主题时,按钮使用不同的属性。在主题属性映射部分中进行了描述:https://material.io/develop/android/components/material-button/

Filled button
+------------------------+-----------------------------------------+
| Component Attribute    | Default Theme Attribute Value           |
+------------------------+-----------------------------------------+
| android:textAppearance | textAppearanceButton                    |
| android:textColor      | colorOnPrimary                          |
| iconTint               | colorOnPrimary                          |
| rippleColor            | colorOnPrimary at 32% opacity (pressed) |
| iconTint               | colorOnPrimary                          |
| backgroundTint         | colorPrimary                            |
| ...                    | ...                                     |
+------------------------+-----------------------------------------+

在您的情况下,主题应类似于:

<style name="ButtonRedTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
    <item name="colorPrimary">@color/red</item>
    <item name="colorOnPrimary">@color/white</item>
    <item name="colorOnSurface">@color/black</item>
</style>

您还可以使用以下方法将所有按钮更改为特定样式:

<item name="materialButtonStyle">@style/ButtonRedTheme</item>

在您的应用主题中。