自定义View示例

news2024/11/17 22:32:30

目录

1.继承View重写onDraw方法

2.继承View重写onMeasure方法

3.添加自定义属性

4.完整代码:


1.继承View重写onDraw方法

解决问题:直接继承自View和ViewGroup的控件,padding是默认无法生效的,需要自己处理。

 @Override
 protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        final int paddingLeft=getPaddingLeft();
        final int paddingRight=getPaddingRight();
        final int paddingTop=getPaddingTop();
        final int paddingBottom=getPaddingBottom();

        int width=getWidth()-paddingLeft-paddingRight;
        int height=getHeight()-paddingBottom-paddingTop;
        int radius=Math.min(width,height)/2;
        canvas.drawCircle(paddingLeft+width/2,paddingTop+height/2,radius,mPaint);
 }

中心思想就是在绘制的时候考虑到View四周的空白即可。

2.继承View重写onMeasure方法

解决问题:直接继承自View的控件,如果不对wrap_content做特殊处理,那么使用wrap_content就相当于使用match_parent。

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthSpecMode=MeasureSpec.getMode(widthMeasureSpec);
        int widthSpecSize=MeasureSpec.getSize(widthMeasureSpec);
        int heightSpecMode=MeasureSpec.getMode(heightMeasureSpec);
        int heightSpecSize=MeasureSpec.getSize(heightMeasureSpec);
        if(widthSpecMode==MeasureSpec.AT_MOST&&heightSpecSize==MeasureSpec.AT_MOST){
            setMeasuredDimension(200,200);
        }else if(widthSpecMode==MeasureSpec.AT_MOST){
            setMeasuredDimension(200,heightSpecSize);
        } else if (heightSpecMode==MeasureSpec.AT_MOST) {
            setMeasuredDimension(widthSpecSize,200);
        }

    }

3.添加自定义属性

第一步:在values目录下面创建自定义属性的XML,比如attrs.xml,文件内容如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="CircleView">
        <attr name="circle_color" format="color"/>
    </declare-styleable>
</resources>

在XML中声明了一个自定义属性集合“CircleView”,在这个集合里面可以有很大自定义属性,这里只定义了一个格式为“Color”的属性“circle_color”,这里的格式color指的是颜色。

第二步:在View的构造方法中解析自定义属性的值并做出相应的处理。

    public CircleView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        TypedArray a=context.obtainStyledAttributes(attrs,R.styleable.CircleView);
        mColor=a.getColor(R.styleable.CircleView_circle_color,Color.RED);
        a.recycle();
        init();
    }

首先加载自定义属性集合CircleView,接着解析CircleView属性集合中的circle_color属性,它的id为R.styleable.CircleView_circle_color。如果在使用时没有指定circle_color这个属性,那么就会选择红色作为默认的颜色值,解析完自定义属性后,通过recycle方法来释放资源,这样CircleView中所做的工作就完成了。

第三步:在布局文件中使用自定义属性

<?xml version="1.0" encoding="utf-8"?>
<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"
    tools:context=".MainActivity"
    android:background="#ffffff"
    android:orientation="vertical">
    <com.example.myview.CircleView
        android:id="@+id/circleView1"
        android:layout_width="wrap_content"
        android:layout_height="100dp"
        android:background="#000000"
        android:layout_margin="20dp"
        android:padding="20dp"
        app:circle_color="@color/green"
        />
</LinearLayout>

 运行:

4.完整代码

CircleView类:


public class CircleView extends View {

    private int mColor= Color.RED;
    private Paint mPaint=new Paint(Paint.ANTI_ALIAS_FLAG);

    public CircleView(Context context) {
        super(context);
        init();
    }

    public CircleView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        TypedArray a=context.obtainStyledAttributes(attrs,R.styleable.CircleView);
        mColor=a.getColor(R.styleable.CircleView_circle_color,Color.RED);
        a.recycle();
        init();
    }

    public CircleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }


   private void init(){
        mPaint.setColor(mColor);
   }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthSpecMode=MeasureSpec.getMode(widthMeasureSpec);
        int widthSpecSize=MeasureSpec.getSize(widthMeasureSpec);
        int heightSpecMode=MeasureSpec.getMode(heightMeasureSpec);
        int heightSpecSize=MeasureSpec.getSize(heightMeasureSpec);
        if(widthSpecMode==MeasureSpec.AT_MOST&&heightSpecSize==MeasureSpec.AT_MOST){
            setMeasuredDimension(200,200);
        }else if(widthSpecMode==MeasureSpec.AT_MOST){
            setMeasuredDimension(200,heightSpecSize);
        } else if (heightSpecMode==MeasureSpec.AT_MOST) {
            setMeasuredDimension(widthSpecSize,200);
        }
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        final int paddingLeft=getPaddingLeft();
        final int paddingRight=getPaddingRight();
        final int paddingTop=getPaddingTop();
        final int paddingBottom=getPaddingBottom();

        int width=getWidth()-paddingLeft-paddingRight;
        int height=getHeight()-paddingBottom-paddingTop;
        int radius=Math.min(width,height)/2;
        canvas.drawCircle(paddingLeft+width/2,paddingTop+height/2,radius,mPaint);
    }
}

 布局文件:

<?xml version="1.0" encoding="utf-8"?>
<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"
    tools:context=".MainActivity"
    android:background="#ffffff"
    android:orientation="vertical">
    <com.example.myview.CircleView
        android:id="@+id/circleView1"
        android:layout_width="wrap_content"
        android:layout_height="100dp"
        android:background="#000000"
        android:layout_margin="20dp"
        android:padding="20dp"
        app:circle_color="@color/green"
        />
</LinearLayout>

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

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

相关文章

组合和聚合

不是c的语法要求&#xff0c;是一种建模思想 目录 1.组合 1. 使用 -- 在一个类中创建另外一个类的对象 代码中的解释: 代码结果&#xff1a; 组合&#xff1a; 2. 使用 -- 在一个类中创建另外一个类的指针 2.使用类定义一个指针 -- 不是创建一个对象 3.聚合 1. 使…

世微AP5125 输入14-80V 输出12V5A LED灯降压恒流电源驱动方案 SOT23-6

这是一款60WLED驱动方案,线路图BOM表如下 ​ 祥单表&#xff1a; 实物图&#xff1a; 产品描述 AP5125 是一款外围电路简单的 Buck 型平均电流检测模式的 LED 恒流驱动器&#xff0c;适用于 8-100V 电压范围的非隔离式大功率恒流 LED 驱动领域。芯片采用固定频率 140kHz 的 …

与建设者同行:TinTinLand 社区 2023 年度回顾

2023 是 Web3 行业不同寻常的一年&#xff0c;也是 TinTinLand 社区高速发展的一年&#xff1a;我们精心提供最有价值的内容&#xff0c;举办一系列丰富多样的活动&#xff0c;开设氛围友好的区块链技术课程&#xff0c;为尚不了解 Web3 的开发者等各领域人才&#xff0c;构建颇…

小程序必看系列!什么是抖音小程序?抖音小程序怎么制作?

随着移动互联网的飞速发展&#xff0c;抖音已经成为了一个广受欢迎的短视频平台。在这个平台上&#xff0c;用户可以分享自己的生活点滴、表达自己的观点&#xff0c;甚至还能通过小程序来丰富自己的社交体验。那么&#xff0c;如何制作抖音小程序呢&#xff1f; 一、抖音小程…

清水模板厂家专供 — 易脱模,不翘曲

在现代建筑施工中&#xff0c;清水模板的选择对于实现优质建筑表面尤为关键。我们专供的清水模板&#xff0c;凭借其易脱模和不翘曲的特性&#xff0c;为建筑项目提供了理想的解决方案。 产品特点 易脱模性能&#xff1a;我们的清水模板表面光滑细腻&#xff0c;经过特殊处理…

知识库软件有很多,这几个最好用

时代进步的同时&#xff0c;逐渐优化的企业知识库已经成为企业优化工作效率、提升企业竞争力的重要工具。随着云计算和大数据技术的快速发展&#xff0c;知识库软件如雨后春笋般出现在人们的视野中。下面&#xff0c;我从寻宝者的角度&#xff0c;向大家稳稳地推荐三款最优秀的…

电动工具直流调速专用集成电路GS069,具有电源电压范围宽、功耗小、抗干扰能力强等特性

GS069电动工具直流调速电路是CMOS专用集成电路&#xff0c;具有电源电压范 围宽、功耗小、抗干扰能力强等特点。通过外接电阻网络&#xff0c;改变与之相接 的VMOS 管的输出&#xff0c;达到控制电动工具转速的作用。该电路输出幅值宽&#xff0c; 频率变化小&#xff0c;占空比…

SQL-DML增删改

&#x1f389;欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克&#x1f379; ✨博客主页&#xff1a;小小恶斯法克的博客 &#x1f388;该系列文章专栏&#xff1a;重拾MySQL &#x1f379;文章作者技术和水平很有限&#xff0c;如果文中出现错误&am…

利用Qt输出XML文件

使用Qt输出xml文件 void PixelConversionLibrary::generateXML() {QFile file("D:/TEST.xml");//创建xml文件if (!file.open(QIODevice::WriteOnly | QIODevice::Text))//以只写方式&#xff0c;文本模式打开文件{qDebug() << "generateXML:Failed to op…

ZigBee快速入门——IO配置(LED)

ZigBee快速入门——IO配置&#xff08;LED&#xff09; 点亮LEDIO配置 建议先看IO配置再看点亮LED 点亮LED #include <iocc2530.h> //点亮LED&#xff08;纯寄存器版&#xff09; void Delay(unsigned int n); void InitIO(void); void main(void){InitIO();while(1){P1…

redis源码之:事件驱动epoll

一、aeEventLoop初始化 从server.c的main方法中进入initServer&#xff0c;在initServer方法中&#xff0c;server.el aeCreateEventLoop(server.maxclientsCONFIG_FDSET_INCR);创建eventloop&#xff1a;&#xff08;注意fileevent与epollevent的区分fileEvent是标识往epoll…

Frida基本能力汇总

1 需求 Frida GitHub Welcome | Frida • A world-class dynamic instrumentation toolkit 2 接口 3.1 基本能力Ⅰ&#xff1a;hook参数、修改结果 3.2 基本能力Ⅱ&#xff1a;参数构造、方法重载、隐藏函数的处理 3.3 中级能力&#xff1a;远程调用 3.4 高级能力&#xff1…

部署ATS(Apache Traffic Server)和Nginx正向代理服务性能对比

部署ATS&#xff08;Apache Traffic Server&#xff09;和Nginx正向代理服务&性能对比 1. 正向代理的用途2. ATS(Apache Traffic Server)正向代理服务器部署3. Nginx正向代理服务器部署4. 性能对比 1. 正向代理的用途 正向代理一般是用于内部网络出去&#xff0c;反向代理一…

C#实现Excel合并单元格数据导入数据集

目录 功能需求 Excel与DataSet的映射关系 范例运行环境 Excel DCOM 配置 设计实现 组件库引入 ​方法设计 返回值 参数设计 打开数据源并计算Sheets 拆分合并的单元格 创建DataTable 将单元格数据写入DataTable 总结 功能需求 将Excel里的worksheet表格导入到Da…

互联网加竞赛 基于大数据的股票量化分析与股价预测系统

文章目录 0 前言1 课题背景2 实现效果3 设计原理QTChartsarma模型预测K-means聚类算法算法实现关键问题说明 4 部分核心代码5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于大数据的股票量化分析与股价预测系统 该项目较为新颖…

HarmonyOS4.0系统性深入开发18公共事件简介

公共事件简介 HarmonyOS通过CES&#xff08;Common Event Service&#xff0c;公共事件服务&#xff09;为应用程序提供订阅、发布、退订公共事件的能力。 公共事件从系统角度可分为&#xff1a;系统公共事件和自定义公共事件。 系统公共事件&#xff1a;CES内部定义的公共事…

如何利用RPA做UI自动化测试对传统自动化的降维打击

写在前面 RPA软件一开始的目的并不是自动化测试&#xff0c;而是要把电脑上面几十个、上百个常用的软件&#xff0c;通过机器人流程自动化来打通&#xff0c;通过一个软件来控制几十个、上百个软件。而这个过程&#xff0c;其实覆盖了软件自动化测试。 所谓降维打击&#xff0c…

webpack初始化

1.下载 webpack webpack-cli 到项目 (版本独立) ** npm i webpack webpack-cli --save-dev ** 2.项目中运行工具命念&#xff0c;采用自定义命令的方式(局部命令)

Python商业数据挖掘实战——爬取网页并将其转为Markdown

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 ChatGPT体验地址 文章目录 前言前言正则表达式进行转换送书活动 前言 在信息爆炸的时代&#xff0c;互联网上的海量文字信息如同无尽的沙滩。然而&#xff0c;其中真正有价值的信息往往埋…

【源码阅读】事件订阅包v2

1、Feed Feed 实现一对多订阅&#xff0c;其中事件的载体是通道。发送到 Feed 的值会同时传送到所有订阅的通道。 与Typemux的对比 链接: link TypeMux是一个同步的事件框架&#xff0c;当有一个被订阅的事件发生的时候&#xff0c;会遍历该事件对应的订阅者通道&#xff0c;…