如何清理这些复杂的按钮?

How can I clean up these complex buttons?

我们有一个 Android 应用程序,它的视图顶部有一排按钮。该行中的三个按钮中的每一个都由一个圆圈内的图标和圆圈下方描述它的文本组成(类似于这个线框,虽然我随机选择了图标,因为我不允许分享实际的图标):

最初,这些按钮设计有图标、圆形背景和圆形边框作为光栅图像(具有多种密度,根据需要)和以下代码(重复三次,每个按钮一次):

<LinearLayout
    android:id="@+id/button1"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_gravity="center_vertical"
    android:layout_weight="1"
    android:gravity="center"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/button1Image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent"
        android:clickable="false"
        android:contentDescription="@string/button1Text"
        android:src="@drawable/button1Image" />

    <TextView
        android:id="@+id/txtButton1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="3dp"
        android:text="@string/button1Text"
        android:textColor="@android:color/white"
        android:textSize="14sp" />
</LinearLayout>

我被赋予了使这段代码现代化的任务,因为我们使用的图标实际上都是最初的矢量图标(来自 Material 设计库),我们应该能够只使用矢量和无需担心光栅化和像素密度。

我想做的是从图标本身删除圆圈(这样我就可以使用 Material 矢量图标而不修改它们)并让按钮背景添加圆圈。 (这也让我可以根据应用变体更改圆圈的颜色,而无需使用许多不同的图像集。)

我看过很多关于如何制作一个带有图标和文本的圆形按钮的例子,但我似乎无法弄清楚如何制作一个看起来像我想要的样子的按钮。

如何制作一个漂亮的可重用组件,它采用矢量图标和文本并为每个按钮提供此布局?


澄清:我想在这里做的是从图标中删除圆圈并将圆圈作为按钮的背景。我知道我可以用两个按钮来做到这一点,一个用于没有背景的文本,一个用于有背景的图像,但我想知道是否有一种方法可以用一个 XML 标签来做到这一点,因为我有一大堆。

您可以使用按钮并使用android:drawableTop="@drawable/icon"设置按钮图标。

完整代码如下:

<Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:background="@android:color/transparent"
        android:drawableTop="@drawable/ic_launcher_background"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

已更新: 在这种情况下,您可以做的是创建自定义组件并从那里设置顶部图标。以下是我尝试过并且有效的步骤:

  1. res/values folder 中创建 attrs.xml 文件并将 topIcon 作为属性名称:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <attr name="topIcon" format="reference" />
    
        <declare-styleable name="CustomButton">
            <attr name="topIcon" />
        </declare-styleable>
    </resources>
    
  2. 创建 CustomButton class 并使用 LayerDrawable:

    添加圆形可绘制对象作为背景层
    public class CustomButton extends Button {
        public CustomButton(Context context, AttributeSet attrs) {
            super(context, attrs);
            if (attrs != null) {
                TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomButton);
                Drawable topIcon = typedArray.getDrawable(R.styleable.CustomButton_topIcon);
    
                LayerDrawable layerDrawable = new LayerDrawable(
                        new Drawable[]{getResources().getDrawable(R.drawable.circle), topIcon}
                );
    
                setCompoundDrawablesWithIntrinsicBounds(null, layerDrawable, null, null);
                typedArray.recycle();
            }
        }
    }
    
  3. 使用布局文件中创建的组件并设置 topIcon 属性。此外,当我们扩展 Button class 时,您可以使用它的任何其他属性。确保包名称正确:

       <com.natigbabayev.experimental.CustomButton
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Hello World!"
                app:topIcon="@android:drawable/ic_input_add"/>
    

使用Material Button;例如:

<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <com.google.android.material.button.MaterialButton
        style="@style/Widget.MaterialComponents.Button.Icon"
        android:text="@string/text_button_delete"
        android:layout_width="wrap_content"
        android:layout_height="148dp"
        android:elevation="4dp"
        android:textSize="18sp"
        app:cornerRadius="80dp"
        app:icon="@drawable/ic_delete_black_36dp"
        app:iconPadding="6dp"/>

</layout>