Android自定义View实现带4圆角或者2圆角的效果
作者:chen yu 发布时间:2023-04-08 04:32:10
标签:android,自定义,view,圆角
1 问题
实现任意view经过自定义带4圆角或者2圆角的效果
2 原理
1) 实现view 4圆角
我们只需要把左边的图嵌入到右边里面去,最终显示左边的图就行。
2) 实现view上2圆角
我们只需要把左边的图嵌入到右边里面去,最终显示左边的图就行。
安卓源码里面有这样的类
package android.graphics;
/**
* <p>Specialized implementation of {@link Paint}'s
* {@link Paint#setXfermode(Xfermode) transfer mode}. Refer to the
* documentation of the {@link PorterDuff.Mode} enum for more
* information on the available alpha compositing and blending modes.</p>
*
*/
public class PorterDuffXfermode extends Xfermode {
/**
* Create an xfermode that uses the specified porter-duff mode.
*
* @param mode The porter-duff mode that is applied
*/
public PorterDuffXfermode(PorterDuff.Mode mode) {
porterDuffMode = mode.nativeInt;
}
}
然后我们看下点击mode进去看下
/**
* @hide
*/
public static Mode intToMode(int val) {
switch (val) {
default:
case 0: return Mode.CLEAR;
case 1: return Mode.SRC;
case 2: return Mode.DST;
case 3: return Mode.SRC_OVER;
case 4: return Mode.DST_OVER;
case 5: return Mode.SRC_IN;
case 6: return Mode.DST_IN;
case 7: return Mode.SRC_OUT;
case 8: return Mode.DST_OUT;
case 9: return Mode.SRC_ATOP;
case 10: return Mode.DST_ATOP;
case 11: return Mode.XOR;
case 16: return Mode.DARKEN;
case 17: return Mode.LIGHTEN;
case 13: return Mode.MULTIPLY;
case 14: return Mode.SCREEN;
case 12: return Mode.ADD;
case 15: return Mode.OVERLAY;
}
}
什么意思呢?
应该可以看得懂,这里每个图片显示的效果是最终的效果,然后很明显,我们这里需要的是SrcIn效果,我们要把左图的效果嵌套到右图里面去。
3 代码实现
1)MyTextView.java文件如下
package com.onemt.sdk.circle;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.util.AttributeSet;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatTextView;
public class MyTextView extends AppCompatTextView {
private final RectF roundRect = new RectF();
private final Paint desPaint = new Paint();
private final Paint srcPaint = new Paint();
private float mRadius = 10;
private boolean isChange = false;
public MyTextView(@NonNull Context context) {
super(context);
init();
}
public MyTextView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public MyTextView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public void change(boolean isChange) {
this.isChange = isChange;
invalidate();
}
public void init() {
desPaint.setAntiAlias(true);//设置抗锯齿
desPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
srcPaint.setAntiAlias(true);
float density = getResources().getDisplayMetrics().density;
mRadius *= density;
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
int width = getWidth();
int height = getHeight();
roundRect.set(0, 0, width, height);
}
@Override
public void draw(Canvas canvas) {
//保存最原始的roundRect
canvas.saveLayer(roundRect, srcPaint, Canvas.ALL_SAVE_FLAG);
if (isChange) {
//保存去掉头部2圆角的roundRect(实际就是保留底部的2个圆角)
canvas.drawRect(roundRect.left, (roundRect.top + roundRect.bottom) / 2, roundRect.right, roundRect.bottom, srcPaint);
//保存去掉底部2圆角的roundRect(实际就是保留顶部的2个圆角)
// canvas.drawRect(roundRect.left, roundRect.top, roundRect.right, roundRect.bottom / 2, srcPaint);
}
//保存掉头部2圆角的roundRect
canvas.drawRoundRect(roundRect, mRadius, mRadius, srcPaint);
//保存叠加后的内容
canvas.saveLayer(roundRect, desPaint, Canvas.ALL_SAVE_FLAG);
super.draw(canvas);
//清空所有的图像矩阵修改状态
canvas.restore();
}
}
如果你看不懂这个函数drawRoundRect,请看下我的这篇博客介绍 Android之Canvas的drawRoundRect()
2)MainActivity.java文件如下
package com.onemt.sdk.circle;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
public MyTextView myTextView;
public boolean isChange = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myTextView = findViewById(R.id.my_textview);
myTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (isChange) {
myTextView.change(true);
isChange = false;
} else {
myTextView.change(false);
isChange = true;
}
}
});
}
}
3)activity_main.xml文件如下
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".MainActivity">
<com.onemt.sdk.circle.MyTextView
android:id="@+id/my_textview"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@color/colorAccent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
4 效果
初始进来如下效果,4圆角效果
然后我们点击图片切换效果如下,上2圆角效果
来源:https://blog.csdn.net/u011068702/article/details/105021656


猜你喜欢
- .NET中提供了读写Cookie的多种方法,Request.Cookies 是客户端通过 Cookie 标头形式由客户端传输到服务器的 Co
- 使用JPA CriteriaQuery查询的注意事项1.pojo类@Entity@Table(name = "report_wor
- 话不多说,请看代码:package com.lxj.demo;import java.io.BufferedReader;import ja
- 持久性底部面板可以用于补充应用主要内容的信息,即使用户与应用程序的其他控件进行互动,也仍然可以看到持久的底部面板。可以使用Scaffold.
- 这里给大家带来的是动态webservice调用接口并读取解析返回结果的具体示例,非常的简单,注释也很详细,小伙伴们可以参考下。using S
- 使用了RecyclerView嵌套RecyclerView的方案。购物车的第一个界面为RecyclerView,每个Item里面包含一个店铺
- jol(java object layout)需要的依赖<dependency> <
- 大家都知道为了防止我们的网站被有些人和黑客恶意攻击,比如我们网站的注册页面,如果我们在用户注册的时候不加上一个验证码框的话,别人就可以写一个
- 介绍记录将elasticsearch集成到spring boot的过程,以及一些简单的应用和helper类使用。接入方式使用spring-b
- 本文实例讲述了Java使用组合模式实现表示公司组织结构功能。分享给大家供大家参考,具体如下:一、模式定义组合模式:将对象组合成树形结构以表示
- 算法描述堆排序算法的描述如下:将待排序的数组调整为最大堆,此时未排序的长度 N 为数组的长度,调整的过程就是倒序将数组的
- 1. 概述本文主要包括以下几个方面:编码基本知识,Java,系统软件,url,工具软件等。在下面的描述中,将以"中文"两
- 从现在开始,大家可以跟随着我的脚步来自定义一个属于自己的Spring框架。但是,在学习自定义Spring框架之前,我们得先来回顾一下Spri
- 我们知道在C语言编译时,有那么几个常用的优化编译选项,分别是-O0,-O1,-O2,-O3以及-Os。之前一直觉得既然是优化选
- 一、项目创建创建一个控制台应用程序,项目右键->管理 NuGet 程序包->Topshelft及Topshelf.Log4Net
- java 泛型方法:泛型是什么意思在这就不多说了,而Java中泛型类的定义也比较简单,例如:public class Test
- 本文实例为大家分享了SpringBoot实现动态多线程并发定时任务的具体代码,供大家参考,具体内容如下实现定时任务有多种方式,使用sprin
- java对象拷贝详解及实例Java赋值是复制对象引用,如果我们想要得到一个对象的副本,使用赋值操作是无法达到目的的:@Testpublic
- using System;using System.Collections.Generic;using System.Web.Script.
- spring validation多层对象校验1、第一层对象定义import java.io.Serializable; import ja