/** * 作者:David Zheng on 2015/11/7 15:38 * *网站:http://www.93sec.cc * *微博:http://weibo.com/mcxiaobing * *微博:http://weibo.com/93sec.cc */ 个人交流QQ986945193
前言
- 课程介绍
- 自定义控件在android相当重要。要求:大家熟悉自定义控件的原理,熟悉自定义控件的使用步骤。
- 按类型划分,自定义View的实现方式可分为三种:自绘控件、组合控件、以及继承控件。
- 如何让自定义的View在界面上显示出来? 只需要像使用普通的控件一样来使用自定义View就可以了。
- 1,回顾系统的一些控件 ,Viewpager广告条的展示
- 2,介绍View的绘制过程
- 3,自定义View:开关Button
- 4,自定义属性
- 5,组合控件:标题栏
- 6,继承系统控件:ListView刷新加载的原理等
- 自定义控件在android相当重要。要求:大家熟悉自定义控件的原理,熟悉自定义控件的使用步骤。
- 系统控件
- 心中要有一个View树
一,自定义View:
- 概念:自绘控件的意思就是,这个View上所展现的内容全部都是自己绘制出来的。
- 自绘控件的步骤:
- 实现构造方法
- onMeasure(int ,int)中调用onMeasureDimention() 进行测量
- onDraw(Canvas)方法进行绘制View
- 实现onTouchEvent(MotionEvent ev)方法,对touch事件进行解析
- 一些API:
- 绘制View主要是onDraw()方法中完成。通过参数Canvas来处理,相关的绘制主要有drawRect、drawLine、drawPath等等。
-
Canvas绘制的常用方法:
- drawColor() 填充颜色
- drawLine() 绘制线
- drawLines() 绘制线条
- drawOval() 绘制椭圆
- drawPaint() 画笔绘制
- drawPath() 绘制路径
- drawPicture() 绘制图片
- drawPoint() 绘制点
- drawPoints() 绘制点
- drawRGB() 填充颜色
- drawRect() 绘制矩形
- drawText() 绘制文本
- drawTextOnPath() 在路径上绘制文本
- 2、刷新View :(刷新view的方法这里主要有:)
- invalidate(int l,int t,int r,int b)
- 刷新局部,四个参数分别为左、上、右、下
- invalidate()
- 整个view刷新。执行invalidate类的方法将会设置view为无效,最终重新调用onDraw()方法。
- invalidate()是用来刷新View的,必须是在UI线程中进行工作。在修改某个view的显示时,调用invalidate()才能看到重新绘制的界面。invalidate()的调用是把之前的旧的view从主UI线程队列中pop掉。
- invalidate(Rect dirty)
- 刷新一个矩形区域
- invalidate(int l,int t,int r,int b)
二,组合控件
- 概念: 组合控件的意思就是,不需要自己去绘制视图上显示的内容,而只是用系统原生的控件就好了,但可以将几个系统原生的控件组合到一起,这样创建出的控件就被称为组合控件。
- 例如:标题栏就是个很常见的组合控件,很多界面的头部都会放置一个标题栏,标题栏上会有个返回按钮和标题,点击按钮后就可以返回到上一个界面。那么下面我们就来尝试去实现这样一个标题栏控件。
三,继承控件:
- 概念: 继承控件的意思就是,我们并不需要自己重头去实现一个控件,只需要去继承一个现有的控件,然后在这个控件上增加一些新的功能,就可以形成一个自定义的控件了。这种自定义控件的特点就是不仅能够按照我们的需求加入相应的功能,还可以保留原生控件的所有功能,比如 Android PowerImageView实现,可以播放动画的强大ImageView 就是一个典型的继承控件。
- 例如:对ListView进行扩展, 加入在ListView上滑动就可以显示出一个删除按钮,点击按钮就会删除相应数据的功能。或者刷新加载的ListView
一些重要的补充:
1,通用的布局,再抽出来一个布局,命名规则:layout开头。栗子:layout_title.xml ; 如何引用 : <include layout="@layout/layout_tilte" />
------------------------------------------------------华丽丽的分割线 - 咯咯咯--------------------------------------------------
功能案例
系统重要控件的展示:Viewpager
- 步骤:
2,描述的联动
3,点的联动
4,无限循环的实现
5,自动播放,动画效果的实现
自定义开关按钮:
- 步骤:
- 1,自定义类继承自View
- 2,重写onMeasure方法,设置View的大小
- 3,重写onDraw方法,绘制View的内容
- 4,重写onTouchEvent事件,对touch事件进行解析
自定义属性:
1. 在attrs.xml文件中声明属性,
如:<declare-styleable name="MyToggleBtn"> // 声名属性集的名称,即这些属性是属于哪个控件的。
<attr name="current_state" format="boolean"/> // 声名属性 current_state 格式为 boolean 类型
<attr name="slide_button" format="reference"/> // 声名属性 slide_button 格式为 reference 类型
</declare-styleable> 所有的format类型,详见注1:
2, 在布局文件中使用:在使用之前必须声名命名空间,
xmlns:zhaokeming="http://schemas.android.com/apk/res/com.zhaokeming.mytogglebtn"
说明:① xmlns 是XML name space 的缩写; ② zhaokeming 可为任意写符 ③ http://schemas.android.com/apk/res/ 此为
android固定格式; ④com.zhaokeming.mytogglebtn 此应用的包名,如manifest配置文件中一致。 布局文件:
<com.zhaokeming.mytogglebtn.MyToggleButton xmlns:heima="http://schemas.android.com/apk/res/com.zhaokeming.mytogglebtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
heima:slide_button="@drawable/slide_button" />
3 ,在代码中对属性进行解析,主要代码:
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyToggleBtn); // 由attrs 获得 TypeArray
可以查看,View 自己定义的属性 怎么初始化的。。。
注1: format 常用类型: reference 引用 color 颜色
boolean 布尔值 dimension 尺寸值 float 浮点值 integer 整型值 string 字符串 enum 枚举
组合控件-标题栏:
- 重要的知识点:
- 1,去掉标题: requestWindowFeature(Window.FEATURE_NO_TITLE); 必须在setContentView()方法执行前
- 2,相同的布局,可以抽出来一个layout_xxx.xml 。 引用 <include layout="@layout/layout_xxx">
- 3 ,定义相同控件的功能时,就可以抽出来一个 自定义组合控件
- 步骤:
- 1,继承一个layout_xxx.xml布局的最外面的 布局,比如 LinearLayout,RelativeLayout等等
- 2, // inflate:把xml布局文件,转换成 View对象 ;把xml文件转换成的View对象,然后赋值给当前的类。 ;当前的类,就相当于View对象 ;通过调用这个 View.inflate(mContext, R.layout.layout_xxx, this);
- 3,把控件初始化,添加相应的功能
自定义ListView的刷新:
- 步骤:
- 1,
- 注意事项:
- 1,
- addHeaderView(View v) : 在ListView的头部,添加一个View ; 这个方法必须在 setAdapter()之前调用;
- addFooterView(v): 在ListView的底部添加view
- 2,
- getHeight(): 在执行完onLayout()方法后,才会执行
- getMeasuredHeight(); 在onMeasure()方法后,就执行;
- 实现步骤:
- mViewHeader.measure(0, 0);// 通知系统,执行测量工作
- mHeaderHeight = mViewHeader.getMeasuredHeight(); // 获得测量的高度
- 1,
/** * 作者:David Zheng on 2015/11/7 15:38 * *网站:http://www.93sec.cc * *微博:http://weibo.com/mcxiaobing * *微博:http://weibo.com/93sec.cc */ 个人交流QQ986945193