问题描述
我一直在研究自定义“按钮”,到目前为止,它的工作与我想要的一样。但是,我试图将文本而不是可绘制对象添加到按钮上(这是我之前所做的)。
当前,我在declare-styleable
文件中使用了attrs.xml
,如下所示:
<?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>
除此之外,我还有随附的课程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,(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,Path.Direction.ccw);
canvas.clipOutPath(path);
path.rewind();
path.addRoundRect(0f,((float) getWidth()),((float) getHeight()),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>
我尝试将android:text
添加到attrs.xml
文件中,但是没有显示出来,我也不明白为什么会这样。
提前谢谢!
解决方法
自定义视图扩展AppCompatImageButton
时,文本不会显示。 AppCompatImageButton
仅显示图像。
public class StyledButton extends AppCompatImageButton {
如果您需要一个用于显示文本的按钮,请考虑使用两个自定义视图,一个用于图像,另一个用于文本。
StyledImageButton :
public class StyledImageButton extends AppCompatImageButton {
StyledButton
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>