android 快速实现 圆角矩形控件 及 圆形控件
1.自定义RoundImageView
package com.examle.widget;import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.ImageView;import androidx.annotation.ColorInt;
import androidx.annotation.Dimension;
import androidx.annotation.Nullable;import com.examlpe.R;public class RoundImageView extends ImageView {private String TGA=RoundImageView.class.getSimpleName();private final PorterDuffXfermode xfermode=new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP);//绘制模式private final Paint mPaint;//实体paintprivate final Paint mStrokePaint;//描边paintprivate int mRadius;//圆角值private int mStrokeWidthColor;//描边颜色private int mStrokeWidth;//描边宽度private boolean mIsCircle;//true-圆形模式,false-圆角矩形模式public RoundImageView(Context context) {this(context, null);}public RoundImageView(Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);}public RoundImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {this(context, attrs, defStyleAttr, 0);}public RoundImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {super(context, attrs, defStyleAttr, defStyleRes);TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundImageView);mStrokeWidthColor = a.getColor(R.styleable.RoundImageView_riv_stroke_color, Color.WHITE);mStrokeWidth = a.getDimensionPixelSize(R.styleable.RoundImageView_riv_stroke_width, 0);mRadius = a.getDimensionPixelSize(R.styleable.RoundImageView_riv_round_radius, 0);mIsCircle = a.getBoolean(R.styleable.RoundImageView_riv_circle, false);a.recycle();mPaint = new Paint();mPaint.setAntiAlias(true);//抗锯齿mPaint.setColor(Color.WHITE);mPaint.setStyle(Paint.Style.FILL);mStrokePaint = new Paint();mStrokePaint.setAntiAlias(true);//抗锯齿mStrokePaint.setStyle(Paint.Style.STROKE);}@Overrideprotected void onDraw(Canvas canvas) {int layerId = canvas.saveLayer(0, 0, getWidth(), getHeight(), null);//保存图层super.onDraw(canvas);Drawable src = getDrawable();int tmpBpW = getWidth() - getPaddingLeft() - getPaddingRight();//位图宽度,必须大于0int tmpBpH = getHeight() - getPaddingTop() - getPaddingBottom();//位图高度,必须大于0if (src != null && getWidth() > 0 && getHeight() > 0 && tmpBpW>0 && tmpBpH>0) {Bitmap tmpBp = Bitmap.createBitmap(tmpBpW, tmpBpH, Bitmap.Config.ARGB_8888);Canvas tmpCv = new Canvas(tmpBp);//tmpBp画布float tmpR = Math.min(tmpBp.getWidth(), tmpBp.getHeight()) * 0.5f;//取最小宽度if (mIsCircle) {//圆形模式tmpCv.drawCircle(tmpR, tmpR, tmpR, mPaint);//绘制圆形} else {//圆角矩形模式tmpCv.drawRoundRect(0, 0, tmpBp.getWidth(), tmpBp.getHeight(), mRadius, mRadius, mPaint);//绘制圆角矩形}mPaint.setXfermode(xfermode);//绘制模式canvas.drawBitmap(tmpBp, getPaddingLeft(), getPaddingTop(), mPaint);//绘制位图if (mStrokeWidth > 0) {//描边mStrokePaint.setColor(mStrokeWidthColor);//描边颜色mStrokePaint.setStrokeWidth(mStrokeWidth);//描边宽度if (mIsCircle) {//圆形模式canvas.drawCircle(getPaddingLeft()+tmpR, getPaddingTop()+tmpR, tmpR-mStrokeWidth*0.5f, mStrokePaint);} else {//圆角矩形模式canvas.drawRoundRect(getPaddingLeft()+mStrokeWidth*0.5f, getPaddingTop()+mStrokeWidth*0.5f, getWidth() - getPaddingRight()-mStrokeWidth*0.5f, getHeight() - getPaddingBottom()-mStrokeWidth*0.5f, mRadius-mStrokeWidth*0.5f, mRadius-mStrokeWidth*0.5f, mStrokePaint);//绘制圆角}}}canvas.restoreToCount(layerId);//恢复图层}/*** 圆角值 dp* @param dpValue*/public void setRadius(@Dimension int dpValue) {this.mRadius =(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,dpValue,getResources().getDisplayMetrics());invalidate();}/*** 描边颜色* @param strokeWidthColor*/public void setStrokeWidthColor(@ColorInt int strokeWidthColor) {this.mStrokeWidthColor = strokeWidthColor;invalidate();}/*** 描边宽度 dp* @param dpValue*/public void setStrokeWidth(@Dimension int dpValue) {this.mStrokeWidth =(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,dpValue,getResources().getDisplayMetrics());invalidate();}/*** 圆角矩形 或 圆形控件* @param isCircle*/public void setCircle(boolean isCircle) {this.mIsCircle = isCircle;invalidate();}
}
2.新建attrs.xml 文件,路径 res/values/attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources><declare-styleable name="RoundImageView"><attr name="riv_stroke_width" format="dimension" /><attr name="riv_stroke_color" format="color" /><attr name="riv_round_radius" format="dimension" /><attr name="riv_circle" format="boolean"/></declare-styleable>
</resources>
3.布局使用:圆角矩形
<com.examlpe.widget.RoundImageViewandroid:id="@+id/riv"android:layout_width="180dp"android:layout_height="180dp"app:riv_circle="false"android:scaleType="fitXY"app:riv_round_radius="20dp"app:riv_stroke_width="2dp"app:riv_stroke_color="@color/white"android:src="@mipmap/ic_launcher" />
4.布局使用:圆形控件
<com.examlpe.widget.RoundImageViewandroid:id="@+id/riv"android:layout_width="180dp"android:layout_height="180dp"app:riv_circle="true"android:scaleType="fitXY"app:riv_stroke_width="2dp"app:riv_stroke_color="@color/white"android:src="@mipmap/ic_launcher" />
相关文章:
android 快速实现 圆角矩形控件 及 圆形控件
1.自定义RoundImageView package com.examle.widget;import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import an…...
【Python】外网远程登录访问jupyter notebook+pycharm使用ipython
第一步:创建python虚拟环境 conda create -n py3610 python3.6.10第二步:安装ipython pip install ipython pip install ipython notebook第三步:创建 IPython Notebook 服务器配置文件 # 进入python交互shell,设置密码 >&…...
error:0308010C:digital envelope routines::unsupported
error:0308010C:digital envelope routines::unsupported 报错原因解决方案方案一:降低node版本在17以下指定node版本 mac node版本降级 mac切换node版本 方案二:启用legacy OpenSSL provider方案三:配置package.json文件拓展:pac…...
Vue前端的工作需求
加油,新时代打工人! 需求: 实现带树形结构的表格,父数据显示新增下级,和父子都显示编辑。 技术: Vue3 Element Plus <template><div><el-table:data"tableData"style"width…...
97. 常用的HTTP服务压测工具
文章目录 导言一、ab二、wrk三、go-wrk 导言 在项目正式上线之前,我们通常需要通过压测来评估当前系统能够支撑的请求量、排查可能存在的隐藏bug,同时了解了程序的实际处理能力能够帮我们更好的匹配项目的实际需求(服务器实例个数,如需要部署…...
活动预告|听云猿生数据创始人 CEO 曹伟分享云数据库行业十余年经验总结
3月16日,KubeBlocks 将携手 OceanBase 开源社区、AutoMQ 带来《LLMs 时代下的企业数据管理与降本增效之路》主题 meetup,扫描下方二维码,即刻报名👇。 云猿生数据创始人 & CEO 曹伟将带来《KubeBlocks:把所有数据…...
数仓实战——京东数据指标体系的构建与实践
目录 一、如何理解指标体系 1.1 指标和指标体系的基本含义 1.2 指标和和标签的区别 1.3 指标体系在数据链路中的位置和作用 1.4 流量指标体系 1.5 指标体系如何向上支撑业务应用 1.6 指标体系背后的数据加工逻辑 二、如何搭建和应用指标体系 2.1 指标体系建设方法—OS…...
Alias许可配置
在数字化时代,软件已成为企业竞争的核心要素。然而,随着软件市场的日益复杂,如何合理配置和使用软件许可,已成为企业亟待解决的问题。Alias许可配置服务,凭借其卓越的功能和性能,帮助企业优化软件使用&…...
【读书笔记】针对ICS的ATTCK矩阵详解(一)
Techniques - ICS | MITRE ATT&CKhttps://attack.mitre.org/techniques/ics/ 一、初始访问(Initial Access) 该阶段:攻击者正在尝试进入ICS环境。 初始访问包括攻击者可能用作入口向量,从而可以在 ICS 环境中获得初始立足点的…...
Rust多线程访问数据,推荐使用mutex还是channel?
在Rust中,选择使用互斥锁(mutex)还是通道(channel)来进行多线程间的数据访问,主要取决于你的具体需求和数据共享的模式。 互斥锁(Mutex) 互斥锁是一种同步原语,用于保护…...
基于pytorch的手写体识别
一、环境搭建 链接: python与深度学习——基础环境搭建 二、数据集准备 本次实验用的是MINIST数据集,利用MINIST数据集进行卷积神经网络的学习,就类似于学习单片机的点灯实验,学习一门机器语言输出hello world。MINIST数据集,可以…...
Leetcode 56. 合并区间
题目描述:以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。 示例 1: 输入…...
C++:List的使用和模拟实现
创作不易,感谢三连!! 一、List的介绍 list的文档介绍 1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。 2. list的底层是双向链表结构,双向链表中每个元素存储在互不…...
20个Python函数程序实例
前面介绍的函数太简单了: 以下是 20 个不同的 Python 函数实例 下面深入一点点: 以下是20个稍微深入一点的,使用Python语言定义并调用函数的示例程序: 20个函数实例 简单函数调用 def greet():print("Hello!")greet…...
Wireshark——获取捕获流量的前N个数据包
1、问题 使用Wireshark捕获了大量的消息,但是只想要前面一部分。 2、方法 使用Wireshark捕获了近18w条消息,但只需要前5w条。 选择文件,导出特定分组。 输入需要保存的消息范围。如:1-50000。 保存即可。...
006-浏览器输入域名到返回
浏览器输入域名到返回 1、URL 输入2、DNS 域名解析3、建立 TCP 连接三次握手概念三次握手理解 4、发送 HTTP/HTTPS 请求5、服务器处理,并返回响应6、浏览器解析并渲染页面7、请求结束,端口 TCP 连接四次挥手概念四次挥手理解 1、URL 输入 2、DNS 域名解析…...
【kubernetes】关于k8s集群如何将pod调度到指定node节点?
目录 一、k8s的watch机制 二、scheduler的调度策略 Predicate(预选策略) 常见算法: priorities(优选策略)常见的算法有: 三、k8s的标签管理之增删改查 四、k8s的将pod调度到指定node的方法 方案一&am…...
【框架】React和Vue的异同
1. 前言 React对于原生JS要求会高一级,国外React用的多,国内Vue用的多。 2. 共同点 组件化函数式编程 (vue3函数式编程、vue2声明式编程)单向数据流,数据驱动视图VirtualDOM Diff算法操作DOM社区成熟,…...
如何选择阅读软件技术学习书籍
如何选择阅读软件技术学习书籍 这里以软件技术学习的角度结合自身感悟谈谈,如何选择阅读书籍。 人的时间和精力都是非常有限的,软件技术学习者如何选择阅读书籍。以下是从我的经验教训总结的一些体会: 1、确定自己的兴趣领域和阅读目标 选…...
做抖店用平板能代替电脑操作吗?抖店运营相关注意事项,注意规避
我是王路飞。 之前给你们讲在抖音开店流程的时候,说过开店需要用到电脑,还需要执照、资金、时间等等。 那么做抖店用平板能代替电脑操作吗? 这个问题其实有很多新手问过我,有的甚至是想直接在手机上操作,想着能省点…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...
