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、确定自己的兴趣领域和阅读目标 选…...

做抖店用平板能代替电脑操作吗?抖店运营相关注意事项,注意规避
我是王路飞。 之前给你们讲在抖音开店流程的时候,说过开店需要用到电脑,还需要执照、资金、时间等等。 那么做抖店用平板能代替电脑操作吗? 这个问题其实有很多新手问过我,有的甚至是想直接在手机上操作,想着能省点…...

SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...

Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...

MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...

Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...