zoukankan      html  css  js  c++  java
  • 自定义控件(视图)2期笔记02:自定义控件之使用系统控件(优酷案例之环形菜单布局)

    1.首先我们看看效果图:

    这是优酷布局效果图:

    2. 下面是我们最终编写的程序的效果图:

    3. 下面就是详细演示这个效果的实现过程

    (1)新建一个Android工程,命名为"优酷菜单",如下:

    (2)这里的图片资源都是美工开发好的给我们的,如下:

    我们把这些图片拷贝到res/drawable(工程图片资源文件),如下:

    (3)三级菜单实现的效果如下,布局activity_main.xml,如下:

     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="com.himi.youkumenu.MainActivity" >
     6 
     7     <TextView
     8         android:layout_width="wrap_content"
     9         android:layout_height="wrap_content"
    10         android:layout_centerHorizontal="true"
    11         android:layout_centerVertical="true"
    12         android:text="@string/hello_world" />
    13 
    14     <ImageView
    15         android:id="@+id/level1"
    16         android:layout_width="100dp"
    17         android:layout_height="50dp"
    18         android:layout_alignParentBottom="true"
    19         android:layout_centerHorizontal="true"
    20         android:background="@drawable/level1" /> 
    21 
    22     <ImageView
    23         android:id="@+id/level2"
    24         android:layout_width="180dp"
    25         android:layout_height="90dp"
    26         android:layout_alignParentBottom="true"
    27         android:layout_centerHorizontal="true"
    28         android:background="@drawable/level2" />
    29     
    30      <ImageView
    31         android:id="@+id/level3"
    32         android:layout_width="280dp"
    33         android:layout_height="140dp"
    34         android:layout_alignParentBottom="true"
    35         android:layout_centerHorizontal="true"
    36         android:background="@drawable/level3" />
    37 </RelativeLayout>

    布局效果如下:

    这样设计确实可以实现三级菜单的效果,但是后面每一级菜单上面都会有很多小图标,这里设置ImageView不利于后面菜单摆放图标,必须修改。

    这里activity_main.xml修改,如下:

     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="com.himi.youkumenu.MainActivity" >
     6 
     7     <TextView
     8         android:layout_width="wrap_content"
     9         android:layout_height="wrap_content"
    10         android:layout_centerHorizontal="true"
    11         android:layout_centerVertical="true"
    12         android:text="@string/hello_world" />
    13 
    14     <RelativeLayout
    15         android:id="@+id/level1"
    16         android:layout_width="100dp"
    17         android:layout_height="50dp"
    18         android:layout_alignParentBottom="true"
    19         android:layout_centerHorizontal="true"
    20         android:background="@drawable/level1" /> 
    21 
    22     <RelativeLayout
    23         android:id="@+id/level2"
    24         android:layout_width="180dp"
    25         android:layout_height="90dp"
    26         android:layout_alignParentBottom="true"
    27         android:layout_centerHorizontal="true"
    28         android:background="@drawable/level2" />
    29     
    30      <RelativeLayout
    31         android:id="@+id/level3"
    32         android:layout_width="280dp"
    33         android:layout_height="140dp"
    34         android:layout_alignParentBottom="true"
    35         android:layout_centerHorizontal="true"
    36         android:background="@drawable/level3" />
    37 </RelativeLayout>

    之前的ImageView改成RelativeLayout布局,方便之后每级菜单摆放小图标

    (4)接下来实现三级菜单的图标摆放,如下:

    activity_main.xml,如下:

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

    布局效果如下:

    这里第1级菜单 和 第2级菜单实现没什么好讲的,关键是第3级菜单,分析思路如下:

    第3级菜单左右分为一半,同时channel4为中间一个。

    左半部分:channel1为左半部分定位基准

    •channel1为左边第一个,让它和父容器的底部对齐(默认是靠左),为了美观好看一点我们添加属性:android:layout_marginBottom="10dp"  和 android:layout_marginLeft="10dp"

    •channel2是以channel1为基准进行对齐的,channel2在channel1右上角,但是只要实现channel2在channel1上面的属性:android:layout_above="@id/channel1",没有实现直接属性实现channel2在channel1的右边,该怎么办呢? 这里我们可以先让channel2和channel1进行左对齐,然后设置靠左的边距适当即可:android:layout_alignLeft="@id/channel1"(channel2和channel1左对齐),android:layout_marginLeft="20dp"(设置靠左边距)

    •同样道理channel3是以channel2为基准进行对齐的,思路和上面一样。

    右半部分:思路和上面过程是一致的,这个时候是以channel7为右半部分定位基准

    •channel7为右半部分定位基准,而且channel7和channel1是对称的,这样的话,也就是channel7和channel1布局是一致只不过,左右位置调换,如下:

          

    •其余也是对称设置,channel2 和channel6   ,channel3 和channel5

    (5)下面就要实现代码部分,利用Animation旋转出现、消失菜单。

    首先我们必须知道旋转的坐标系,如下:

    (6)来到MainActivity,搭建实现逻辑框架,如下:

      1 package com.himi.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 
     11 public class MainActivity extends Activity implements OnClickListener {
     12     private ImageView icon_menu;
     13     private ImageView icon_home;
     14     
     15     private RelativeLayout level1;
     16     private RelativeLayout level2;
     17     private RelativeLayout level3;
     18     /**
     19      * 判断第3级菜单是否显示
     20      * true 显示 (默认)
     21      * false 隐藏
     22      */
     23     private boolean isLevel3Show = true;
     24     /**
     25      * 判断2级菜单是否显示
     26      * true 显示 (默认)
     27      * false 隐藏
     28      */
     29     private boolean isLevel2Show = true;
     30     /**
     31      * 判断1级菜单是否显示
     32      * true 显示 (默认)
     33      * false 隐藏
     34      */
     35     private boolean isLevel1Show = true;
     36 
     37     @Override
     38     protected void onCreate(Bundle savedInstanceState) {
     39         super.onCreate(savedInstanceState);
     40         setContentView(R.layout.activity_main);
     41         
     42         icon_home = (ImageView) findViewById(R.id.icon_home);
     43         icon_menu = (ImageView) findViewById(R.id.icon_menu);
     44         
     45         level1 = (RelativeLayout) findViewById(R.id.level1);
     46         level2 = (RelativeLayout) findViewById(R.id.level2);
     47         level3 = (RelativeLayout) findViewById(R.id.level3);
     48         
     49         icon_home.setOnClickListener(this);
     50         icon_menu.setOnClickListener(this);
     51     }
     52 
     53     public void onClick(View v) {
     54         switch (v.getId()) {
     55         case R.id.icon_menu:// 处理menu的点击的事件
     56             // 如果第3级菜单是显示状态,那么将其隐藏
     57             if (isLevel3Show) {
     58                 MyUtils.startAnimOut(level3);
     59             } else {
     60                 // 如果第3级菜单是隐藏状态,那么将其显示
     61                 MyUtils.startAnimIn(level3);
     62             }
     63 
     64             isLevel3Show = !isLevel3Show;
     65             break;
     66 
     67         case R.id.icon_home:// 处理home的点击的事件
     68             // 如果第2级菜单是显示状态,那么就隐藏2,3级菜单
     69             if (isLevel2Show) {
     70                 MyUtils.startAnimOut(level2);
     71                 isLevel2Show = false;
     72 
     73                 if (isLevel3Show) {// 如果此时第3级菜单是显示状态,那么将其隐藏
     74 
     75                     // 这里不能使用Thread.sleep延迟时间,因为这个办法会是整个线程处于休眠状态,上面的2级菜单也不会旋转离开
     76                     MyUtils.startAnimOut(level3, 200);
     77                     isLevel3Show = false;
     78                 }
     79 
     80             } else {
     81                 // 如果第2级菜单是隐藏状态,那么就显示2级菜单
     82                 MyUtils.startAnimIn(level2);
     83                 isLevel2Show = true;
     84             }
     85 
     86             break;
     87         }
     88     }
     89     
     90     /**
     91      * 监听按键的动作
     92      */
     93     @Override
     94     public boolean onKeyDown(int keyCode, KeyEvent event) {
     95         if(keyCode == KeyEvent.KEYCODE_MENU) {//监听menu按键
     96             changeLevelState();
     97         }
     98         return super.onKeyDown(keyCode, event);
     99     }
    100 
    101     /**
    102      * 改变第1级菜单的状态
    103      */
    104     private void changeLevelState() {
    105         //如果第1菜单是显示状态,隐藏1,2,3级菜单
    106         
    107         if(isLevel1Show) {
    108             MyUtils.startAnimOut(level1);
    109             isLevel1Show = false;
    110             
    111             if(isLevel2Show) {
    112                 MyUtils.startAnimOut(level2,100);
    113                 isLevel2Show = false;
    114                 
    115                 if(isLevel3Show) {
    116                     MyUtils.startAnimOut(level3,200);
    117                     isLevel3Show = false;
    118                 }
    119             }    
    120             
    121         } else {
    122             //如果第1菜单是隐藏状态,显示1,2级菜单
    123             MyUtils.startAnimIn(level1);
    124             isLevel1Show = true;
    125             
    126             MyUtils.startAnimIn(level2,200);
    127             isLevel2Show = true;
    128         }
    129         
    130     }
    131     
    132 
    133 
    134     
    135 }

    其中要用到的工具类MyUtils(实现View旋转的方法工具),如下:

     1 package com.himi.youkumenu;
     2 
     3 import android.view.animation.RotateAnimation;
     4 import android.widget.RelativeLayout;
     5 
     6 public class MyUtils {
     7     
     8     /**
     9      * 菜单顺时针旋转离开
    10      * @param view
    11      */
    12     public static void startAnimOut(RelativeLayout view) {
    13         startAnimOut(view, 0);
    14     }
    15 
    16     
    17     /**
    18      * 菜单顺时针旋转进入
    19      * @param view
    20      */
    21     public static void startAnimIn(RelativeLayout view) {
    22         startAnimIn(view,0);
    23     }
    24     
    25     /**
    26      * 让指定的view延时执行旋转离开的画面
    27      * @param view
    28      * @param offset 延时时间
    29      */
    30     public static void startAnimOut(RelativeLayout view, long offset) {
    31         /**
    32          * 默认圆心为view的左上角
    33          * 水平向右为 0度
    34          * 顺时针旋转度数增加
    35          * 顺时针旋转离开度数变化是:0 ~ 180
    36          */
    37         RotateAnimation animation = new RotateAnimation(0, 180, view.getWidth()/2, view.getHeight());
    38         animation.setDuration(500);//设置运行的时间
    39         animation.setFillAfter(true);//动画执行完了之后,保持最后的状态
    40         animation.setStartOffset(offset);//设置延时执行的时间参数
    41         view.startAnimation(animation);//上面是设置动画效果参数,传入到view的方法startAnimation()方法.    
    42     }
    43 
    44     /**
    45      * 让指定的view延时执行旋转进入的画面
    46      * @param view
    47      * @param offset 延时时间
    48      */
    49 
    50     public static void startAnimIn(RelativeLayout view, long offset) {
    51         /**
    52          * 默认圆心为view的左上角
    53          * 水平向右为 0度
    54          * 顺时针旋转度数增加
    55          * 顺时针旋转离开度数变化是:180 ~ 360
    56          */
    57         RotateAnimation animation = new RotateAnimation(180, 360, view.getWidth()/2, view.getHeight());
    58         animation.setDuration(500);//设置运行的时间
    59         animation.setFillAfter(true);//动画执行完了之后,保持最后的状态
    60         animation.setStartOffset(offset);
    61         view.startAnimation(animation);
    62         
    63     }
    64 
    65 }

    (7)部署程序到模拟器上,如下:

  • 相关阅读:
    HTTP协议
    JavaScript学习(一)
    Cookie&Session
    注解初学
    反射初学
    XML
    Web概念
    Response对象
    Servlet
    LeetCode Notes_#617 Merge Two Binary Trees
  • 原文地址:https://www.cnblogs.com/hebao0514/p/4828575.html
Copyright © 2011-2022 走看看