自定义声明样式不显示文本属性

Custom declare-styleable not displaying text attribute

我一直在研究自定义“按钮”,到目前为止它的工作方式与我希望的一样。但是,我正在尝试向按钮而不是可绘制对象添加文本(这是我之前所做的)。

目前我在 attrs.xml 文件中使用了 declare-styleable,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- Custom attributes for the button -->
    <declare-styleable name="StyledButton">
        <attr name="cornerRadius" format="dimension" />
        <attr name="borderWidth" format="dimension" />
        <attr name="startColor" format="color" />
        <attr name="centerColor" format="color" />
        <attr name="endColor" format="color" />
    </declare-styleable>
</resources>

除此之外,我还有 class StyledButton.java :

package com.example.test;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.graphics.Path;
import android.graphics.Paint;
import android.graphics.LinearGradient;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatImageButton;

public class StyledButton extends AppCompatImageButton {

    private float cornerRadius = 0f;
    private float borderWidth = 0f;
    private int startColor = 0;
    private int centerColor = 0;
    private int endColor = 0;

    private Path path = new Path();
    private Paint borderPaint = new Paint();

    {
        borderPaint.setStyle(Paint.Style.FILL);
    }

    public StyledButton(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs, 0);

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.StyledButton);

        try {
            cornerRadius = a.getDimension(R.styleable.StyledButton_cornerRadius, 10f);
            borderWidth = a.getDimension(R.styleable.StyledButton_borderWidth, 10f);
            startColor = a.getColor(R.styleable.StyledButton_startColor, getResources().getColor(R.color.colorPrimaryDark, context.getTheme()));
            centerColor = a.getColor(R.styleable.StyledButton_centerColor, getResources().getColor(R.color.colorAccent, context.getTheme()));
            endColor = a.getColor(R.styleable.StyledButton_endColor, Color.WHITE);
        }
        finally {
            a.recycle();
        }

    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        borderPaint.setShader(new LinearGradient(0f, 0f, 0f, (float) getHeight(), new int[] {startColor, centerColor, endColor}, null, Shader.TileMode.CLAMP));
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        path.rewind();
        path.addRoundRect(borderWidth, borderWidth, ((float) getWidth()) - borderWidth, ((float) getHeight()) - borderWidth, cornerRadius - borderWidth / 2, cornerRadius - borderWidth / 2, Path.Direction.CCW);
        canvas.clipOutPath(path);
        path.rewind();
        path.addRoundRect(0f, 0f, ((float) getWidth()), ((float) getHeight()), cornerRadius, cornerRadius, Path.Direction.CCW);
        canvas.drawPath(path, borderPaint);
    }
}

我正在尝试在自定义对话框中使用这些来通过以下代码获取用户输入:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:elevation="5dp">

    <androidx.cardview.widget.CardView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:cardCornerRadius="20dp">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:background="@drawable/background_gradient"
            android:padding="10dp">

            <TextView
                android:layout_width="300dp"
                android:layout_height="wrap_content"
                android:scaleType="center"
                android:text="@string/app_name"
                android:textAlignment="center"
                android:fontFamily="@font/lato_bold"
                android:textSize="36sp"
                android:padding="10dp"
                android:textColor="@android:color/white" />

            <EditText
                android:id="@+id/player_name_dialog_name"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="16dp"
                android:layout_marginLeft="4dp"
                android:layout_marginRight="4dp"
                android:layout_marginBottom="4dp"
                android:hint="@string/player_name_hint"
                android:textAlignment="center"/>

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="40dp"
                android:orientation="horizontal"
                android:layout_gravity="center"
                android:layout_marginTop="10dp">

                <com.example.test.StyledButton
                    android:id="@+id/player_name_dialog_confirm_button"
                    android:layout_weight="1"
                    android:layout_height="match_parent"
                    android:layout_width="120dp"
                    android:scaleType="center"
                    android:layout_gravity="center"
                    app:startColor="@color/colorPrimaryDark"
                    app:centerColor="@color/colorPrimary"
                    app:endColor="@color/colorAccent"
                    app:borderWidth="2dp"
                    app:cornerRadius="20dp"
                    android:text="@string/cancel"
                    android:textColor="@android:color/white"
                    android:textSize="20sp"
                    android:fontFamily="@font/lato"
                    android:layout_marginHorizontal="10dp"
                    android:onClick="deletePlayerButtonClick"/>

                <com.example.test.StyledButton
                    android:id="@+id/add_players_activity_delete_button"
                    android:layout_weight="1"
                    android:layout_height="match_parent"
                    android:layout_width="120dp"
                    android:scaleType="center"
                    android:layout_gravity="center"
                    app:startColor="@color/colorPrimaryDark"
                    app:centerColor="@color/colorPrimary"
                    app:endColor="@color/colorAccent"
                    app:borderWidth="2dp"
                    app:cornerRadius="20dp"
                    android:layout_marginHorizontal="10dp"
                    android:onClick="deletePlayerButtonClick"/>

            </LinearLayout>
        </LinearLayout>
    </androidx.cardview.widget.CardView>
</RelativeLayout>

我已经尝试在 attrs.xml 文件中添加 android:text,但是没有显示,我不明白为什么会这样。

提前致谢!

随着自定义视图扩展 AppCompatImageButton,文本将不会显示。 AppCompatImageButton 只显示一张图片。

public class StyledButton extends AppCompatImageButton {

如果您需要一个显示文本的按钮,请考虑使用两个自定义视图,一个用于图像,另一个用于文本。

StyledImageButton:

public class StyledImageButton extends AppCompatImageButton {

样式按钮

public class StyledButton extends AppCompatButton {

其余代码可以保持不变。

注意:Android 不会让您在 attrs.xml 中创建重复的属性。创建全局属性并重用它们。像这样:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="cornerRadius" format="dimension" />
    <attr name="borderWidth" format="dimension" />
    <attr name="startColor" format="color" />
    <attr name="centerColor" format="color" />
    <attr name="endColor" format="color" />

    <declare-styleable name="StyledButton">
        <attr name="cornerRadius" />
        <attr name="borderWidth" />
        <attr name="startColor" />
        <attr name="centerColor" />
        <attr name="endColor" />
    </declare-styleable>

    <declare-styleable name="StyledImageButton">
        <attr name="cornerRadius" />
        <attr name="borderWidth" />
        <attr name="startColor" />
        <attr name="centerColor" />
        <attr name="endColor" />
    </declare-styleable>
</resources>