【问题标题】:Programmatically create three MaterialButtons with styling and constraintlayout chaining以编程方式创建三个具有样式和约束布局链接的 MaterialButton
【发布时间】:2019-12-18 12:00:08
【问题描述】:

所以我的初始布局是这样的:

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/white"
            android:orientation="horizontal"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent">

            <androidx.constraintlayout.widget.ConstraintLayout
                android:id="@+id/holder"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="@dimen/margin_padding_size_small">

                <com.google.android.material.button.MaterialButton
                    android:id="@+id/btn_cod"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:paddingStart="@dimen/margin_padding_size_small"
                    android:paddingEnd="@dimen/margin_padding_size_small"
                    android:text="@string/cash_on_delivery_label"
                    app:cornerRadius="@dimen/card_corner_radius_medium"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintEnd_toStartOf="@+id/btn_card"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent"
                    tools:text="@string/cash_on_delivery_label" />

                <com.google.android.material.button.MaterialButton
                    android:id="@+id/btn_card"
                    style="@style/Widget.MaterialComponents.Button.OutlinedButton"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:paddingStart="@dimen/margin_padding_size_small"
                    android:paddingEnd="@dimen/margin_padding_size_small"
                    android:text="@string/card_label"
                    app:cornerRadius="@dimen/card_corner_radius_medium"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintEnd_toStartOf="@+id/btn_qr_scan"
                    app:layout_constraintStart_toEndOf="@+id/btn_cod"
                    app:strokeColor="@color/colorAccent"
                    tools:text="@string/card_label" />

                <com.google.android.material.button.MaterialButton
                    android:id="@+id/btn_qr_scan"
                    style="@style/Widget.MaterialComponents.Button.OutlinedButton"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:paddingStart="@dimen/margin_padding_size_small"
                    android:paddingEnd="@dimen/margin_padding_size_small"
                    android:text="@string/qr_scan_label"
                    app:cornerRadius="@dimen/card_corner_radius_medium"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toEndOf="@+id/btn_card"
                    app:strokeColor="@color/colorAccent"
                    tools:text="@string/qr_scan_label" />


            </androidx.constraintlayout.widget.ConstraintLayout>


        </LinearLayout>

我很早就做了一个假设,我将根据从服务器收到的响应为按钮设置style 属性。但是Android Framework没有setStyle()方法。

所以我必须找到其他方法来做到这一点。我搜索并发现 Paris 库确实允许我们设置样式,但它目前不适用于 MaterialComponents。

我尝试使用 MaterialButtonToggleGroup,但包含依赖项会完全弄乱 DataBinding,并在应用程序的其他模块中显示错误。

我目前的方法是动态创建所有三个按钮并将它们填充到 ConstraintLayout 中,这将是我的根布局。

我如何以编程方式使用约束和链来填充这三个按钮。

我一直在尝试:

        val constraintSet = ConstraintSet()
//        constraintSet.clone(holder) // do I need this? 
        //holder is the id of the constraint layout from xml

        val codButton = MaterialButton(this, null, R.attr.materialButtonStyle)
        codButton.text = resources.getString(R.string.cash_on_delivery_label)
        codButton.id = generateViewId()
        codButton.setCornerRadiusResource(R.dimen.card_corner_radius_medium)
        holder.addView(codButton)

        val cardButton = MaterialButton(this, null, R.attr.borderlessButtonStyle)
        cardButton.text = resources.getString(R.string.card_label)
        cardButton.id = generateViewId()
        cardButton.setCornerRadiusResource(R.dimen.card_corner_radius_medium)
        cardButton.setStrokeColorResource(R.color.colorAccent)
        holder.addView(cardButton)

        val qrButton = MaterialButton(this, null, R.attr.borderlessButtonStyle)
        qrButton.text = resources.getString(R.string.qr_scan_label)
        qrButton.id = generateViewId()
        qrButton.setCornerRadiusResource(R.dimen.card_corner_radius_medium)
        qrButton.setStrokeColorResource(R.color.colorAccent)
        holder.addView(qrButton)

        //constraintSet.connect() calls?

        constraintSet.applyTo(holder)

请告诉我实现这一目标的最佳方法。要求是对于来自服务器的任何响应,三个按钮中的两个应设置为材质组件的轮廓按钮,一个设置为材质组件的常规按钮。

另一个问题是:我无法使用R.attr.materialButtonOutlinedStyle(未解析的符号)但我可以使用R.attr.materialButtonStyle;这是为什么呢?

【问题讨论】:

  • 你试过直接指定样式吗?或将 R.attr.materialButtonOutlinedStyle 更改为 R.style.materialButtonOutlinedStyle ?也看看这个链接也许会有所帮助:stackoverflow.com/questions/26346727/…
  • 直接指定样式是什么意思?没有在视图上设置样式的方法。将 attr 更改为 style 对我没有任何作用。您提供的链接讨论了 AppCompat 按钮。我需要具有cornerRadius 和轮廓样式的材质按钮。
  • 你用的是哪个版本的材质库?
  • 您可以在 xml 布局中使用 Outlined 样式定义 MaterialButton。然后以编程方式执行以下操作:(MaterialButton) getLayoutInflater().inflate(R.layout.my_button, buttonGroup, false);
  • @GabrieleMariotti 假设我这样做是为了让按钮膨胀,我将如何保持它们在约束布局根中的位置?

标签: android material-design android-constraintlayout


【解决方案1】:

我最终做的是:

  1. 创建样式:
<!-- Outline Button Style -->
    <style name="ThemeOverlay.MyApp.OutlinedButton" parent="">
        <item name="materialButtonStyle">@style/Widget.MaterialComponents.Button.OutlinedButton</item>
    </style>
  1. 动态生成三个按钮集。使用ContextThemeWrapper 将上述样式应用于按钮。并设置约束以水平链接它们。
        val constraintSet = ConstraintSet()

        //construct COD button
        val codButton = MaterialButton(this, null, R.attr.materialButtonStyle)
        codButton.text = resources.getString(R.string.cash_on_delivery_label)
        codButton.id = generateViewId()
        codButton.setCornerRadiusResource(R.dimen.card_corner_radius_medium)
        holder.addView(codButton)

        //construct card button
        val cardButton =
            MaterialButton(ContextThemeWrapper(this, R.style.ThemeOverlay_MyApp_OutlinedButton))
        cardButton.text = resources.getString(R.string.card_label)
        cardButton.id = generateViewId()
        cardButton.isClickable = false
        cardButton.setCornerRadiusResource(R.dimen.card_corner_radius_medium)
        cardButton.setStrokeColorResource(R.color.colorAccent)
        holder.addView(cardButton)


        //construct qr button
        val qrButton =
            MaterialButton(ContextThemeWrapper(this, R.style.ThemeOverlay_MyApp_OutlinedButton))
        qrButton.text = resources.getString(R.string.qr_scan_label)
        qrButton.id = generateViewId()
        qrButton.isClickable = false
        qrButton.setCornerRadiusResource(R.dimen.card_corner_radius_medium)
        qrButton.setStrokeColorResource(R.color.colorAccent)
        holder.addView(qrButton)

        constraintSet.clone(holder)

        // constraints for the cod button
        constraintSet.connect(
            codButton.id,
            ConstraintSet.START,
            ConstraintSet.PARENT_ID,
            ConstraintSet.START
        )
        constraintSet.connect(codButton.id, ConstraintSet.END, cardButton.id, ConstraintSet.START)

        // constraints for the card button
        constraintSet.connect(cardButton.id, ConstraintSet.START, codButton.id, ConstraintSet.END)
        constraintSet.connect(cardButton.id, ConstraintSet.END, qrButton.id, ConstraintSet.START)

        // constraints for the qr scan
        constraintSet.connect(qrButton.id, ConstraintSet.START, cardButton.id, ConstraintSet.END)
        constraintSet.connect(
            qrButton.id,
            ConstraintSet.END,
            ConstraintSet.PARENT_ID,
            ConstraintSet.END
        )

        constraintSet.applyTo(holder)

【讨论】:

  • 使用1.1.0 版本的材质组件库,您可以在默认主题中使用materialButtonOutlinedStyle 属性。然后使用构造函数new MaterialButton(context, null, R.attr.materialButtonOutlinedStyle);
猜你喜欢
  • 2019-06-01
  • 2012-10-01
  • 2019-02-06
  • 2015-10-17
  • 2018-04-08
  • 2022-07-08
  • 2017-01-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多