一、
在Android开发中,实现具有圆角的UI元素是一项常见的需求,原生的FrameLayout并不直接支持这一特性,幸运的是,有一些开源项目和自定义控件可以解决这个问题,为开发者提供简单易用、性能高效的圆角布局组件,RoundAngleFrameLayout和RCLayout都是优秀的解决方案,本文将详细介绍如何在Android项目中实现圆角布局,包括各种方法的原理和具体实现步骤。
二、相关技术分析
1. RoundAngleFrameLayout
1.1 项目简介
RoundAngleFrameLayout是一个自定义的Android视图,它可以让你轻松地给FrameLayout添加任意角的圆角,而且不会影响到其内部的子视图,通过设置不同的圆角半径,你可以创建出各种复杂而美观的界面效果,而不必编写复杂的代码或者依赖第三方库。
1.2 技术原理
该组件的核心是利用Android的图形绘制API——Paint和Path来实现圆角效果,在onDraw()方法中,RoundAngleFrameLayout创建一个路径对象,根据设定的圆角半径描绘出带圆角的矩形边界,使用Paint对象进行填充和描边,实现了自定义边框和颜色的效果,这种做法既保留了FrameLayout的原有功能,又增加了灵活性,且性能开销相对较小。
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 创建并配置画笔 mBorderPaint.setColor(mBorderColor); mBackgroundPaint.setColor(mBackgroundColor); // 创建路径,描绘带圆角的矩形 Path path = new Path(); path.addRoundRect(rect, radii, Path.Direction.CW); // 绘制边框和背景 canvas.drawPath(path, mBorderPaint); canvas.drawPath(path, mBackgroundPaint); }
1.3 应用场景
设计美感:可以用于创建更具视觉吸引力的登录、注册页面,卡片式展示等。
用户体验:通过平滑的边缘提升应用的整体视觉感受,提高用户的使用体验。
自定义UI:开发者可以根据需要,自由调整每个角落的圆角大小,以满足特定的设计需求。
1.4 特点
高度定制化:允许设置各个角落的不同圆角半径,甚至可以单独控制边框的颜色和宽度。
轻量级:不依赖任何外部库,直接集成到你的项目中即可使用,减少了应用的体积。
兼容性好:支持Android 4.0(API Level 14)及以上版本,覆盖大部分设备。
易于使用:通过简单的属性设置,即可快速实现圆角效果,代码友好。
1.5 上文归纳
如果你是一名Android开发者,正在寻找一个简单、高效的方式来实现圆角布局,那么RoundAngleFrameLayout将是一个理想的选择,它的强大功能、高性能和易用性,将帮助你快速打造精美的UI设计,提升应用的整体品质,现在就尝试将其集成到你的项目中,开启更优质的Android开发之旅吧!
RCLayout
2.1 基本用法
RCRelativeLayout (Round Corner RelativeLayout),使用圆角布局包裹需要圆角的内容然后添加自定义属性即可。
<com.gcssloop.widget.RCRelativeLayout android:padding="20dp" android:layout_width="match_parent" android:layout_height="match_parent" app:round_corner="40dp"> <!--任意View--> <ImageView android:scaleType="centerCrop" android:src="@drawable/test" android:layout_width="match_parent" android:layout_height="match_parent"/> <TextView android:layout_width="match_parent" android:layout_height="50dp" android:background="#aaffffff" android:gravity="center" android:layout_alignParentBottom="true" android:text="圆角测试"/> </com.gcssloop.widget.RCRelativeLayout>
2.2 配置属性
可以在布局文件中配置的属性如下:
round_corner:总体圆角半径,类型为dp。
round_corner_top_left:左上角圆角半径,类型为dp。
round_corner_top_right:右上角圆角半径,类型为dp。
round_corner_bottom_left:左下角圆角半径,类型为dp。
round_corner_bottom_right:右下角圆角半径,类型为dp。
round_as_circle:是否剪裁为圆形,类型为boolean。
stroke_width:描边半径,类型为dp。
stroke_color:描边颜色,类型为color。
2.3 添加方法
添加仓库:在项目的build.gradle文件中配置仓库地址。
添加项目依赖:在需要添加依赖的Module下添加以下信息,使用方式和普通的远程仓库一样。
compile 'com.gcssloop.widget:rclayout:1.4.2@aar'
2.4 属性简介
圆角属性:round_as_circle的权限最高,在默认情况下它的值为false,如果设置这个属性为true,则会忽略圆角大小的数值,剪裁结果均为圆形,设置圆角大小的一共有5个属性,一个是全局的圆角大小round_corner,其余四个round_corner_xx_xx是分别对每一个角进行设置,它们之间存在替代关系,仅设置全局,所有的角都跟随全局,仅对某些角设置,则只有设置过的角会有圆角效果,全局和部分都有设置,则有具体设置的角跟随具体设置的数值,没有具体设置的角跟随全局设置。
描边属性:描边宽度stroke_width默认情况下数值为0,即不存在描边效果,描边颜色stroke_color默认情况下为白色,允许自定义颜色。
三、实现方法详解
1. Shape drawable res/drawable/round_outline.xml
新建一个Shape,指定圆角大小和填充颜色。
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <corners android:radius="100dp"/> <solid android:color="#ff0000"/> </shape>
在需要的布局上指定这个Shape。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="#000000" tools:context=".XmlShapeActivity"> <androidx.cardview.widget.CardView android:layout_width="100dp" android:layout_height="100dp" app:cardCornerRadius="50dp" app:cardElevation="0dp" app:cardUseCompatPadding="false"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/test"/> </androidx.cardview.widget.CardView> <RelativeLayout android:background="@drawable/round_shape" android:layout_width="100dp" android:layout_height="100dp"/> </LinearLayout>
这种方法简单但不够灵活,不能裁剪布局,会导致内部控件超出。
Xfermode
通过Xfermode实现圆角图片或背景。
public class RoundedCornerLayout extends FrameLayout{ private final static float CORNER_RADIUS = 15.0f; private Bitmap maskBitmap; private Paint paint, maskPaint; private float corner; public RoundedCornerLayout(Context context) { super(context); paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG); maskPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG); maskBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ALPHA_8); initMask(); } private void initMask(){ corner = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, CORNER_RADIUS, getResources().getDisplayMetrics()); Canvas canvas = new Canvas(maskBitmap); canvas.translate(corner, corner); canvas.clipPath(new RoundRect((float)0, (float)0, maskBitmap.getWidth() corner, maskBitmap.getHeight() corner, corner, corner, Path.Direction.CW)); canvas.drawColor(0xFFFFFFFF); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.saveLayerAlpha(0xFF, 0xFF, 255); if (maskBitmap != null) { canvas.drawBitmap(maskBitmap, 0, 0, paint); } int sc = canvas.saveLayerAlpha(0xFF, 0xFF, 255); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); super.onDraw(canvas); canvas.restoreToCount(sc); } }
这种方法较为复杂,需要对Android绘制流程熟悉,并且要对每个版本相关的API差异熟悉,否则坑会连续的踩。
CardView
CardView是官方提供的一个控件,使用它需要引入依赖。
implementation 'androidx.cardview:cardview:1.0.0'
然后在布局文件中使用app:cardCornerRadius属性来设置圆角大小。
<androidx.cardview.widget.CardView android:layout_width="100dp" android:layout_height="100dp" app:cardCornerRadius="50dp" app:cardElevation="0dp" app:cardUseCompatPadding="false"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/test"/> </androidx.cardview.widget.CardView>
但是这种方式有坑,在某些版本中可能会导致问题。
4. GradientDrawable和RoundedBitmapDrawable
GradientDrawable可以创建一个带有圆角的drawable。
GradientDrawable drawable = new GradientDrawable(); drawable.setShape(GradientDrawable.RECTANGLE); drawable.setCornerRadius(10); // set the corner radius to desired value drawable.setColor(Color.TRANSPARENT); // set the color to transparent or any other color as needed
RoundedBitmapDrawable可以直接将Bitmap转换为带有圆角的Drawable。
RoundedBitmapDrawable roundedBitmapDrawable = RoundedBitmapDrawableFactory.create(bitmap); roundedBitmapDrawable.setCornerRadius(Math.max(bitmap.getWidth(), bitmap.getHeight()) / 2.0f); // set the corner radius to half of the width or height of the bitmap
这两种方法适用于图片或背景的处理。
5. ViewOutlineProvider
ViewOutlineProvider是Android Lollipop引入的一个接口,可以通过重写getOutline方法来提供自定义的Outline,这通常与Elevation一起使用以实现Material Design的效果,不过这个方法主要用于阴影效果而不是单纯的圆角效果。
class CustomView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : View(context, attrs, defStyleAttr) { init { outlineProvider = object : ViewOutlineProvider { override fun getOutline(view: View, outline: Outline ) { val radius = resources.displayMetrics.density * 10f outline.setRoundRect(0f, 0f, view.width.toFloat(), view.height.toFloat(), radius) } } } }
这种方法主要用于阴影效果而不是单纯的圆角效果,但是它也可以用来处理一些复杂的形状变化需求。
原创文章,作者:未希,如若转载,请注明出处:https://www.kdun.com/ask/1268270.html
本网站发布或转载的文章及图片均来自网络,其原创性以及文中表达的观点和判断不代表本网站。如有问题,请联系客服处理。
发表回复