Android:自定义控件

3.16自定义控件

1.自定义VIEW组件

创建CustomizeView,继承View。重写onDraw方法,通过onDraw方法绘制我们自定义的图像、位图、路径等。

示例:

//自定义绘制View
public class CutomizeView extends View {//构造方法public CutomizeView(Context context) {super(context);}//构造方法,这个构造必须有public CutomizeView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);}//重新onDraw方法@Overrideprotected void onDraw(Canvas canvas) {//矩形位置坐标RectF rectF=new RectF(100,100,400,400);//画笔Paint paint=new Paint();//设置画笔//设置反锯齿paint.setAntiAlias(true);//设置绘制颜色paint.setColor(0xFF20FF22);//设置绘制样式paint.setStyle(Paint.Style.STROKE);//设置绘制文本大小paint.setTextSize(100);//绘制矩形canvas.drawRect(rectF,paint);//绘制椭圆canvas.drawOval(rectF,paint);//绘制圆canvas.drawCircle(300,300,200,paint);//绘制线段canvas.drawLine(0,0,100,100,paint);//绘制文本canvas.drawText("hello",200,900,paint);//绘制圆弧canvas.drawArc(rectF,0,100,true,paint);//绘制点canvas.drawPoint(800,800,paint);//绘制图片//bitmap位图,1、将项目已有图片转为bitmapBitmap bitmap=BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher);canvas.drawBitmap(bitmap,200,1000,paint);//2.创建一个bitmap//Bitmap bitmap1=Bitmap.createBitmap(100,100, Bitmap.Config.ARGB_8888);//绘制路径drawPath(canvas);}//绘制路径public void drawPath(Canvas canvas){Paint paint=new Paint();paint.setColor(0xFF0022FF);paint.setStyle(Paint.Style.STROKE);//绘制路径Path path=new Path();//起点path.moveTo(300,400);//直线path.lineTo(500,200);path.lineTo(550,350);path.lineTo(800,700);//曲线path.quadTo(500,300,300,800);canvas.drawPath(path,paint);}
}

创建对应layout文件,l_customize1.xml文件

示例:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical" android:layout_width="match_parent"android:layout_height="match_parent"><com.example.pro_customizeview.view.CutomizeViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"></com.example.pro_customizeview.view.CutomizeView></LinearLayout>

补充:Canvas对象坐标变换方法

translate(100,100):平移变化;

rotate(90):旋转变化;

scale():缩放变化;

save():保存当前坐标系;

restore():销毁当前坐标系,返回上一次坐标系;

自定义属性:

在res/values/attrs.xml中创建我们自定义组件属性。

示例:

定义属性名和属性需要数据格式类型

<?xml version="1.0" encoding="utf-8"?>
<resources><declare-styleable name="CutomizeView"><attr name="fontColor" format="color"></attr><attr name="fontSize" format="dimension"></attr></declare-styleable>
</resources>

修改l_customize1.xml文件,设置自定义属性。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:zdy="http://schemas.android.com/apk/res-auto"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><com.example.pro_customizeview.view.CutomizeViewzdy:fontSize="20dp"zdy:fontColor="@color/colorPrimary"android:layout_width="wrap_content"android:layout_height="wrap_content" />
</LinearLayout>

在自定义组件CutomizeView中构造函数中获取到我们自定义的属性,然后可以在onDraw,onMeasure,onLayout方法中使用。

//构造方法,这个构造必须有
public CutomizeView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);//所有的属性存放在AttributeSet中int count = attrs.getAttributeCount();//1、遍历获取for(int i=0;i<count;i++){//获取属性名String attrName=attrs.getAttributeName(i);//获取属性值String attrValue=attrs.getAttributeValue(i);}//2、直接获取到自定义属性//在R文件中会自动生成TypedArray typedArray= context.obtainStyledAttributes(attrs,R.styleable.CutomizeView);//将获取到的属性可以在onDraw,onMesure,onLayout中使用。int fontColor=typedArray.getColor(R.styleable.CutomizeView_fontColor,0xFF0022FF);float fontSize=typedArray.getDimension(R.styleable.CutomizeView_fontSize,20);//注意使用完释放资源typedArray.recycle();
}

onMeasure方法和onLayout方法。

示例:

//测量方法,获取控件宽高,模式
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {//调用父类onMeasure方法,实际注释掉super.onMeasure(widthMeasureSpec, heightMeasureSpec);//1、获取mode和sizeint widthMode=MeasureSpec.getMode(widthMeasureSpec);int widthSize=MeasureSpec.getSize(widthMeasureSpec);int heightMode=MeasureSpec.getMode(heightMeasureSpec);int heightSize=MeasureSpec.getSize(heightMeasureSpec);//当父控件为viewgroup时,要获取子控件宽高,必须先测量一次,强制测量//否则childView的getMeasuredWidth拿不到宽度measureChildren(widthMeasureSpec,heightMeasureSpec);//2、通过mode设置合理sizeswitch (widthMode){//父控件对子控件限制最大值,wrap_contentcase MeasureSpec.AT_MOST://宽度设置,widthSize = 100dp ;break;//控件大小是个确定值,100dp,match_parent(父控件大小确定)等case MeasureSpec.EXACTLY:break;//父控件对子控件大小不做限定case MeasureSpec.UNSPECIFIED:break;}switch (heightMode){//父控件对控件限制最大值,wrap_contentcase MeasureSpec.AT_MOST://宽度设置,break;//控件大小是个确定值,layout中设置为具体20dp等或者match_parent,父控件大小确定case MeasureSpec.EXACTLY:break;//父控件对控件大小不做限定,例如:ListView中子item数量不定case MeasureSpec.UNSPECIFIED:br

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/675604.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【原创 附源码】Flutter海外登录--Tiktok登录最详细流程

最近接触了几个海外登录的平台&#xff0c;踩了很多坑&#xff0c;也总结了很多东西&#xff0c;决定记录下来给路过的兄弟坐个参考&#xff0c;也留着以后留着回顾。更新时间为2024年2月7日&#xff0c;后续集成方式可能会有变动&#xff0c;所以目前的集成流程仅供参考&#…

[BeginCTF]真龙之力

安装程序 双击安装 出现了安装失败的标签&#xff0c;开发者不允许测试。 查看Mainfest入口文件 <?xml version"1.0" encoding"utf-8"?> <manifest xmlns:android"http://schemas.android.com/apk/res/android" android:versionCo…

71_Pandas.DataFrame排名

71_Pandas.DataFrame排名 使用rank()方法对pandas.DataFrame和pandas.Series的行/列进行排名。 sort_values() 是一种按升序或降序对 pandas.DataFrame 列和 pandas.Series 进行排序的方法&#xff0c;但rank() 返回每个元素的排名而不对数据进行排序。 请参阅下面的文章了解…

[vscode]ssh报错: Resolver error: Error: XHR failedscode错误

场景问题&#xff1a;通过vscode ssh连接远程服务器失败&#xff0c;报错&#xff1a;Resolver error: Error: XHR failedscode&#xff1a; 问题原因&#xff1a;~/.vscode-server/bin/一串数字下的vscode-server-linux-x64.tar.gz由于某种原因无法正常下载 解决方式&#x…

JavaScript实现轮播图方法

效果图 先来看下效果图&#xff0c;嫌麻烦就不用具体图片来实现了&#xff0c;主要是理清思路。&#xff08;自动轮播&#xff0c;左右按钮切换图片&#xff0c;小圆点切换图片&#xff0c;鼠标移入暂停轮播&#xff0c;鼠标移出继续轮播&#xff09; HTML 首先是html内容&am…

【QT学习十四】 文件目录操作

目录 一、概述 二、详解 1. QFile QFile 类中的一些静态方法&#xff1a; 使用示例&#xff1a; 注意事项&#xff1a; 2. QDir 成员函数 使用实例&#xff1a; 注意事项&#xff1a; 3. QFileInfo 成员函数 使用实例 4. QTemporaryFile 成员函数 使用实例 注…

Rust语言之集合

文章目录 一、元组&#xff08;tuple&#xff09;1.元组定义2.元组使用解构索引 3.元组修改非可变元组可变元组类型不一致 二、数组1.数组不可变数组定义可变数组定义数组使用数组修改数组的遍历 2.动态数组-向量&#xff08;Vector&#xff09;向量定义向量遍历向量追加向量插…

MongoDB聚合: $sort

聚合的$sort阶段对所有输入文件进行排序&#xff0c;并按排序顺序返回管道。 语法 { $sort: { <field1>: <sort order>, <field2>: <sort order> ... } }$sort阶段参数为一个文档&#xff0c;该文档指定了要排序的字段和相应的排序顺序。<sort or…

[职场] 公安管理学就业方向及前景 #媒体#笔记#笔记

公安管理学就业方向及前景 公安管理学是中国普通高等学校本科专业。本专业文理兼收&#xff0c;学制4年&#xff0c;授予法学学士学位。本专业培养掌握马克思主义基本原理&#xff0c;政治坚定&#xff0c;坚持党和国家的路线、方针、政策&#xff0c;具有良好职业素养、科学素…

获取视频帧图片

在实现了minio文件上传的基础上进行操作 一、编写pom <dependency><groupId>org.jcodec</groupId><artifactId>jcodec</artifactId><version>0.2.5</version> </dependency> <dependency><groupId>org.jcodec<…

【小程序】基础API——面板API接口介绍

ty.preloadPanel 面板预下载 需引入BizKit&#xff0c;且在>3.0.0版本才可使用 参数 Object object 属性类型默认值必填说明deviceIdstring是设备 idextraInfoPanelExtraParams否额外面板信息 当预下载的是二级面板时, 需要传递的额外信息completefunction否接口调用结束…

PMP考试之20240209

1、生物制药公司ClinicaLabs的一位项目经理打算与她的经理讨论为其团队无法执行的复杂活动获取额外资源的问题。一旦活动完成&#xff0c;这些资源将立即投入项目。在这种情况下&#xff0c;项目经理最需要以下哪项技能&#xff1f; A.确定资源需求的规划技能 B.使经理相信她…

git恢复rebase过程中遇到权限问题和丢失的提交

文章目录 一、检查丢失的提交是否还在 reflog 中二、创建一个新分支来恢复丢失的提交三、处理权限问题四. 使用 git fsck 查找丢失对象1、创建一个新分支来恢复该提交2、检查和合并提交 五. 介绍git中命令reflog 与 fsck1、git reflog2、git fsck使用场景 一、检查丢失的提交是…

freesql orm 使用 DynamicFilterInfo 拼接日期查询条件时间格式一个难得的经验

文本到时间条件的转换 前端输入 1253-3 , 后台提示"varchar 数据类型到 datetime 数据类型的转换产生一个超出范围的值" 经查询, mssql 【datetime】数据类型&#xff1a;最大是9999年12 月31日&#xff0c;最小是1753年1月1日 所以要拼接限制一下, 只是 if (val.…

迅为RK3588开发板ubuntu和window互传图形界面直接拖拽进行文件传输

确保以及安装了 VMware Tools。如下图所示表示已安装过了。 和 windows 端文件夹间传输一样直接拖拽进去即可&#xff0c;如下图所示&#xff1a; 也可拖拽到终端&#xff0c;如下图所示&#xff1a; 更多内容可以B站搜索迅为RK3588开发板

什么是系统工程(字幕)22

0 00:00:00,650 --> 00:00:02,660 那么下一个呢&#xff0c;就是 1 00:00:03,200 --> 00:00:04,770 图16.12 2 00:00:05,740 --> 00:00:07,910 这是一个活动图 3 00:00:09,090 --> 00:00:11,930 表达了蒸馏这个水的 4 00:00:12,280 --> 00:00:13,470 过程的…

一文彻底搞懂Redis的内存回收机制和内存过期淘汰策略

文章目录 1. Redis内存回收机制2. Redis过期策略3. Redis淘汰策略3.1 LRU算法3.2 缓存清理配置3.3 Redis数据淘汰策略3.4 缓存清理的流程 4. 总结 关于 Redis 内存回收机制和内存过期淘汰策略的常见问题&#xff1a; 什么是 Redis 的内存回收机制&#xff1f; Redis 的内存回收…

百家cms代审

环境搭建 源码链接如下所示 https://gitee.com/openbaijia/baijiacms 安装至本地后 直接解压到phpstudy的www目录下即可 接下来去创建一个数据库用于存储CMS信息。&#xff08;在Mysql命令行中执行&#xff09; 接下来访问CMS&#xff0c;会默认跳转至安装界面 数据库名称和…

原根primitive root

&#xff08;a,m&#xff09;1&#xff0c;若,则称a为模N的原根。 以下程序只能判断结果为简化剩余系情况下的模N的原根。 对于模4的primitive_root3,模9的primitive_root2,5这些情况无法判断。 def find_primitive_root(n):for base in range(1,n):l[]for index in range(…

uni使用openlayer加载本机离线地图

manifest.json添加配置 "runmode": "liberate"(默认为normal) 把地图打包进apk&#xff0c;这样手机每次访问地图就可以访问到工程文件夹的地图资源了&#xff0c;不用每次都请求云资源&#xff0c;消耗流量太大了