自定义控件入门及案例

自定义控件一般分为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:优酷菜单

        wKioL1XeRbeB7_VhAAZxXQBbtrc587.gif

        

        上面的这个动画录制得比较的粗糙,真实速度是没有这么快的。

            1)素材和布局

                   wKioL1XeSgWx-s08AABx2sHbE6E983.jpg   

               优酷菜单分为三级,每一级采用的都是相对布局(因为菜单里的控件是沿着弧形摆放的),而且三个布局的三个上下的中

            心在一条直线且在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,但是会有太多的限制。
      * @author LENOVO
     
      */
     
     
     public  class  MyAnimUtils {
       public  int  runningAnimations =  0 ;
       MyAnimationListener listener =  new  MyAnimationListener();
       
     //暴露方法-有没有动画正在运行
       public  boolean  isRunningAnimation()
       {
           return  runningAnimations !=  0 ;
       }
       
       
       
     // 隐藏菜单动画
     public   boolean  startHideAnimation(Context context, View view) {
         return  startHideAnimation(context, view,  0 );
     }
 
     // 隐藏菜单动画-延时
     public   boolean  startHideAnimation(Context context, View view,
             int  startOffset) {
         
         //因为补间动画不会改变控件原有的坐标位置,虽然不可见了,但是还是可以点击。
         // 找到View里所有的控件,使它们不可用。
         RelativeLayout rl = (RelativeLayout) view;
         int  childCount = rl.getChildCount();
         for  ( int  i =  0 ; i < childCount; i++) {
             rl.getChildAt(i).setEnabled( false );
         }
 
         Animation hideAnimation = AnimationUtils.loadAnimation(context,
                 R.anim.zero_to_fu180);
         hideAnimation.setStartOffset(startOffset);
         view.startAnimation(hideAnimation);
         // 动画监听
         hideAnimation.setAnimationListener(listener);
         return  false // 表示隐藏菜单
     }
 
     // 显示菜单动画
     public   boolean  startShowAnimation(Context context, View view) {
         return  startShowAnimation(context, view,  0 );
     }
 
     // 显示菜单动画-延时
     public   boolean  startShowAnimation(Context context, View view,
             int  startOffset) {
 
         // 找到View里所有的控件,使它们可用。
         RelativeLayout rl = (RelativeLayout) view;
         int  childCount = rl.getChildCount();
         for  ( int  i =  0 ; i < childCount; i++) {
             rl.getChildAt(i).setEnabled( true );
         }
 
         Animation showAnimation = 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(Animation animation) {
             runningAnimations++;
         }
 
         @Override
         public  void  onAnimationRepeat(Animation animation) {
 
         }
 
         @Override
         public  void  onAnimationEnd(Animation animation) {
             runningAnimations--;
         }
     }
     
     }

            3)显示或隐藏动画的布局和逻辑

            第1步:初始化操作

                实例动画类,findview,注册点击事件。

            第2步:点击事件

              ■menu(菜单)键的点击事件逻辑

                 如果第三级菜单level3隐藏/关闭,关闭/隐藏第三级菜单level3,且在关闭/隐藏动画未执行完之前,不会执行隐藏

                /关闭动画。

                



升级控件,继承已有的Android控件 

  实际场景1:




拓展:

1。关于onDraw()方法不被执行的解决方法(setWillNotDraw),经常见到别人自定义控件的时候使用。

  http://blog.youkuaiyun.com/look85/article/details/8442675


2.最简单也最难——如何获取到Android控件的高度

 http://www.2cto.com/kf/201410/341592.html  


3.Android 获得view的宽和高

    http://blog.youkuaiyun.com/yangdeli888/article/details/25405263

4.Android getWidth和getMeasuredWidth 区别

    http://blog.sina.com.cn/s/blog_4b93170a0102e2ns.html







      本文转自屠夫章哥  51CTO博客,原文链接:http://blog.51cto.com/4259297/1688686,如需转载请自行联系原作者




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值