前言:

在日常的Android开发中会经常和控件打交道,有时Android提供的控件未必能满足业务的需求,这个时候就需要我们实现自定义一些控件,今天先大致了解一下自定义控件的要求和实现的基本原理。

自定义控件要求:

1. 应当遵守Android标准的规范(命名,可配置,事件处理等)。

2. 在XML布局中可配置控件的属性。

3. 对交互应当有合适的反馈,比如按下,点击等。

4. 具有兼容性, Android版本很多,应该具有广泛的适用性。

自定义控件学习步骤:

1 .View的工作原理

2 .编写View类

3.为View类增加属性

4 .绘制屏幕

5. 响应用户消息

6 .自定义回调函数

自定义控件两种方式:

1. 继承ViewGroup

例如:ViewGroup、LinearLayout、FrameLayout、RelativeLayout等。

2. 继承View

例如:View、TextView、ImageView、Button等。

自定义控件基本绘制原理:

View的绘制基本上由measure()、layout()、draw()这个三个函数完成

1.)测量-Measure过程是计算视图大小,View measure过程相关方法主要有三个:

protected final void setMeasuredDimension(int measuredWidth, int measuredHeight)

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)

measure调用onMeasure,onMeasure测量宽度、高度然后调用setMeasureDimension保存测量结果,measure,setMeasureDimension是final类型,view的子类不需要重写,onMeasure在view的子类中重写。

关于MeasureSpec:

(1) UPSPECIFIED :父容器对于子容器没有任何限制,子容器想要多大就多大.

(2) EXACTLY父容器已经为子容器设置了尺寸,子容器应当服从这些边界,不论子容器想要多大的空间.

(3) AT_MOST子容器可以是声明大小内的任意大小.

2.)布局-Layout过程用于设置视图在屏幕中显示的位置,View layout过程相关方法主要要三个:

protected boolean setFrame(int left, int top, int right, int bottom)

protected void onLayout(boolean changed, int left, int top, int right, int bottom)

layout通过调用setFrame(l,t,r,b),l,t,r,b即子视图在父视图中的具体位置,onLayout一般只会在自定义ViewGroup中才会使用

3.)绘制-draw过程主要用于利用前两步得到的参数,将视图显示在屏幕上,到这里也就完成了整个的视图绘制工作。

protected void onDraw(Canvas canvas)

通过调用draw函数进行视图绘制,在View类中onDraw函数是个空函数,最终的绘制需求需要在自定义的onDraw函数中进行实现,比如ImageView完成图片的绘制,如果自定义ViewGroup这个函数则不需要重载。

自定义控件示例:

这里先介绍继承View的方式为例,其实ViewGroup最终的继承的也是View。这里 模拟一个需求场景,需要一个圆形显示百分比。

private final static String TAG = PercentView.class.getSimpleName();

private Paint mPaint;

private RectF oval;

public PercentView(Context context) {

super(context);

init();

}

public PercentView(Context context, AttributeSet attrs) {

super(context, attrs);

init();

}

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

super(context, attrs, defStyleAttr);

init();

}

private void init(){

mPaint = new Paint();

mPaint.setAntiAlias(true);

oval=new RectF();

}

@Override

protected 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);

Log.e(TAG, "onMeasure--widthMode-->" + widthMode);

switch (widthMode) {

case MeasureSpec.EXACTLY:

break;

case MeasureSpec.AT_MOST:

break;

case MeasureSpec.UNSPECIFIED:

break;

}

Log.e(TAG, "onMeasure--widthSize-->" + widthSize);

Log.e(TAG, "onMeasure--heightMode-->" + heightMode);

Log.e(TAG, "onMeasure--heightSize-->" + heightSize);

}

@Override

protected void onLayout(boolean changed, int left, int top, int right, int bottom) {

super.onLayout(changed, left, top, right, bottom);

Log.e(TAG, "onLayout");

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

mPaint.setColor(Color.GRAY);

// FILL填充, STROKE描边,FILL_AND_STROKE填充和描边

mPaint.setStyle(Paint.Style.FILL_AND_STROKE);

int with = getWidth();

int height = getHeight();

Log.e(TAG, "onDraw---->" + with + "*" + height);

float radius = with / 4;

canvas.drawCircle(with / 2, with / 2, radius, mPaint);

mPaint.setColor(Color.BLUE);

oval.set(with / 2 - radius, with / 2 - radius, with / 2

+ radius, with / 2 + radius);//用于定义的圆弧的形状和大小的界限

canvas.drawArc(oval, 270, 120, true, mPaint); //根据进度画圆弧

}

}

在布局中如何使用

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical">

android:layout_width="150dp"

android:layout_height="150dp"

android:layout_margin="10dp" />

总结:

本篇主要介绍Android自定义控件的基本绘制原理,后面会介绍如何自定义属性。

android自定义view实现原理,android随笔之自定义View基本原理相关推荐

  1. android动画的实现原理,Android动画的实现原理 .

    1.动画运行模式 独行模式 中断模式 2.Animation类 每个动画都重载了父类的applyTransformation方法这个方法的主要作用是把一些属性组装成一个Transformation类, ...

  2. android qq功能实现原理,Android QQ、微信聊天消息界面设计原理与实现

     Android QQ.微信聊天消息界面设计原理与实现 原理:Android平台上,典型的以腾讯的QQ.微信这些聊天消息界面通常可以采用ListView设计与实现,需要使用ListView 适配器 ...

  3. View工作原理(二)导致View重建原因

    导致View重建的原因有三个: 1.视图本身内部状态变化引起重绘: 2.view树内部添加或者删除子view: 3.View本身的大小及可见性发生变化. 这三种情况最后都直接或者间接的调用到了三个方法 ...

  4. Android病毒查杀原理,Android编程之杀毒的实现原理及具体实例

    本文实例讲述了Android杀毒的实现原理.分享给大家供大家参考,具体如下: 一个杀毒软甲最核心的部分一个是病毒库一个是杀毒引擎,病毒库从服务器中获得,杀毒引擎实际上是判断程序中的包名和签名是否匹配病 ...

  5. Android中AMS工作原理,Android AMS启动详解

    启动 在Android系统启动流程中中我们提到过,AMS是在system_service中启动的, //frameworks/base/services/java/corri/android/serv ...

  6. android群聊红包原理,Android之微信抢红包实现原理分析

    微信抢红包主要用到AccessibilityService,该服务需要用户手动到辅助功能里面授权,下面直接粘贴源码,先看Activity,主要是跳转到辅助功能界面,让用户开启辅助功能的服务: publ ...

  7. android护眼程序原理,Android 护眼模式的实现

    思路:获取content根布局,在上面添加一层浮层,默认透明,开启护眼模式设置护眼色值. 实现:在BaseActivity的onCreate方法中,添加浮层,所有的Activity继承BaseActi ...

  8. android 系统截屏原理,Android 系统副屏截屏功能

    收到一个客户需求,要求对双屏设备的副屏进行截图.查询资料后发现,系统截图有两种方法,一种是通过SurfaceControl.screenshot提供的接口调用,还有一种是通过screencap 命令获 ...

  9. android省电模式 原理,Android省电模式侦听器?

    所以你只需要接受它: 的AndroidManifest.xml: PowerSaveModeReceiver.java: public class PowerSaveModeReceiver exte ...

最新文章

  1. 特征值和特征向量的实际意义
  2. android小程序源代码_我从 Android 转到微信小程序的思考
  3. rpm卸载mysql和php_Linux系统中自带Mysql、Apache、Php卸载
  4. python爬虫如何从一个页面进入另一个页面-爬虫入门(一)——如何打开一个网页...
  5. ORG.SPRINGFRAMEWORK.HTTP.CONVERTER.HTTPMESSAGENOTREADABLEEXCEPTION: COULD NOT READ JSON: UNRECOGNIZE
  6. nginx学习十 ngx_cycle_t 、ngx_connection_t 和ngx_listening_t
  7. php url地址 怎么写,php url地址重写
  8. LeetCode 1814. 统计一个数组中好对子的数目(哈希)
  9. kafka集群下载、启动、部署、测试
  10. 2022年百度新能源汽车行业洞察
  11. Bootstrap3.0 栅格系统背后的精妙魔法(Bootstrap3.0的栅格布局系统实现原理) - willian12345...
  12. linux安装qq_体验一下,看看 Linux 系统中的 QQ 是什么样子的
  13. springboot集成oauth2和JWT(授权码模式)
  14. 互利的关系方能长久,可惜大部分人就是不懂
  15. [Visual Studio] 重置默认设置 还原默认设置
  16. vivado之FFT ip核的入门学习
  17. Mysql中select into from用法
  18. 利用Python爬虫爬取淘宝商品做数据挖掘分析实战篇,超详细教程!
  19. 后台管理系统(第一天)
  20. [cocos2d-iphone]ios6截图问题

热门文章

  1. 牛客网--蘑菇街2016研发工程师编程题
  2. Oracle中如何判断字符串是否全为数字
  3. [转载]Java数组扩容算法及Java对它的应用
  4. 软件工程学习进度06
  5. 中文字体字号和磅数的转化
  6. python 字符集编码设置(精华)
  7. 计算机学院科技活动策划,计算机学院科技创新活动策划书(7页)-原创力文档...
  8. pix4d无人机影像处理_让无人机创造更大价值?你还差一个Pix4D培训会!
  9. C++静态数据成员与静态函数(案例分析)
  10. Python之进程+线程+协程(multiprocessing多进程模块)