原文地址:http://blog.csdn.net/risky78125/article/details/50609538

自定义View入门

long time no see,这次写一个灰常简单的一个自定义的view.当然,虽然说简单,但是麻雀虽小五脏俱全,自定义view的流程基本涵盖了.

从简单入手,然后大致了解一下view的绘制过程.这个view有多简单呢,实际上咱们就画一个圆,然后上个色.

下面开始:

public class CircleView extends View {private static final String TAG = "CircleView";    /*** 定义一个默认的圆形颜色*/private static final int DEFAULT_COLOR = Color.GRAY;    /*** 圆形的颜色*/private int color = DEFAULT_COLOR;    /*** 画笔*/private Paint mPaint;    public CircleView(Context context) {        this(context, null);}    public CircleView(Context context, AttributeSet attrs) {        this(context, attrs, 0);}    public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);initPaint();}    private void initPaint() {        // 设置画笔抗锯齿,可以让图形的边缘更平滑.如果需要画的图形四四方方的那就没必要设置了mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);        // 设置画笔的颜色mPaint.setColor(color);}    @Overrideprotected void onDraw(Canvas canvas) {        super.onDraw(canvas);        // 获取控件本身的宽和高,并选择较短的一边的一半作为圆的半径int width = getWidth();        int height = getHeight();        int radius = Math.min(width, height) / 2;        // 画圆,前两个参数确定圆心的位置,之后圆的半径,画笔canvas.drawCircle(width / 2, height / 2, radius, mPaint);}
}123456789101112131415161718192021222324252627282930313233343536373839404142434445

很简单吧,那么看一下布局文件

<?xml version="1.0" encoding="utf-8"?><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:padding="10dp"android:orientation="vertical"><com.lanou3g.drawview.widget.CircleView        android:layout_width="wrap_content"android:layout_height="wrap_content"/></LinearLayout>12345678910111213

布局也非常简单对吧,那好,看一下预览,还算是正常的吧

那好,接下来,咱们自定义一下这个圆圈的颜色,也就是需要在布局中有一条属性,可以控制这个view的颜色.

创建自定义属性文件,在res/values下,创建一个资源文件,命名为attrs,如下图:

文件里面就可以创建自定义的属性,继续贴代码:

<?xml version="1.0" encoding="utf-8"?><resources><!--一般来说,为某个控件自定义属性,name就跟控件名字一样--><declare-styleable name="CircleView"><!--定义一条属性叫circleColor,规定参数填颜色值--><attr name="circleColor" format="color"/></declare-styleable></resources>12345678

属性定义好了,就可以到代码中把颜色值取出,然后设置给画笔就可以了,继续代码

public class CircleView extends View {/** 这部分代码与上文一样,省略... */public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        // 获取自定义属性TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleView);        // 取出对应的值设置给color,并提供一个默认值color = a.getColor(R.styleable.CircleView_circleColor, DEFAULT_COLOR);initPaint();}    private void initPaint() {        // 设置画笔抗锯齿,可以让图形的边缘更平滑.如果需要画的图形四四方方的那就没必要设置了mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);        // 设置画笔的颜色mPaint.setColor(color);}    /** 画圆部分与上文一样,省略 */}12345678910111213141516171819

自定义的属性获取就写完了.然后在布局文件中,设置命名空间,目的为可以获取到自定义的属性,然后在CircleView中使用自定义的属性为圆上色.当然,命名空间的名字我写的是view,这个可以根据自己的爱好命名.

<?xml version="1.0" encoding="utf-8"?><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"xmlns:view="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"android:padding="10dp"android:orientation="vertical"><com.lanou3g.drawview.widget.CircleView        android:layout_width="wrap_content"android:layout_height="wrap_content"view:circleColor="#0088ff"/></LinearLayout>123456789101112131415

ok,看预览,可以看到颜色咱们可以自定义了

实 际上这个自定义的控件是灰常不专业的,不知道大家注意到没有.咱们在布局文件中给这个控件设置的宽高都为wrap_content,那显示成这么大肯定是 不正常的.实际上虽然给的是wrap_content,但是系统是按照match_parent来计算的.那为什么会出现这种情况呢?给10秒钟大家思考 一下

try {Thread.sleep(10000);} catch (InterruptedException e) {e.printStackTrace();}12345

思考完了吧,那记住一句话就得了,对于直接继承自view的自定义组件,如果不在代码中对wrap_content进行处理,那么系统就会把它理解成match_parent,呵呵哒,气人不.

那接下来,咱们就处理一下吧.在自定义组件中,重写onMeasure()这个方法,处理的过程就在此方法中.思路就是,如果布局中的宽或高设置成了wrap_content,那么对应的宽高就给设置成188.

/** 其他部分的代码省略 */@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int widthMode = MeasureSpec.getMode(widthMeasureSpec);        int widthSize = MeasureSpec.getSize(widthMeasureSpec);        int heightMode = MeasureSpec.getMode(heightMeasureSpec);        int heightSize = MeasureSpec.getSize(heightMeasureSpec);        if (widthMode == MeasureSpec.AT_MOST && heightMode == MeasureSpec.AT_MOST){setMeasuredDimension(188,188);}else if (widthMode == MeasureSpec.AT_MOST){setMeasuredDimension(188,heightSize);}else if (heightMode == MeasureSpec.AT_MOST){setMeasuredDimension(widthSize,188);}}12345678910111213141516

接下来再看一下预览(PS:Android Studio真是个好东西)

<com.lanou3g.drawview.widget.CircleViewandroid:layout_width="match_parent"android:layout_height="wrap_content"view:circleColor="#0088ff"/>1234

接下来另一个问题,写到现在这个程度的时候,大家可以试一下给这个控件加上margin属性和padding属性,看一下效果,给大家半个小时尝试一下

    try {Thread.sleep(30 * 60 * 1000);} catch (InterruptedException e) {e.printStackTrace();}12345

擦擦擦

/** Application Not Responding !!!!! */1

实 际结果是,margin是生效的,而padding是不会生效的.因为margin属性是由父容器控制的,所以会生效.而padding是控件本身控制 的,咱们没有进行处理,所有是无效的.那么接下来,继续处理一下padding.处理的过程也非常简单,在绘制的过程中,考虑一下padding即可.那 么修改一下onDraw方法,如下:

@Overrideprotected void onDraw(Canvas canvas) {        super.onDraw(canvas);        // 获取padding值int paddingLeft = getPaddingLeft();        int paddingRight = getPaddingRight();        int paddingTop = getPaddingTop();        int paddingBottom = getPaddingBottom();        // 获取控件本身的宽和高,并选择较短的一边的一半作为圆的半径.计算时将padding考虑进去int width = getWidth() - paddingLeft - paddingRight;        int height = getHeight() - paddingTop - paddingBottom;        int radius = Math.min(width, height) / 2;        // 画圆,前两个参数确定圆心的位置,之后圆的半径,画笔canvas.drawCircle(paddingLeft + width / 2, paddingTop + height / 2, radius, mPaint);}123456789101112131415

布局文件

<com.lanou3g.drawview.widget.CircleViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="30dp"android:paddingTop="5dp"android:paddingBottom="20dp"view:circleColor="#0088ff"/>1234567

预览

转载于:https://my.oschina.net/u/2531415/blog/639721

自定义View入门 --转载自武老师博客160303相关推荐

  1. 基于Android自带插入器的图形波动效果 --转载自李硕老师博客160303

    原文地址:http://blog.csdn.net/u012215170/article/details/50598747 对于Android的各种动画我们并不陌生,但是可能很多同学不知道Interp ...

  2. codewarrior 入门(来源于逍遥呤博客)

    codewarrior 入门(来源于逍遥呤博客) (2009-08-08 12:12:15) 转载 标签: 杂谈 分类: ARM系列 1.首先是要建立工程,new->ARM Executable ...

  3. 【学术】我读科学网“马臻”老师博客体会

    从知乎看到有博士提到马臻老师博客,便去关注了一下.看了一上午,摘录一些自己有感觉的句子吧. 1. 心中一杆秤 我看,无论别人怎么做,我们自己心中应该自有一杆秤. 一个美国参议院对热切期望踏入政界的年轻 ...

  4. python 等高线地图图片转 tin_由等高线生成TIN并由TIN生成坡度图【解决中文环境翻译差别的问题】(转载请注明出自博客园)...

    由等高线等生成TIN并生成坡度图的代码.在softline代码段对错误信息作了处理,不再使用"软线","软性线","柔性线","软 ...

  5. MD5算法在PB中的实现(转载自 - 阿多米 - 博客园)

    MD5算法在PB中的实现(转载自 - 阿多米 - 博客园) 注:转载请写明出处.本文转载自--阿多米,原链接:http://www.cnblogs.com/zzjder/archive/2008/10 ...

  6. 如何快速转载别人的CSDN博客文章并附带格式与图片

    1.问题背景 最近在学习Git过程中想了解git reflog命令的高级用法与命令详解,于是找到了这几篇特别优秀的文章: [1]使用git reflog 命令来查看历史提交记录并使用提交记录恢复已经被 ...

  7. 阮一峰老师博客爬取与博客文章存储持久化方式的思考

    阮一峰老师博客爬取与博客文章存储持久化方式的思考 前言 博客文章存储持久化思考 文本形式存储 html形式存储 pdf形式存储 博客爬取思路 爬取思路一 爬取思路二 个人选择 pdf存储 结尾 前言 ...

  8. 解决阮一峰老师博客广告拦截器问题

    在浏览器阮一峰老师博客时,存在广告拦截器,无法显示页面.如下: 这个问题是浏览器的adb广告拦截器插件导致的,只需要把该页面从adb插件中移除就可以. 具体操作为点击右上角插件按钮,取消该页面即可 关 ...

  9. 【机器学习】<刘建平Pinard老师博客学习记录>线性回归原理

    目录 一.线性回归的模型函数和损失函数: 二.线性回归的算法: 1.梯度下降法: 2.最小二乘法: 三.线性回归的推广:多项式回归 四.线性回归的推广:广义线性回归 五.线性回归的正则化: 一.线性回 ...

最新文章

  1. JS判断访问设备(userAgent)加载不同页面 JS判断客户端操作系统类型(platform)
  2. javaBean【02】javaBean与表单应用
  3. rest post put_REST / HTTP方法:POST与PUT与PATCH
  4. visio对象放入word显示不全_办公人士必学visio技能 手把手教你使用visio绘制项目全景图!...
  5. 小程序mpvue图片绘制水印_开发笔记:使用 mpvue 开发斗图小程序
  6. 重磅官宣:Nacos2.0发布,性能提升10倍
  7. phpcmsV9调用顶级父栏目的所有子栏目 - 调用总结
  8. 今晚直播 | PostgreSQL基于非易失性内存优化探索
  9. jQuery的表单验证
  10. 【编译工具】之gcc中-march与-arch的使用
  11. linux安装php7.3
  12. doip 源码_DoIP协议源码车载以太网诊断协议ISO13400协议c源码
  13. 没有基础怎么学习PLC编程?
  14. 解决WORD输出Html图片Jpg变模糊的问题
  15. 大岩量化小白科普:什么是量化交易?什么是宽客?
  16. Source Files 与 Resource Files 的区别
  17. HDU 5437by cyl优先队列
  18. 一个简单的app爬虫:对近期热播剧《三十而已》进行知乎app关键词搜索
  19. 使用LSTM完成简单的中英翻译
  20. 耳机断线了怎么修 耳机头部断线了如何修4线修复的方法

热门文章

  1. 为什么你的下一餐要交给机器人?
  2. org.apache.tomcat.util.descriptor.web.WebXml.setVersion Unknown version stri
  3. VS2019 MFC 对话框拆分窗格
  4. 推荐系统的评价指标总结
  5. 2017高二会考计算机考试时间,2017年高中期末考试时间通知
  6. SpringBoot整合MongoDB 及 基本使用
  7. 实现微信生活缴费功能详细讲解
  8. <C++> 通讯录管理系统(纯手写含源码)
  9. “熬夜导致秃头”,因果关系推断说这话有问题!
  10. 课时23 递归:这帮小兔崽子