自定义控件在android开发中的重要性,是不言而喻,众人皆知的。希望通过这二天的学习,能让大家了解自定义控件的原理,熟悉自定义控件的使用步骤,并能写出一些普通的效果。
内容介绍:
1、使用系统控件,实现自定义的效果,案例有:
优酷环形菜单、广告条(Viewpager)、下拉菜单(spinner)
2、自己定义一个类继承View ,实现特定的效果,案例有:
自定义开关按钮、水波纹效果
3、自定义属性:给自己的控件,添加自己的属性,通过demo了解系统解析属性的过程,并给上一个例子开关按钮,添加新属性。
4、自己定义一个类继承ViewGroup,实现相应的效果,案例有:
仿ViewPager的效果实现 、 仿网易侧滑菜单
自定义控件
- 通过对android本身提供的控件的代码进行研究,android中控件都是继承view类来实现,通过重写ondraw方法来绘制我们所需要的控件.通过这个我们得到两点提示:
我们可以在已有的控件的基础上,通过重写相关方法来实现我们的需求.
继承view类或viewgroup类,来绘制我们所需要的控件.一般来讲,通过继承已有的控件,来自定义控件要简单一点 - 组合控件.(把很多android原生的控件组合起来, 达到某种效果叫组合效果.)==========优酷菜单+ViewPager
动画的执行不会影响控件的位置.
ViewPager: 预加载, 预先加载左右两边的item. 左边不可以加载-1索引, 右边不可以加载ViewPager的总长度.
预加载只会保留三个item对象.
自定义控件.(完全自己实现一个控件. 继承自View类和ViewGroup类实现某种特殊的效果.)
<!-- 设置子控件可以获取自己的区域的焦点, 但不可以抢占父类其他区域的焦点 -->
<!-- android:descendantFocusability="blocksDescendants" -->
Android中View的绘制流程(从创建到显示).
-
measure -> layout -> draw
测量宽和高 布局(排版) 绘制控件
| | |
onMeasure onLayout onDraw自定义开关:
1. onMeasure设置开关的宽度和高度: 背景图片的宽度和高度.
2. onDraw, 把背景和滑动块画在指定的位置.getX 获得的是相对于当前自己控件的x轴的坐标
getRowX 获得当前手指按下在屏幕中的x轴的值.
自定义属性:
1. 需要声明自定义属性.
在values下创建一个文件attrs.xml, 写一下内容:
<declare-styleable name="ToggleView">
<!-- 背景的属性 -->
<attr name="switchBackgroundID" format="reference" /><!-- 滑动块的属性 -->
<attr name="slideButtonBackgroundID" format="reference" /><!-- 开关的状态 -->
<attr name="toggleState" format="boolean" />
</declare-styleable>2. 在布局文件中引用自定义的属性.
1). 在根节点声明命名空间.
xmlns:itheima="http://schemas.android.com/apk/res/com.itheima30.togglebutton"
2). 在自定义控件中引用自定义属性.
itheima:switchBackgroundID="@drawable/switch_background"
itheima:slideButtonBackgroundID="@drawable/slide_button_background"
itheima:toggleState="false"3. 在自定义控件中取出自定义属性的值.
// 把属性集合(AttributeSet)中的属性和自定义属性(ToggleView)中相同的属性取出来
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ToggleView);
int indexCount = typedArray.getIndexCount(); // 获得当前属性集合自定义属性的数量
for (int i = 0; i < indexCount; i++) {
// 获取第i个属性在ToggleView自定义属性数组中的索引
int index = typedArray.getIndex(i);
switch (index) {
case R.styleable.ToggleView_switchBackgroundID: // 当前是背景的属性
// 获取布局文件中背景属性的值: 资源的id@drawable/
int switchBackgroundID = typedArray.getResourceId(index, -1);
setSwitchBackgroundID(switchBackgroundID); // 初始化了背景的图片
System.out.println("当前是背景的属性, 值为: " + switchBackgroundID);
break;
case R.styleable.ToggleView_slideButtonBackgroundID: // 当前是滑动块的属性
// 获取布局文件中滑动块属性的值: 资源的id@drawable/
int slideButtonBackgroundID = typedArray.getResourceId(index, -1);
setSlideButtonBackgroundID(slideButtonBackgroundID); // 初始化了滑动块的图片
System.out.println("当前是滑动块的属性, 值为: " + slideButtonBackgroundID);
break;
case R.styleable.ToggleView_toggleState: // 当前是开关状态的属性
currentToggleState = typedArray.getBoolean(index, false);
System.out.println("当前是开关状态的属性, 值为: " + currentToggleState);
break;
default:
break;
}
}