自定义控件

自定义控件---优酷菜单demo

第一步:实现三个圆环(最里面的圆环,中间圆环,最外面的圆环)

 

[java] view plain copy
 
  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.   
  6.     <RelativeLayout  
  7.         android:id="@+id/level3"  
  8.         android:layout_width="280dp"  
  9.         android:layout_height="140dp"  
  10.         android:layout_alignParentBottom="true"  
  11.         android:layout_centerHorizontal="true"  
  12.         android:background="@drawable/level3" >  
  13.     </RelativeLayout>  
  14.    
  15.     <RelativeLayout  
  16.         android:id="@+id/level2"  
  17.         android:layout_width="180dp"  
  18.         android:layout_height="90dp"  
  19.         android:layout_alignParentBottom="true"  
  20.         android:layout_centerHorizontal="true"  
  21.         android:background="@drawable/level2" >  
  22.     </RelativeLayout>  
  23.       
  24.     <RelativeLayout  
  25.         android:id="@+id/level1"  
  26.         android:layout_width="100dp"  
  27.         android:layout_height="50dp"  
  28.         android:layout_alignParentBottom="true"  
  29.         android:layout_centerHorizontal="true"  
  30.         android:background="@drawable/level1" >  
  31.     </RelativeLayout>  
  32. </RelativeLayout>  

 

第二步:实现三个圆环里面的图标


 

 

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


优酷代码实现:

旋转原理图分析:
第一步:二级,三级菜单的显示和隐藏
 
MainActivity.java
[java] view plain copy
 
  1. package com.example.youkumenu;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.view.View;  
  6. import android.view.View.OnClickListener;  
  7. import android.widget.ImageView;  
  8. import android.widget.RelativeLayout;  
  9. public class MainActivity extends Activity implements OnClickListener {  
  10.   
  11.     private RelativeLayout level1, level2, level3;  
  12.     private ImageView icon_home, icon_menu;  
  13.     /** 判断三级菜单是否显示 true显示 false隐藏 */  
  14.     private boolean isLevel3Show = true;  
  15.     /** 判断二级菜单是否显示 true显示 false隐藏 */  
  16.     private boolean isLevel2Show = true;  
  17.     /** 判断一级菜单是否显示 true显示 false隐藏 */  
  18.     private boolean isLevel1Show = true;  
  19.   
  20.     @Override  
  21.     protected void onCreate(Bundle savedInstanceState) {  
  22.         super.onCreate(savedInstanceState);  
  23.         setContentView(R.layout.activity_main);  
  24.         // 初始化空间  
  25.         level1 = (RelativeLayout) findViewById(R.id.level1);  
  26.         level2 = (RelativeLayout) findViewById(R.id.level2);  
  27.         level3 = (RelativeLayout) findViewById(R.id.level3);  
  28.         icon_home = (ImageView) findViewById(R.id.icon_home);  
  29.         icon_menu = (ImageView) findViewById(R.id.icon_menu);  
  30.         // 设置主页与菜单按钮的监听事件  
  31.         icon_home.setOnClickListener(this);  
  32.         icon_menu.setOnClickListener(this);  
  33.     }  
  34.   
  35.     @Override  
  36.     public void onClick(View v) {  
  37.         switch (v.getId()) {  
  38.         case R.id.icon_menu://响应menu图标的监听事件  
  39.             if(isLevel3Show){  
  40.                 //隐藏三级菜单  
  41.                 Tools.hiddenView(level3);  
  42.                 isLevel3Show = false;  
  43.             }else{  
  44.                 //显示三级菜单  
  45.                 Tools.showView(level3);  
  46.                 isLevel3Show = true;  
  47.             }  
  48.             break;  
  49.         case R.id.icon_home://响应home图标的监听事件  
  50.             if(isLevel2Show){  
  51.                 //如果二级菜单是显示状态,那么隐藏二级菜单  
  52.                 Tools.hiddenView(level2);  
  53.                 isLevel2Show = false;  
  54.                 //同时判断,三级菜单的状态,如果是显示,同样也隐藏三级菜单  
  55.                 if(isLevel3Show){  
  56.                     Tools.hiddenView(level3);  
  57.                     isLevel3Show = false;  
  58.                 }  
  59.             }else{  
  60.                 //如果二级菜单是隐藏状态,那么显示二级菜单  
  61.                 Tools.showView(level2);  
  62.                 isLevel2Show = true;  
  63.             }  
  64.             break;  
  65.         }  
  66.   
  67.     }  
  68. }  
Tools.java:
[java] view plain copy
 
  1. package com.example.youkumenu;  
  2.   
  3. import android.view.View;  
  4. import android.view.animation.RotateAnimation;  
  5. public class Tools {  
  6.   
  7.     public static void showView(View view) {  
  8.         RotateAnimation ra = new RotateAnimation(180,360, view.getWidth()/2, view.getHeight());  
  9.         //设置动画的运行时间  
  10.         ra.setDuration(500);  
  11.         //动画执行完后,保持现有的状态  
  12.         ra.setFillAfter(true);  
  13.         //让view执行动画  
  14.         view.startAnimation(ra);  
  15.           
  16.     }  
  17.     public static void hiddenView(View view) {  
  18.         /** 
  19.          * RotateAnimation 中的四个参数: 
  20.          * fromDegrees 从多少度 
  21.          * toDegrees 到多少度 
  22.          * pivotX 中心点的x 坐标 
  23.          * pivotY 中心点的Y坐标 
  24.          */  
  25.         RotateAnimation ra = new RotateAnimation(0, 180, view.getWidth()/2, view.getHeight());  
  26.         //设置动画的运行时间  
  27.         ra.setDuration(500);  
  28.         //动画执行完后,保持现有的状态  
  29.         ra.setFillAfter(true);  
  30.         //让view执行动画  
  31.         view.startAnimation(ra);  
  32.           
  33.     }  
  34.   
  35. }  
第二步:设置延迟动画setStartOffset()方法和代码重构
Tools.java
[java] view plain copy
 
  1. package com.example.youkumenu;  
  2.   
  3. import android.view.View;  
  4. import android.view.animation.RotateAnimation;  
  5. public class Tools {  
  6.   
  7.     public static void showView(View view) {  
  8.         showView(view, 0);  
  9.     }  
  10.   
  11.     public static void hiddenView(View view) {  
  12.         hiddenView(view, 0);  
  13.   
  14.     }  
  15.     public static void hiddenView(View view, int startOffset) {  
  16.         /** 
  17.          * RotateAnimation 中的四个参数: 
  18.          * fromDegrees 从多少度  
  19.          * toDegrees 到多少度 
  20.          * pivotX 中心点的x坐标 
  21.          * pivotY 中心点的Y坐标 
  22.          */  
  23.         RotateAnimation ra = new RotateAnimation(0, 180, view.getWidth() / 2,  
  24.                 view.getHeight());  
  25.         // 设置动画的运行时间  
  26.         ra.setDuration(500);  
  27.         // 动画执行完后,保持现有的状态  
  28.         ra.setFillAfter(true);  
  29.         // 设置动画执行的延时时间  
  30.         ra.setStartOffset(startOffset);  
  31.         // 让view执行动画  
  32.         view.startAnimation(ra);  
  33.     }  
  34.   
  35.     public static void showView(View view, int startOffset) {  
  36.         RotateAnimation ra = new RotateAnimation(180, 360, view.getWidth() / 2,  
  37.                 view.getHeight());  
  38.         // 设置动画的运行时间  
  39.         ra.setDuration(500);  
  40.         // 动画执行完后,保持现有的状态  
  41.         ra.setFillAfter(true);  
  42.         // 设置动画执行的延时时间  
  43.         ra.setStartOffset(startOffset);  
  44.         // 让view执行动画  
  45.         view.startAnimation(ra);  
  46.     }  
  47.   
  48. }  
第三步:监听手机menu按键实现菜单的隐藏和显示
 
MainActivity.java:
[java] view plain copy
 
  1. package com.example.youkumenu;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.view.KeyEvent;  
  6. import android.view.View;  
  7. import android.view.View.OnClickListener;  
  8. import android.widget.ImageView;  
  9. import android.widget.RelativeLayout;  
  10. public class MainActivity extends Activity implements OnClickListener {  
  11.   
  12.     private RelativeLayout level1, level2, level3;  
  13.     private ImageView icon_home, icon_menu;  
  14.     /** 判断三级菜单是否显示 true显示 false隐藏 */  
  15.     private boolean isLevel3Show = true;  
  16.     /** 判断二级菜单是否显示 true显示 false隐藏 */  
  17.     private boolean isLevel2Show = true;  
  18.     /** 判断一级菜单是否显示 true显示 false隐藏 */  
  19.     private boolean isLevel1Show = true;  
  20.   
  21.     @Override  
  22.     protected void onCreate(Bundle savedInstanceState) {  
  23.         super.onCreate(savedInstanceState);  
  24.         setContentView(R.layout.activity_main);  
  25.         // 初始化空间  
  26.         level1 = (RelativeLayout) findViewById(R.id.level1);  
  27.         level2 = (RelativeLayout) findViewById(R.id.level2);  
  28.         level3 = (RelativeLayout) findViewById(R.id.level3);  
  29.         icon_home = (ImageView) findViewById(R.id.icon_home);  
  30.         icon_menu = (ImageView) findViewById(R.id.icon_menu);  
  31.         // 设置主页与菜单按钮的监听事件  
  32.         icon_home.setOnClickListener(this);  
  33.         icon_menu.setOnClickListener(this);  
  34.     }  
  35.     /** 
  36.      * 当点击手机按键的时候,触发该方法 
  37.      * keyCode点击按键代表的值 
  38.      * event按键事件 
  39.      */  
  40.     @Override  
  41.     public boolean onKeyDown(int keyCode, KeyEvent event) {  
  42.         //判断是否点击menu按钮  
  43.         if(keyCode == KeyEvent.KEYCODE_MENU){  
  44.             //判断一级菜单  
  45.             //如果是隐藏状态,那么就显示一级菜单和二级菜单  
  46.             if(!isLevel1Show){  
  47.                 Tools.showView(level1);  
  48.                 isLevel1Show = true;  
  49.                 //同时显示二级菜单  
  50.                 Tools.showView(level2,200);  
  51.                 isLevel2Show = true;  
  52.             }else{  
  53.                 //如果一级菜单是显示状态  
  54.                 //隐藏一级菜单 同时判断 ,隐藏二,三级菜单  
  55.                 Tools.hiddenView(level1);  
  56.                 isLevel1Show = false;  
  57.                 if(isLevel2Show){  
  58.                     Tools.hiddenView(level2,200);  
  59.                     isLevel2Show = false;  
  60.                     if(isLevel3Show){  
  61.                         Tools.hiddenView(level3, 300);  
  62.                         isLevel3Show = false;  
  63.                     }  
  64.                 }  
  65.             }  
  66.             return true;  
  67.         }  
  68.         return super.onKeyDown(keyCode, event);  
  69.     }  
  70.     @Override  
  71.     public void onClick(View v) {  
  72.         switch (v.getId()) {  
  73.         case R.id.icon_menu://响应menu图标的监听事件  
  74.             if(isLevel3Show){  
  75.                 //隐藏三级菜单  
  76.                 Tools.hiddenView(level3);  
  77.                 isLevel3Show = false;  
  78.             }else{  
  79.                 //显示三级菜单  
  80.                 Tools.showView(level3);  
  81.                 isLevel3Show = true;  
  82.             }  
  83.             break;  
  84.         case R.id.icon_home://响应home图标的监听事件  
  85.             if(isLevel2Show){  
  86.                 //如果二级菜单是显示状态,那么隐藏二级菜单  
  87.                 Tools.hiddenView(level2);  
  88.                 isLevel2Show = false;  
  89.                 //同时判断,三级菜单的状态,如果是显示,同样也隐藏三级菜单  
  90.                 if(isLevel3Show){  
  91.                     Tools.hiddenView(level3,500);  
  92.                     isLevel3Show = false;  
  93.                 }  
  94.             }else{  
  95.                 //如果二级菜单是隐藏状态,那么显示二级菜单  
  96.                 Tools.showView(level2);  
  97.                 isLevel2Show = true;  
  98.             }  
  99.             break;  
  100.         }  
  101.   
  102.     }  
  103. }  

优酷效果图的整体完成和bug的修复:

仔细观察效果图:会发现一点点的小bug。当我们通过menu按键隐藏一二三级菜单的时候,我们点击布局的空白处,同样会出现某些级的菜单。我们这里修复这个bug

 

[java] view plain copy
 
    1. package com.example.youkumenu;  
    2.   
    3. import android.view.View;  
    4. import android.view.ViewGroup;  
    5. import android.view.animation.RotateAnimation;  
    6.   
    7. public class Tools {  
    8.   
    9.     public static void showView(ViewGroup view) {  
    10.         showView(view, 0);  
    11.     }  
    12.   
    13.     public static void hiddenView(ViewGroup view) {  
    14.         hiddenView(view, 0);  
    15.   
    16.     }  
    17.   
    18.     public static void hiddenView(ViewGroup view, int startOffset) {  
    19.         /** 
    20.          * RotateAnimation 中的四个参数: 
    21.          * fromDegrees 从多少度  
    22.          * toDegrees 到多少度 
    23.          * pivotX 中心点的x坐标 
    24.          * pivotY 中心点的Y坐标 
    25.          */  
    26.         RotateAnimation ra = new RotateAnimation(0, 180, view.getWidth() / 2,  
    27.                 view.getHeight());  
    28.         // 设置动画的运行时间  
    29.         ra.setDuration(500);  
    30.         // 动画执行完后,保持现有的状态  
    31.         ra.setFillAfter(true);  
    32.         // 设置动画执行的延时时间  
    33.         ra.setStartOffset(startOffset);  
    34.         // 让view执行动画  
    35.         view.startAnimation(ra);  
    36.         <span style="color:#cc33cc;">for (int i = 0; i < view.getChildCount(); i++) {  
    37.             View child = view.getChildAt(i);  
    38.             child.setVisibility(View.GONE);  
    39.         }</span>  
    40.     }  
    41.   
    42.     public static void showView(ViewGroup view, int startOffset) {  
    43.         RotateAnimation ra = new RotateAnimation(180, 360, view.getWidth() / 2,  
    44.                 view.getHeight());  
    45.         // 设置动画的运行时间  
    46.         ra.setDuration(500);  
    47.         // 动画执行完后,保持现有的状态  
    48.         ra.setFillAfter(true);  
    49.         // 设置动画执行的延时时间  
    50.         ra.setStartOffset(startOffset);  
    51.         // 让view执行动画  
    52.         view.startAnimation(ra);  
    53.         <span style="color:#cc33cc;">/** 
    54.          * ViewGroup中的方法介绍: 
    55.          * getChildCount()返回子View的数量 
    56.          * getChildAt(i)获得指定小标的子view 
    57.          */  
    58.         for (int i = 0; i < view.getChildCount(); i++) {  
    59.             View child = view.getChildAt(i);  
    60.             child.setVisibility(View.VISIBLE);  
    61.         }</span>  
    62.     }  
    63.   
    64. }  
posted @ 2017-03-15 08:24  导演,我躺哪儿?  阅读(569)  评论(0编辑  收藏  举报