Android常见的自定义控件有三种方式:

继承View

继承原有的控件,在原有控件的基础上进行修改

重新拼装组合

今天先来简单说一说第一种也是最复杂的一种~~ 剩下的下次再说~~

继承View,重写onDraw方法,但是注意采用这种方式需要自己在代码中来支持熟悉的wrap_content、padding属性。

1、想好需要自定义的属性,在values下创建一个attrs.xml,这里我就演示一个简单的颜色,自定义一个属性集合,命名为CustomView,有一个格式为color的属性custom_color

2、自定义View

public class CustomView extends View {

private Paint mPaint = new Paint();// 创建一个画笔;

private int mColor = Color.RED; //默认为红色

public CustomView(Context context) {

super(context);

}

public CustomView(Context context, AttributeSet attrs) {

super(context, attrs);

}

public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

//加载自定义属性集合CustomView

TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomView);

//解析CustomView中自定义的属性custom_color,id为R.styleable.CustomView_custom_color,如果没有就默认为红色

mColor = a.getColor(R.styleable.CustomView_custom_color, Color.RED);

//释放资源,方便下次使用

a.recycle();

//初始化画笔的参数

mPaint.setColor(mColor);// 设置画笔颜色

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

canvas.drawCircle(100, 100, 50, mPaint);// 用画笔在画布上添加一个圆

}

}

3、布局中使用,注意这里使用的时候一定要用全类名,要想用自定义属性,必须在布局中加入如下代码,这样自定义属性就可以用app打头:

xmlns:app="http://schemas.android.com/apk/res-auto"

设置宽高为match_parent,并设置了背景色和自定颜色

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="#123456"

app:custom_color="#000000" />

4、运行效果图

自定义View1.png

显示的是一个青色的背景和一个黑色的圆

5、注意:

这种方式无论怎么设置padding的值或者更改宽和高为wrap_content,执行效果都如上,原因就如开头所说,需要自己处理,那么如何处理呢?

(1) 处理padding

在android:layout_width 和 android:layout_height 都为 match_parent 时,我们考虑一下左边和上边的padding

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="#123456"

android:paddingLeft="100dp"

android:paddingTop="100dp"

app:custom_color="#000000" />

在onDraw()方法中设置padding

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

int paddingLeft = getPaddingLeft();

int paddingTop = getPaddingTop();

canvas.drawCircle(paddingLeft + 100, paddingTop + 100, 50, mPaint);

}

运行效果:

自定义View2.png

(2)处理wrap_content

为什么要单独处理wrap_content呢?这和View的工作原理有关,View经过measure、layout和draw显示出来,其中measure时需要用到MeasureSpec的变量(包含SpecMode和SpecSize),其中SpecSize指定了特定测试模式下的大小,SpecMode指定了测量的模式,分为三类:

UNSPECIFIED

父容器对View无任何限制,一般用于系统内部

EXACTLY

View的最终大小就是SpecSize指定的值,适用于指定具体大小和match_parent的形式

AT_MOST

父容器指定了一个SpecSize,View不能超过它,适用于wrap_content

当使用wrap_content时,SpecSize其实就是父容器中可用空间的大小,即View的宽和高等于父容器当前剩余的当前剩余空间大小,和使用match_parent一样,那么怎么处理?也很简单,只要重写onMeasure方法,在AT_MOST模式时,设置一个具体的宽高即可:

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

//获取宽和高的SpecMode和SpecSize

int wSpecMode = MeasureSpec.getMode(widthMeasureSpec);

int wSpecSize = MeasureSpec.getSize(widthMeasureSpec);

int hSpecMode = MeasureSpec.getMode(heightMeasureSpec);

int hSpecSize = MeasureSpec.getSize(heightMeasureSpec);

//分别判断宽高是否设置为wrap_content

if (wSpecMode == MeasureSpec.AT_MOST && hSpecMode == MeasureSpec.AT_MOST) {

//宽高都为wrap_content,直接指定为400

setMeasuredDimension(400, 400);

} else if (wSpecMode == MeasureSpec.AT_MOST) {

//只有宽为wrap_content,宽直接指定为400,高为获取的SpecSize

setMeasuredDimension(400, hSpecSize);

} else if (hSpecMode == MeasureSpec.AT_MOST) {

//只有高为wrap_content,高直接指定为400,宽为获取的SpecSize

setMeasuredDimension(wSpecSize, 400);

}

}

此时布局如下:

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:background="#123456"

android:paddingLeft="50dp"

android:paddingTop="50dp"

app:custom_color="#000000" />

运行效果:

自定义View3.png

android自定义view凯,Android开发之自定义View(一)相关推荐

  1. Android开发-自定义View-AndroidStudio(二十八)缩放的View

    转载请注明出处: http://blog.csdn.net/iwanghang/ 觉得博文有用,请点赞,请评论,请关注,谢谢!~ 继续上一篇博文,移动的View,我们来一下自定义View如何缩放: 老 ...

  2. Android开发,自定义View的学习合集

    转载自:http://blog.csdn.net/u011507982/article/details/51199644 自定义控件学习  https://github.com/GcsSloop/An ...

  3. 【Android 应用开发】自定义View 和 ViewGroup

    一. 自定义View介绍 自定义View时, 继承View基类, 并实现其中的一些方法. (1) ~ (2) 方法与构造相关 (3) ~ (5) 方法与组件大小位置相关 (6) ~ (9) 方法与触摸 ...

  4. Android开发之自定义view进行旋转动画

    老套路先上图: 整个view非常简单,我自定义view里面都有详细的注释说明 先看自定义view部分代码: package cn.xiayiye5.customizestudy.view;import ...

  5. 【安卓开发 】Android初级开发(五)自定义View

    1.自定义View的构造函数调用的场景 package com.sina.myapplication;import android.content.Context; import android.ut ...

  6. Android仿支付宝UI功能开发,Android 自定义view仿支付宝咻一咻功能

    支付宝上有一个咻一咻的功能,就是点击图片后四周有水波纹的这种效果,今天也写一个类似的功能. 效果如下所示: 思路: 就是几个圆的半径不断在变大,这个可以使用动画缩放实现,还有透明动画 还有就是这是好几 ...

  7. Android开发之自定义View(一)

    Android常见的自定义控件有三种方式: 继承View 继承原有的控件,在原有控件的基础上进行修改 重新拼装组合 今天先来简单说一说第一种也是最复杂的一种~~ 剩下的下次再说~~ 继承View,重写 ...

  8. Android开发之自定义SurfaceView绘制动效音波图 | 动效音阶图 | Android自定义View

    老套路献上图: 第一张是通过播放歌曲拿到歌曲播放的数据进行动态展示的 第二张是通过定时器随机生成的数据动态展示的 先说下这个自定义view也不难很简单,就是绘制矩形,唯一的难点在于计算矩形的坐标 说下 ...

  9. Android开发之自定义View

    目录 一.View的简介 1.1 View的构造函数 1.2 View的绘制流程图 二.自定义View 2.1 onMeasure()方法 2.2 OnDraw()方法 一.View的简介 View类 ...

最新文章

  1. Python快速学习10: 循环的对象及设计 (生活的规律)
  2. python和c学习-关于本站 - cPython - 给大学生的入门教程
  3. 007_Vue style样式绑定
  4. C语言用数组(顺序表)实现大小固定的队列的方法
  5. TeamCity工件:HTTP,Ant,Gradle和Maven
  6. sudo apt-get nmap 报错锁占用
  7. 大势所趋与各具特色 超融合市场玩家大盘点
  8. 什么是事件?JS中都有哪些事件?
  9. 雷林鹏分享:Lua 面向对象
  10. 【CV】如何使用Tensorflow提供的Object Detection API--3--手工标注数据
  11. php PHP命令行脚本接收传入参数的三种方式
  12. Java基础程序设计的报告
  13. win98装python_Windows 上的 Python安装
  14. 安卓手机修改ip软件_为什么苹果手机不用杀毒软件?安卓表示要哭了
  15. 芯片行业常用英文术语最详细总结(图文快速掌握)
  16. 完美解决Excel复制后粘贴空白的问题
  17. Python实用案例,Python脚本实现玩转emoji,我微又“偷偷”更新这个表情!
  18. excel插件开发,Smartbi免费版安装流程
  19. 一个身居中国的法国程序员谈Python与PHP
  20. 《我是一只IT小小鸟》连载四

热门文章

  1. VS2015开发OpenDDS实例(ACE_TAO_6.5.10+OpenDDS_3.12+ActivePerl-5.28)
  2. 日历签到 java_Java实现按年月打印日历功能【基于Calendar】
  3. 虚拟服务器C盘备份,电脑换主机怎么备份_电脑换主机c盘怎么备份
  4. 万字综述:行业知识图谱构建最新进展
  5. 基于用户标签的活跃人群特征分析_用户特征分析(行为分析是关键)
  6. python结合json,双倍的快乐
  7. P2709 小B的询问 莫队入门
  8. flask 下载文件
  9. 腾讯创始人Tony谈产品人的信仰:最难的是克制和敬畏心
  10. Vue 中使用 Tinymce 富文本编辑器