button按钮、ImageView、自定义View等各种控件或者布局常常需要这样的样式:
下面是多种方式去实现圆角效果(圆角背景或者圆角边框),各有千秋吧:
在drawable文件夹中新建一个shape.xml文件,在其中设置背景颜色和圆角半径即可:
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<!-- 设置背景颜色 -->
<solid android:color="#02B4FE" />
<!-- 设置边框颜色和粗细 -->
<stroke android:color="#02B4FE" android:width="1dp"/>
<!-- 圆角半径 -->
<!-- 统一设置四个角 -->
<corners android:Radius="5dp" />
<!-- 单独设置四个角 -->
<corners
android:topRightRadius="5dp"
android:bottomRightRadius="5dp"
android:topLeftRadius="5dp"
android:bottomLeftRadius="5dp"/>
</shape>
在布局或者控件中设置背景即可:
android:background="@drawable/shape"
特点:一种新的配置就需要重新创建文件,在xml中配置,可以设置背景或者边框,可以单独设置某个角。
Android 5.x引入的新特性,用于实现View的阴影和轮廓
view.setOutlineProvider(new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
// 设置圆角半径为5
outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), 5);
// 设置按钮为圆形
outline.setOval(0, 0, view.getWidth(), view.getHeight());
}
});
view.setClipToOutline(true);
特点:不需要新建文件,在java中配置,不能单独设置某个角。
CardView嵌套view可以实现阴影和圆角,通过cardCornerRadius设置圆角半径,cardElevation设置阴影
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height=""
app:cardCornerRadius="5dp"
app:cardElevation="0dp"
app:cardUseCompatPadding="false">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.cardview.widget.CardView>
特点:不需要新建文件,在xml中配置,不能单独设置某个角。
这里以Glide为例,在Glide中设置圆角可以使用transform()方法应用 RoundedCorners / GranularRoundedCorners 转换
// 设置圆角半径为10dp
int radius = 10;
//统一设置4个角
RequestOptions options = new RequestOptions().transform(new RoundedCorners(radius));
//单独设置某个角
RequestOptions options = new RequestOptions().transform(new GranularRoundedCorners(radius, radius, radius, radius));
// 在ImageView上显示圆角图片
Glide.with(context)
.load(imageUrl)
.apply(options)
.into(imageView);
特点:不需要新建文件,需要导入第三方包,在java中配置,可以单独设置某个角。
GradientDrawable:
// 设置圆角半径为10dp
int radius = 10;
//同时设置四个角
GradientDrawable drawable = new GradientDrawable();
drawable.setShape(GradientDrawable.RECTANGLE);
drawable.setCornerRadius(radius);
drawable.setColor(0xFFE1F5ED);
imageView.setImageDrawable(drawable);
//单独设置四个角
GradientDrawable drawable = new GradientDrawable();
drawable.setShape(GradientDrawable.RECTANGLE);
drawable.setColor(0xFFE1F5ED);
float[] rad = new float[]{
radius, radius,
0f, 0f,
0f, 0f,
radius, radius
};
drawable.setCornerRadii(rad);
imageView.setImageDrawable(drawable);
RoundedBitmapDrawable:通过RoundedBitmapDrawableFactory创建RoundedBitmapDrawable,第二个参数可以传入Bitmap(可将drawable文件转成Bitmap)、filepath、InputStream三种
RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory.create(getResources(),...);
drawable.setCornerRadius(radius);
imageView.setImageDrawable(drawable);
特点:不需要新建文件,在java中配置,GradientDrawable可以单独设置某个角,RoundedBitmapDrawable不能单独设置。
可以将这两种运用在自定义View或者Button中去·自定义控件的属性,弥补了使用shape元素的缺点,当项目中需要很多不同的样式时,只需要修改对应的属性值。
新建RoundRectDrawable类,实现Drawable抽象方法,用画笔绘制draw圆角背景(圆角边框也类似)
import android.graphics.*
import android.graphics.drawable.Drawable
class RoundRectDrawable() : Drawable() {
private val paint = Paint()
private val path = Path()
private lateinit var rect: RectF
private var radius: FloatArray = floatArrayOf(
0f, 0f,
0f, 0f,
0f, 0f,
0f, 0f
)
init {
paint.isAntiAlias = true
paint.isDither = true
}
constructor(color: Int, radius: FloatArray) : this() {
this.radius = radius
paint.color = color
}
constructor(color: Int, radius: Float) : this(
color, floatArrayOf(
radius, radius,
radius, radius,
radius, radius,
radius, radius
)
)
constructor(color: Int) : this(
color, floatArrayOf(
0f, 0f,
0f, 0f,
0f, 0f,
0f, 0f
)
)
override fun setBounds(left: Int, top: Int, right: Int, bottom: Int) {
super.setBounds(left, top, right, bottom)
rect = RectF(
left.toFloat(),
top.toFloat(),
right.toFloat(),
bottom.toFloat()
)
}
override fun draw(canvas: Canvas) {
path.addRoundRect(
rect,
radius,
Path.Direction.CW
)
canvas.drawPath(path, paint)
}
override fun setAlpha(alpha: Int) {
paint.alpha = alpha
invalidateSelf()
}
override fun setColorFilter(colorFilter: ColorFilter?) {
paint.colorFilter = colorFilter
invalidateSelf()
}
override fun getOpacity(): Int {
return PixelFormat.TRANSLUCENT
}
}
在自定义View中使用:设置background属性
AppCompatTextView(context).apply {
setTextColor(0xFF06CB7C.toInt())
background = RoundRectDrawable(0xFFE1F5ED.toInt(), 5)
text = ""
}
特点:在java中配置,一次配置多次使用,可以单独设置某个角(这里是统一设置)