【0055】自定义控件-2-组合已有控件实现自定义控件-优酷菜单

1.优酷菜单的界面效果及代码书写步骤

1.1 优酷菜单的界面效果

【说明】优酷菜单的控件布局使用从内向外的方式进行布局;

命名的方式是从内到外依次是level1-level3

1.2 代码书写步骤

 

2.界面初始化

2.1 level1-3的布局-使用相对布局

【1】图片的宽高可以直接写死;

【2】即使level2的图片覆盖在level1 的图片上,因为此图片是透明的 ,因此不会妨碍点击事件;

2.2.level1-3中的图片按钮的添加

2.2.1 图片按钮中的背景的处理

【处理方法1】

【处理方法2】

 

2.3【布局源码】

  1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2     xmlns:tools="http://schemas.android.com/tools"
  3     android:layout_width="match_parent"
  4     android:layout_height="match_parent"
  5     tools:context=".MainActivity" >
  6 
  7     <RelativeLayout
  8         android:id="@+id/rl_level1"
  9         android:layout_width="100dp"
 10         android:layout_height="50dp"
 11         android:layout_alignParentBottom="true"
 12         android:layout_centerHorizontal="true"
 13         android:background="@drawable/level1" >
 14 
 15         <ImageButton
 16             android:id="@+id/ib_home"
 17             android:layout_width="wrap_content"
 18             android:layout_height="wrap_content"
 19             android:layout_centerInParent="true"
 20             android:background="@null"
 21             android:src="@drawable/icon_home" />
 22     </RelativeLayout>
 23 
 24     <RelativeLayout
 25         android:id="@+id/rl_level2"
 26         android:layout_width="180dp"
 27         android:layout_height="90dp"
 28         android:layout_alignParentBottom="true"
 29         android:layout_centerHorizontal="true"
 30         android:background="@drawable/level2" >
 31         
 32         <ImageButton
 33             android:id="@+id/ib_menu"
 34             android:layout_width="wrap_content"
 35             android:layout_height="wrap_content"
 36             android:layout_centerHorizontal="true"
 37             android:background="@null"
 38             android:layout_marginTop="5dp"
 39             android:src="@drawable/icon_menu" />
 40         
 41         
 42         <ImageButton
 43             android:layout_width="wrap_content"
 44             android:layout_height="wrap_content"
 45             android:layout_alignParentBottom="true"
 46             android:layout_alignParentLeft="true"
 47             android:layout_marginLeft="10dp"
 48             android:layout_marginBottom="5dp"
 49             android:background="@null"
 50             android:src="@drawable/icon_search" />
 51         
 52         <ImageButton
 53             android:layout_width="wrap_content"
 54             android:layout_height="wrap_content"
 55             android:layout_alignParentBottom="true"
 56             android:layout_alignParentRight="true"
 57             android:layout_marginRight="10dp"
 58             android:layout_marginBottom="5dp"
 59             android:background="@null"
 60             android:src="@drawable/icon_myyouku" />
 61         
 62     </RelativeLayout>
 63 
 64     <RelativeLayout
 65         android:id="@+id/rl_level3"
 66         android:layout_width="280dp"
 67         android:layout_height="140dp"
 68         android:layout_alignParentBottom="true"
 69         android:layout_centerHorizontal="true"
 70         android:background="@drawable/level3" >
 71 
 72         <ImageButton
 73             android:layout_width="wrap_content"
 74             android:layout_height="wrap_content"
 75             android:layout_alignParentBottom="true"
 76             android:layout_alignParentLeft="true"
 77             android:layout_marginLeft="10dp"
 78             android:layout_marginBottom="5dp"
 79             android:background="@null"
 80             android:src="@drawable/channel1" />
 81         
 82         <ImageButton
 83             android:layout_width="wrap_content"
 84             android:layout_height="wrap_content"
 85             android:layout_marginLeft="30dp"
 86             android:layout_marginTop="60dp"
 87             android:background="@null"
 88             android:src="@drawable/channel2" />
 89         <ImageButton
 90             android:layout_width="wrap_content"
 91             android:layout_height="wrap_content"
 92             android:layout_marginLeft="65dp"
 93             android:layout_marginTop="25dp"
 94             android:background="@null"
 95             android:src="@drawable/channel3" />
 96         
 97         <ImageButton
 98             android:layout_width="wrap_content"
 99             android:layout_height="wrap_content"
100             android:layout_centerHorizontal="true"
101             android:background="@null"
102             android:layout_marginTop="5dp"
103             android:src="@drawable/channel4" />
104         
105         
106         <ImageButton
107             android:layout_width="wrap_content"
108             android:layout_height="wrap_content"
109             android:layout_alignParentRight="true"
110             android:background="@null"
111             android:layout_marginRight="30dp"
112             android:layout_marginTop="60dp"
113             android:src="@drawable/channel5" />
114         
115         <ImageButton
116             android:layout_width="wrap_content"
117             android:layout_height="wrap_content"
118             android:layout_marginRight="65dp"
119             android:layout_marginTop="25dp"
120             android:layout_alignParentRight="true"
121             android:background="@null"
122             android:src="@drawable/channel6" />
123         
124         <ImageButton
125             android:layout_width="wrap_content"
126             android:layout_height="wrap_content"
127             android:layout_alignParentBottom="true"
128             android:layout_alignParentRight="true"
129             android:layout_marginRight="10dp"
130             android:layout_marginBottom="5dp"
131             android:background="@null"
132             android:src="@drawable/channel7" />
133         
134     </RelativeLayout>
135 
136 </RelativeLayout>

 3.优酷菜单_执行动画

 

3.1【执行动画的效果】

【1】在初始的界面下,点击level2的菜单按键,最外层的level3的所有图标收回;

【2】在level3收起的情况下,点击level1的home按键,level2收回;

3.2【分配id】只需要5个id,两个点击事件的和三个执行动画的;

  1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2     xmlns:tools="http://schemas.android.com/tools"
  3     android:layout_width="match_parent"
  4     android:layout_height="match_parent"
  5     tools:context=".MainActivity" >
  6 
  7     <RelativeLayout
  8         android:id="@+id/rl_level1"  //第1个id 执行动画
  9         android:layout_width="100dp"
 10         android:layout_height="50dp"
 11         android:layout_alignParentBottom="true"
 12         android:layout_centerHorizontal="true"
 13         android:background="@drawable/level1" >
 14 
 15         <ImageButton
 16             android:id="@+id/ib_home" //第2个id 点击事件
 17             android:layout_width="wrap_content"
 18             android:layout_height="wrap_content"
 19             android:layout_centerInParent="true"
 20             android:background="@null"
 21             android:src="@drawable/icon_home" />
 22     </RelativeLayout>
 23 
 24     <RelativeLayout
 25         android:id="@+id/rl_level2" //第3个id 执行动画
 26         android:layout_width="180dp"
 27         android:layout_height="90dp"
 28         android:layout_alignParentBottom="true"
 29         android:layout_centerHorizontal="true"
 30         android:background="@drawable/level2" >
 31         
 32         <ImageButton
 33             android:id="@+id/ib_menu"//第4个id 点击事件
 34             android:layout_width="wrap_content"
 35             android:layout_height="wrap_content"
 36             android:layout_centerHorizontal="true"
 37             android:background="@null"
 38             android:layout_marginTop="5dp"
 39             android:src="@drawable/icon_menu" />
 40         
 41         
 42         <ImageButton
 43             android:layout_width="wrap_content"
 44             android:layout_height="wrap_content"
 45             android:layout_alignParentBottom="true"
 46             android:layout_alignParentLeft="true"
 47             android:layout_marginLeft="10dp"
 48             android:layout_marginBottom="5dp"
 49             android:background="@null"
 50             android:src="@drawable/icon_search" />
 51         
 52         <ImageButton
 53             android:layout_width="wrap_content"
 54             android:layout_height="wrap_content"
 55             android:layout_alignParentBottom="true"
 56             android:layout_alignParentRight="true"
 57             android:layout_marginRight="10dp"
 58             android:layout_marginBottom="5dp"
 59             android:background="@null"
 60             android:src="@drawable/icon_myyouku" />
 61         
 62     </RelativeLayout>
 63 
 64     <RelativeLayout
 65         android:id="@+id/rl_level3"//第5个id 执行动画
 66         android:layout_width="280dp"
 67         android:layout_height="140dp"
 68         android:layout_alignParentBottom="true"
 69         android:layout_centerHorizontal="true"
 70         android:background="@drawable/level3" >
 71 
 72         <ImageButton
 73             android:layout_width="wrap_content"
 74             android:layout_height="wrap_content"
 75             android:layout_alignParentBottom="true"
 76             android:layout_alignParentLeft="true"
 77             android:layout_marginLeft="10dp"
 78             android:layout_marginBottom="5dp"
 79             android:background="@null"
 80             android:src="@drawable/channel1" />
 81         
 82         <ImageButton
 83             android:layout_width="wrap_content"
 84             android:layout_height="wrap_content"
 85             android:layout_marginLeft="30dp"
 86             android:layout_marginTop="60dp"
 87             android:background="@null"
 88             android:src="@drawable/channel2" />
 89         <ImageButton
 90             android:layout_width="wrap_content"
 91             android:layout_height="wrap_content"
 92             android:layout_marginLeft="65dp"
 93             android:layout_marginTop="25dp"
 94             android:background="@null"
 95             android:src="@drawable/channel3" />
 96         
 97         <ImageButton
 98             android:layout_width="wrap_content"
 99             android:layout_height="wrap_content"
100             android:layout_centerHorizontal="true"
101             android:background="@null"
102             android:layout_marginTop="5dp"
103             android:src="@drawable/channel4" />
104         
105         
106         <ImageButton
107             android:layout_width="wrap_content"
108             android:layout_height="wrap_content"
109             android:layout_alignParentRight="true"
110             android:background="@null"
111             android:layout_marginRight="30dp"
112             android:layout_marginTop="60dp"
113             android:src="@drawable/channel5" />
114         
115         <ImageButton
116             android:layout_width="wrap_content"
117             android:layout_height="wrap_content"
118             android:layout_marginRight="65dp"
119             android:layout_marginTop="25dp"
120             android:layout_alignParentRight="true"
121             android:background="@null"
122             android:src="@drawable/channel6" />
123         
124         <ImageButton
125             android:layout_width="wrap_content"
126             android:layout_height="wrap_content"
127             android:layout_alignParentBottom="true"
128             android:layout_alignParentRight="true"
129             android:layout_marginRight="10dp"
130             android:layout_marginBottom="5dp"
131             android:background="@null"
132             android:src="@drawable/channel7" />
133         
134     </RelativeLayout>
135 
136 </RelativeLayout>

3.3 添加home键menu键的点击事件

3.3.1 menu键功能

【代码逻辑】在初始化的状态下,点击menu键然后level3隐藏;

                     如果level3隐藏了,则点击menu键level3显示;

【动画该如何显示】使用补间动画RotateAnimation进行显示,创建动画执行的类AnimationUtils

【Android中的角度的约定】顺时针角度增加,逆时针角度减小;

【动画约定的旋转中心点】

 

3.3.2 home键功能

【说明】可以直接参考menu键的功能;

【动画实现的源码】

【MainActivity源码】

 1 package it.oztaking.com.youkumenu;
 2 
 3 import android.content.Context;
 4 import android.support.v7.app.AppCompatActivity;
 5 import android.os.Bundle;
 6 import android.view.View;
 7 import android.view.View.OnClickListener;
 8 import android.widget.ImageButton;
 9 import android.widget.RelativeLayout;
10 
11 import it.oztaking.com.MyAnimationUtils.MyAnimationUtils;
12 
13 public class MainActivity extends AppCompatActivity implements OnClickListener {
14 
15     private RelativeLayout rl_level1;
16     private RelativeLayout rl_level2;
17     private RelativeLayout rl_level3;
18     private ImageButton ib_home;
19     private ImageButton ib_menu;
20 
21     private boolean isLevel3Display = true;
22     private boolean isLevel2Display = true;
23 
24     private Context mContext = this;
25 
26 
27     @Override
28     protected void onCreate(Bundle savedInstanceState) {
29         super.onCreate(savedInstanceState);
30         setContentView(R.layout.activity_main);
31 
32 
33         //动画的初始化
34         initAnimator();
35 
36     }
37 
38     private void initAnimator() {
39         rl_level1 = (RelativeLayout) findViewById(R.id.rl_level1);
40         rl_level2 = (RelativeLayout) findViewById(R.id.rl_level2);
41         rl_level3 = (RelativeLayout) findViewById(R.id.rl_level3);
42 
43 
44         ib_home = (ImageButton) findViewById(R.id.ib_home);
45         ib_menu = (ImageButton) findViewById(R.id.ib_menu);
46 
47         ib_home.setOnClickListener(this);
48         ib_menu.setOnClickListener(this);
49 
50 
51     }
52 
53     @Override
54     public void onClick(View v) {
55 
56         switch (v.getId()) {
57             case R.id.ib_home:
58                 if (isLevel2Display) {
59                     MyAnimationUtils.rotateOutAnim(rl_level2);
60                 } else {
61                     MyAnimationUtils.rotateInAnim(rl_level2);
62                 }
63                 isLevel2Display = !isLevel2Display;
64                 break;
65 
66             case R.id.ib_menu:
67                 if (isLevel3Display) {
68                     MyAnimationUtils.rotateOutAnim(rl_level3);
69                 } else {
70                     MyAnimationUtils.rotateInAnim(rl_level3);
71                 }
72                 isLevel3Display = !isLevel3Display;
73                 break;
74             default:
75                 break;
76 
77         }
78     }
79 }

 

【MyAnimationUtils源码】

 1 package it.oztaking.com.MyAnimationUtils;
 2 
 3 import android.view.animation.Animation;
 4 import android.view.animation.RotateAnimation;
 5 import android.widget.RelativeLayout;
 6 
 7 /**
 8  * Created by Administrator on 2018-01-04.
 9  */
10 
11 public class MyAnimationUtils {
12 
13     //旋转出去的动画
14     public static void rotateOutAnim(RelativeLayout rl){
15         RotateAnimation ra = new RotateAnimation(
16                 0f, -180f,
17                 Animation.RELATIVE_TO_SELF, 0.5f,
18                 Animation.RELATIVE_TO_SELF, 1.0f);
19         ra.setFillAfter(true);
20         ra.setDuration(500);
21         rl.startAnimation(ra);
22     }
23 
24     //旋转进来的动画
25     public static void rotateInAnim(RelativeLayout rl){
26         RotateAnimation ra = new RotateAnimation(
27                 -180f,0f,
28                 Animation.RELATIVE_TO_SELF, 0.5f,
29                 Animation.RELATIVE_TO_SELF, 1.0f);
30         ra.setFillAfter(true);
31         ra.setDuration(500);
32         rl.startAnimation(ra);
33     }
34 }

 

3.3.3 存在的问题

【bug1】【说明】在初始化的状态下,直接点击home键之后不会顾及level2,直接操作level3,会在level2处出现空白;

【改正的方法】在点击home键之后,level3和level2不是同时旋转,level3旋转,然后level2旋转;

 

【存在的问题】上面修改之后的状态是level3和level2同时转出去,应该level2延时一下;

但是,在主线程中不可以随便延时;

【再次修正】增加了传入的延时参数;

【bug2】出现了动画还没有执行结束再次点击按钮就会出现动画直接返回了;

 【问题的解决】记录当前已经执行了几个动画,如果执行的动画个数大于2,则屏蔽home键的作用;

   需要添加动画的监听;

【实现监听类】

4.菜单按钮的功能的添加

【菜单按钮的功能】点击菜单按钮之后有个level就将几个level都显示出来;

【事件码】在Android手机的按键上,每个按键都会对应一个keycode码;

在Android手机的按键上,每个按键都会对应一个keycode码;

 

【返回值的指定】需要返回值为true;

【menu按键事件源码】

【注意】需要判断menu键多次按下是否会出现所有的level没有完全出现或者隐藏就接着执行隐藏或者出现的动作,即闪现或者闪退的情况;

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        // keyCode 事件码
        System.out.println("onKeyDown: " + keyCode);
        if(keyCode == KeyEvent.KEYCODE_MENU){

            if(AnimationUtils.runningAnimationCount > 0){
                // 当前有动画正在执行, 取消当前事件
                return true;
            }
            
//            如果按下的是菜单按钮
            if(isLevel1Display){
                long delay = 0;
                // 隐藏三级菜单
                if(isLevel3Display){
                    AnimationUtils.rotateOutAnim(rl_level3, 0);
                    isLevel3Display = false;
                    delay += 200;
                }
                
                // 隐藏二级菜单
                if(isLevel2Display){
                    AnimationUtils.rotateOutAnim(rl_level2, delay);
                    isLevel2Display = false;
                    delay += 200;
                }
                
                // 隐藏一级菜单
                AnimationUtils.rotateOutAnim(rl_level1, delay);
                
            }else {
                // 顺次转进来
                AnimationUtils.rotateInAnim(rl_level1, 0);
                AnimationUtils.rotateInAnim(rl_level2, 200);
                AnimationUtils.rotateInAnim(rl_level3, 400);
                
                isLevel3Display = true;
                isLevel2Display = true;
            }
            isLevel1Display = !isLevel1Display;
            
            return true;// 消费了当前事件
        }
        
        return super.onKeyDown(keyCode, event);
    }

 5.BUG-补间动画的缺点

【缺点】即使动画消失之后,原来的按钮还是存在在原来的位置的;

            例如,在下图中的level2中的菜单按钮,仍然会起作用;

【解决办法】将level2的按钮禁用掉;

 1 public class AnimationUtils {
 2 
 3     // 正在运行的动画个数
 4     public static int runningAnimationCount = 0;
 5     
 6     // 旋转出去的动画
 7     public static void rotateOutAnim(RelativeLayout layout, long delay) {
 8         int childCount = layout.getChildCount();
 9         // 如果隐藏. 则找到所有的子View, 禁用
10         for (int i = 0; i < childCount; i++) {
11             layout.getChildAt(i).setEnabled(false);
12         }
13         ............
14     }
15 
16     // 旋转进来的动画
17     public static void rotateInAnim(RelativeLayout layout, long delay) {
18 
19         int childCount = layout.getChildCount();
20         // 如果隐藏. 则找到所有的子View, 启用
21         for (int i = 0; i < childCount; i++) {
22             layout.getChildAt(i).setEnabled(true);
23         }
24         ............
25         
26     }
27     
28 }

 

posted @ 2018-01-02 10:38  OzTaking  阅读(161)  评论(0)    收藏  举报