自定义控件入门及案例
自定义控件一般分为2种: 1.组合控件 第1种形式:自定义一个类继承任意一个布局(XXLayout),然后复写它的构造方法,填充view,得到XML属性并设置属性。这 种形式我在上一篇文章已经详细讲到 http://4259297.blog.51cto.com/4249297/1683192 第2种形式:由Android原生的控件组合起来,配合动画实现的效果。 2.自定义控件: 控件之所以能由代码转换成视图展现在屏幕上,在底层主要会做3件事:测量(measure)、布局(layout)、绘制(draw),对应的 控件类的3个方法onMeasure、onLayout、onDraw 自定义控件也有3种形式 第1种:View控件继承View,需要复写测量(onMeasure)、绘制(onDraw)方法。因为View的摆放位置,是由它的父控件 ViewGroup来决定。测量是指测量自身的大小。 第2种:ViewGroup控件组,继承ViewGroup,需要复写测量(onMeasure)、布局(onLayout)两个方法。测量是指测量控件组里的 控件的大小,布局是指怎么摆它里面的控件。绘制就不需要复写了,因为这是由控件组里的控件来完成的。 第3种:升级控件,继承已有的Android控件,在它的基础之上再作一些修改。 下面就总结一下老师上课所讲的案例,作为对自定义控件抛砖引玉作用吧... 组合控件案例 案例1:优酷菜单 上面的这个动画录制得比较的粗糙,真实速度是没有这么快的。 1)素材和布局 优酷菜单分为三级,每一级采用的都是相对布局(因为菜单里的控件是沿着弧形摆放的),而且三个布局的三个上下的中 心在一条直线且在activity里水平居中。三个相对布局是相互叠加在一起的,所以最顶层的布局只能是相对布局或帧布局。 给3个布局由里到外取名为level1、level2、level3。 想要实现这样的效果,图片的尺寸是需要计算和设计的,且要为透明。 2)动画类的制作 分析可知,显示或隐藏动画是通过旋转动画来完成的,动画有重载形式(有延时与无延时),且动画之间是有关系的(动 画的个数统计,动画监听机制),所以动画应该写在一个类当中。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 /** *自定义动画工具类 *工具类不一定非要是静态的方法,静态虽然不用new,但是会有太多的限制。 *@authorLENOVO * */ public class MyAnimUtils{ public int runningAnimations= 0 ; MyAnimationListenerlistener= new MyAnimationListener(); //暴露方法-有没有动画正在运行 public boolean isRunningAnimation() { return runningAnimations!= 0 ; } //隐藏菜单动画 public boolean startHideAnimation(Contextcontext,Viewview){ return startHideAnimation(context,view, 0 ); } //隐藏菜单动画-延时 public boolean startHideAnimation(Contextcontext,Viewview, int startOffset){ //因为补间动画不会改变控件原有的坐标位置,虽然不可见了,但是还是可以点击。 //找到View里所有的控件,使它们不可用。 RelativeLayoutrl=(RelativeLayout)view; int childCount=rl.getChildCount(); for ( int i= 0 ;i<childCount;i++){ rl.getChildAt(i).setEnabled( false ); } AnimationhideAnimation=AnimationUtils.loadAnimation(context, R.anim.zero_to_fu180); hideAnimation.setStartOffset(startOffset); view.startAnimation(hideAnimation); //动画监听 hideAnimation.setAnimationListener(listener); return false ; //表示隐藏菜单 } //显示菜单动画 public boolean startShowAnimation(Contextcontext,Viewview){ return startShowAnimation(context,view, 0 ); } //显示菜单动画-延时 public boolean startShowAnimation(Contextcontext,Viewview, int startOffset){ //找到View里所有的控件,使它们可用。 RelativeLayoutrl=(RelativeLayout)view; int childCount=rl.getChildCount(); for ( int i= 0 ;i<childCount;i++){ rl.getChildAt(i).setEnabled( true ); } AnimationshowAnimation=AnimationUtils.loadAnimation(context, R.anim.fu180_to_zero); showAnimation.setStartOffset(startOffset); view.startAnimation(showAnimation); //动画监听 showAnimation.setAnimationListener(listener); return true ; //表示显示菜单 } //自定义动画监听类(自己监听自己) private class MyAnimationListener implements AnimationListener { @Override public void onAnimationStart(Animationanimation){ runningAnimations++; } @Override public void onAnimationRepeat(Animationanimation){ } @Override public void onAnimationEnd(Animationanimation){ runningAnimations--; } } } 3)显示或隐藏动画的布局和逻辑 第1步:初始化操作 实例动画类,findview,注册点击事件。 第2步:点击事件 ■menu(菜单)键的点击事件逻辑 如果第三级菜单level3隐藏/关闭,关闭/隐藏第三级菜单level3,且在关闭/隐藏动画未执行完之前,不会执行隐藏 /关闭动画。 升级控件,继承已有的Android控件 实际场景1: 拓展: 1。关于onDraw()方法不被执行的解决方法(setWillNotDraw),经常见到别人自定义控件的时候使用。 http://blog.csdn.net/look85/article/details/8442675 2.最简单也最难——如何获取到Android控件的高度 http://www.2cto.com/kf/201410/341592.html 3.Android 获得view的宽和高 http://blog.csdn.net/yangdeli888/article/details/25405263 4.AndroidgetWidth和getMeasuredWidth区别 http://blog.sina.com.cn/s/blog_4b93170a0102e2ns.html 本文转自屠夫章哥 51CTO博客,原文链接:http://blog.51cto.com/4259297/1688686,如需转载请自行联系原作者