Android实现圆角控件
在Android开发过程中,控件的使用是最常见、最基本的。但是我们都知道,在Android中的控件都是矩形的,而在实际项目中,我们的UI设计师经常会使用一些圆角的控件。那么,在Android有哪些方式可以实现圆角控件了,在使用和适配的过程当中,又有哪些问题了。下面,我将介绍Android中常见的实现圆角方式。
自定义方式实现圆角:
常见实现方式
- 使用背景图片
- 使用shape方式
- 使用CardView控件
- 使用ViewOutlineProvider裁剪View
-
使用自定义控件
- 使用Canvas 的 clipXxx() 系列方法
- 通过自定义 Drawable 实现
使用背景图片
有圆角的设计时,让设计师给我们一张圆角背景的切图,然后将圆角切图作为控件的背景设置上去,那么控件在显示时就成圆角了;但是使用这种方式时,不同的圆角大小、四个角中可能并不是都有圆角或者圆角大小不一样时,需要动态修改背景时,都需要使用不同的图片,并且每次调整都需要重新切图和替换,那么设计师的工作量就大了很多,而且apk的体积就会增大很多。所以在实际中基本上不使用这种方式实现圆角,也不推荐使用。
使用shape方式
使用shape的方式实现圆角,这应该是我们在平时使用的最多的一种方式了,通过一个xml文件实现,然后直接将这个xml文件作为控件的背景即可。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="5dp"/>
<solid android:color="#FF0000" />
</shape>
通过以上方式我们就实现了一个背景为红色、四个圆角都为5dp的圆角背景图,然后直接将这个文件作为 android:background
的属性值即可。这种方式在创建和使用的过程都很简单;而且占用的空间也很小,在实际的项目中使用很普遍(shape还有其他的很多属性、包括边框、渐变等)。但是,通过shape的方式实现圆角也有这一些问题,就是对于不同的背景颜色、圆角大小、四个角圆角不一致时,需要定义多个shape文件,而且在有多人开发并且项目没有很好的规范时,可能还会导致同一种背景样式的shape被重复创建;甚至同一个人对于同一种类型的shape都重复创建,从而导致shape文件很多,而且很混乱,不好维护与管理。所以在使用这种方式的时候一定需要有一个规范,并且需要每一个开发者都严格按照规范来。
使用CardView控件
CardView 是在Android5.0推出的一个控件(在使用时需要添加依赖),继承自FrameLayout,可以让我们使用类似卡片布局来显示一致性效果的内容。同时卡片还可以包含圆角和阴影效果。
CardView 控件属性:
app:cardBackgroundColor这是设置背景颜色
app:cardCornerRadius这是设置圆角大小
app:cardElevation这是设置z轴的阴影
app:cardMaxElevation这是设置z轴的最大高度值
app:cardUseCompatPadding是否使用CompatPadding
app:cardPreventCornerOverlap是否使用PreventCornerOverlap
app:contentPadding 设置内容的padding
app:contentPaddingLeft 设置内容的左padding
app:contentPaddingTop 设置内容的上padding
app:contentPaddingRight 设置内容的右padding
app:contentPaddingBottom 设置内容的底padding
阴影:在Android5.0及以上设置控件阴影可以通过 elevation
属性或者 translationZ
属性控制。(elevation 是静态值,是View在Z轴上的初始值;translationZ是动态值,是Z上的偏移变化。Z轴阴影: Z = elevation + translationZ)
使用CardView实现控件圆角,因为CardView继承至FrameLayout,所以作为直接父布局时只能实现相对简单的样式,而如果我们需要实现类似 RelativeLayout 的布局话,那么我们还是只能使用 RelativeLayout ,然后将CardView嵌套在外面;另外直接使用CardView,是无法单独指定某个或两个角是直角,其他是圆角的。
使用ViewOutlineProvider裁剪View
在Android5.0及以上系统,实现圆角我们又多了一种方式,那就是使用 ViewOutlineProvider 的方式,这种方式通过代码指定我们的控件形状,基本用法;
view.setClipToOutline(true);
view.setOutlineProvider(new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
outline.setRoundRect(0,0,view.getWidth(),view.getHeight(),5);
}
});
通过outline.setRoundRect()
方法,我们将控件设置成圆角, outline
还有其他的方法 setRect()
、 setOval()
、setConvexPath()
方法指定不同的形状,通过 setConvexPath()
我们还可以指定一个凸路径(ConvexPath 这里简单理解为 圆角矩形的圆角度数大于矩形的高度或宽度(上下圆角度数的边长和大于高度或者左右圆角度数的边长大于高度,那么就不是 ConvexPath 了))。在Android5.0以上使用这种方式实现圆角也是可以的。但是使用这种方式也有一些缺点,就是必须是Android5.0以上系统,另外一点就是需要在代码中进行设置,不能在xml文件中指定。
使用自定义控件
通过自定义控件的方式实现圆角或者其他的形状,使用这种方式灵活性高,没有版本限制。但是他最为明显的缺点就是需要自己实现自定义控件,起初阶段比较麻烦。而通过自定义控件实现也有多种方式,这里我主要介绍两种:裁剪画布和通过自定义Drawable作为控件背景形式。
-
使用Canvas 的 clipXxx() 系列方法
通过 Canvas 的
canvas.clipRect()
、canvas.clipPath()
等系列方法对画布进行裁剪来实现圆角控件,大家都知道Android控件显示都是通过画布(Canvas)来呈现的,那么我们直接把画布裁剪掉了,自然绘制在画布上的内容也就被裁剪掉了,而画布被裁剪成什么形状了,最终显示的肯定也就是这种形状。@Override public void draw(Canvas canvas) { canvas.clipRect(rectF); super.draw(canvas); }
使用这种方式有一个问题,那就是锯齿比较明显,我们都知道在使用画笔进行绘制的时候,都会这是画笔的抗锯齿效果,但是canvas的clip系列方法并没有这个功能,这就导致了我们通过这种方式实现自定义的圆角锯齿效果比较明显。对界面要求比较高的话,可能会不能通过。
-
通过自定义 Drawable 实现
既然通过直接裁剪画布有锯齿效果,而我们上面说过通过shape的方式实现是比较常见的,而且是有很好的抗锯齿效果,但是需要创建多个shape文件实现不同的圆角和颜色。那么,我们能不能将创建shape的过程通过代码的形式创建,然后在自定义控件中进行使用,并且将圆角参数、颜色参数、边框参数通过自定义控件的属性进行定义了。这样一来,我们就既省去了需要创建多个shape文件的问题,也解决了锯齿的问题。我们通过自定义Drawable的方式,对自定义的属性通过画笔、路径等形式绘制到自定的Drawable中,然后将自定义的Drawable作为控件的背景就实现了这个功能。自定义Drawable代码,通过自定义Drawable实现的可指定圆角大小、边框属性的RadiusFrameLayout。点击查看更多圆角控件