博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 自定义View总结
阅读量:6821 次
发布时间:2019-06-26

本文共 3366 字,大约阅读时间需要 11 分钟。

昨夜雨疏风骤。浓睡不消残酒。试问卷帘人,却道“海棠依旧”。知否,知否?应是绿肥红瘦!

一首李清照的《如梦令·昨夜雨疏风骤》送给大家。

本篇博客只是一篇总结,自定义View往往和奇奇怪怪的需求相关。面对不断变化的需求,千万不能“死记硬背”,更重要的是要掌握自定义View的流程。

Android中每个控件都会在界面中占得一块矩形区域,这些控件大致被分为两类,即View控件和ViewGroup控件。ViewGroup控件可以包含多个View控件,并且能管理其包含的View控件。结构如下:

View结构图

1. 自定义View

1. View的测量     Android系统给我们提供了MeasureSpec类来帮助我们测量View,Measure是一个32位的int值。高2位为测量的模式,低30位为测量的大小。测量的模式可以分为以下三种:
  • EXACTLY 精确值模式。例如:android:layout_width="100dp|match_parent"
  • AT_MOST 最大值模式。例如:android:layout_width="wrap_content"控件的大小一般随着控件的子空间或内容的变化而变化,此时控件的尺寸只要不超过父控件允许的最大尺寸即可。
  • UNSPECIFIED 不指定其大小的测量模式。View想多大就多大,通常在绘制自定义View时使用。
    下面是一套通配的代码,可以作为模板使用。
@Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));    }    private int measureWidth(int widthMeasureSpec) {        int result = 0;        int specMode = MeasureSpec.getMode(widthMeasureSpec);        int specSize = MeasureSpec.getSize(widthMeasureSpec);        if (specMode == MeasureSpec.EXACTLY) {            result = specSize;        } else {            result = 200; //单位px            if (specMode == MeasureSpec.AT_MOST) {                result = Math.min(result, specSize);            }        }        return result;    }
2.在View中通常有以下一些比较重要的回调方法。
@Override     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        // 回调该方法进行测量    }    @Override    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {        super.onLayout(changed, left, top, right, bottom);        // 确定显示位置    }    @Override    protected void onDraw(Canvas canvas) { // 画布        super.onDraw(canvas);    }    @Override    public boolean onTouchEvent(MotionEvent event) { // 触摸事件        return super.onTouchEvent(event);    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) { // 组件大小改变时回调        super.onSizeChanged(w, h, oldw, oldh);    }    @Override    protected void onFinishInflate() { // 从XML加载组件后回调        super.onFinishInflate();    }
3. 三种方式实现自定义控件及一般步骤     1. 对已有控件进行拓展 ----> extends TextView      ` @Override         protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {            // 在回调父类方法前,实现自己的逻辑            super.onMeasure(widthMeasureSpec, heightMeasureSpec);            // 在回调父类方法后,实现自己的逻辑         }`     2. 通过组合控件来实现新的控件 ----> extends FrameLayout      1. new 元素      2. 设置属性(可以自定义属性)      3. 定义接口(若有需求)     3. 重写View实现全新控件 ----> extends View      1. onMeasure()      2. onLayout()(可选)      3. onDraw()      4. onTouchEvent()...      注:调用invalidate()方法进行重绘可实现动态效果。

自定义属性

1. 在res目录的values目录下创建一个attrs.xml文件。例如:
2. 获取自定义的属性
private void intView(AttributeSet attrs, Context context) {        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.topBar);        String titleTxt = a.getString(R.styleable.topBar_titleTxt);        float titleTxtSize = a.getDimension(R.styleable.topBar_titleTxtSize, 0);        a.recycle();    }
3. 指定XML命名空间
xmlns:dyk="http://schemas.android.com/apk/res/com.example.testandroid"dyk:titleTxt="test"

2. 自定义ViewGroup

自定义ViewGroup通常需要重写onMeasure()方法来对子View进行测量,重写onLayout()方法确定子View的位置,重写onToutchEvent()方法增加响应事件。    注:new对象时,调用一个参数的构造方法。未使用自定义属性时,调用两个参数的构造方法,使用自定义属性时调用三个参数的构造方法。
你可能感兴趣的文章
翻译WifiConfiguration类
查看>>
伍雨霏-懂游戏的云服务如何保驾护航
查看>>
Lua-5.3.2 安装 luasocket 的正确姿势
查看>>
MFC界面库BCGControlBar v25.1新版亮点四:网格控件等
查看>>
ssh 连接非22端口服务器的方法:
查看>>
Linux基础入门
查看>>
org.hibernate.hql.internal.ast.QuerySyntaxException: user is not mapped
查看>>
图解排序算法之快速排序-双端探测法
查看>>
mysql
查看>>
11月15日云栖精选夜读:分布式服务框架Dubbo疯狂更新!阿里开源要搞大事情?...
查看>>
Druid数据库连接池就这么简单
查看>>
Python最假的库:Faker
查看>>
IDE 插件新版本发布,开发效率 “biu” 起来了
查看>>
阿里云安全肖力:安全基础建设是企业数字化转型的基石
查看>>
Redis 基础、高级特性与性能调优
查看>>
BZT52C15S资料
查看>>
Laravel Telescope入门教程(上)
查看>>
Linux配置ip 及网络问题排查
查看>>
AndroidStudio用Cmake方式编译NDK代码(cmake配置.a库)
查看>>
OSChina 周四乱弹 ——黑丝短裙java程序员同事
查看>>