android仿老式优酷菜单

来源:互联网 发布:php strcmp strncmp 编辑:程序博客网 时间:2024/04/29 01:06

功能简述:
实现一个扇形的3级菜单,由内向外分别是一级菜单、二级菜单、三级菜单。

功能:
1. 点击一级菜单时显示二级菜单,当点击二级菜单时,显示三级菜单。
2. 当点击屏幕上的一个按钮时,会隐藏所有的控件。再次点击时,会显示所有的控件。

效果如图:
这里写图片描述
此图是从网上找的。

菜单UI

主要思路是:全部使用相对布局,以实现图片的叠加。主要用到了 android:layout_alignParentBottom=”true”和android:layout_alignParentRight=”true”
以及设置margin距离。我这上面没有找到menu键,就添加了一个按钮,表示是menu键。

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/activity_main"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.example.customview.MainActivity">    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="button"        android:id="@+id/button1"        /><!--第一级菜单-->    <RelativeLayout        android:id="@+id/rl_level1"        android:layout_width="100dp"        android:background="@drawable/level1"        android:layout_height="50dp"        android:layout_alignParentBottom="true"        android:layout_centerHorizontal="true">        <ImageView            android:id="@+id/iv_home"            android:layout_width="wrap_content"            android:background="@drawable/icon_home"            android:layout_centerInParent="true"            android:layout_height="wrap_content" />    </RelativeLayout><!--第二级菜单-->    <RelativeLayout        android:id="@+id/rl_level2"        android:layout_width="180dp"        android:layout_height="90dp"        android:background="@drawable/level2"        android:layout_alignParentBottom="true"        android:layout_centerHorizontal="true"        >        <ImageView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentBottom="true"            android:layout_marginLeft="10dp"            android:layout_marginBottom="10dp"            android:background="@drawable/icon_search"            />        <ImageView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentBottom="true"            android:layout_marginBottom="10dp"            android:layout_alignParentRight="true"            android:layout_marginRight="10dp"            android:background="@drawable/icon_myyouku"/>        <ImageView            android:id="@+id/iv_menu"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_centerHorizontal="true"            android:background="@drawable/icon_menu"            />    </RelativeLayout>    <!--第三级菜单-->    <RelativeLayout        android:id="@+id/rl_level3"        android:layout_width="280dp"        android:background="@drawable/level3"        android:layout_centerHorizontal="true"        android:layout_alignParentBottom="true"        android:layout_height="140dp">        <ImageView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentBottom="true"            android:layout_marginBottom="0dp"            android:layout_marginLeft="5dp"            android:background="@drawable/channel1"            />        <ImageView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="@drawable/channel2"            android:layout_alignParentBottom="true"            android:layout_marginBottom="40dp"            android:layout_marginLeft="28dp"             />        <ImageView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="@drawable/channel3"            android:layout_alignParentBottom="true"            android:layout_marginBottom="80dp"            android:layout_marginLeft="60dp"            />        <!--这个是最中间的-->        <ImageView            android:layout_width="wrap_content"            android:layout_height="wrap_content"           android:layout_centerHorizontal="true"            android:background="@drawable/channel4"            />        <ImageView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentBottom="true"            android:layout_marginBottom="0dp"            android:layout_alignParentRight="true"            android:layout_marginRight="5dp"            android:background="@drawable/channel5"            />        <ImageView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="@drawable/channel6"            android:layout_alignParentBottom="true"            android:layout_marginBottom="40dp"            android:layout_alignParentRight="true"            android:layout_marginRight="28dp"            />        <ImageView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="@drawable/channel7"            android:layout_alignParentBottom="true"            android:layout_marginBottom="80dp"            android:layout_alignParentRight="true"            android:layout_marginRight="60dp"            />    </RelativeLayout></RelativeLayout>

控制逻辑

这个地方比较常规:

package com.example.customview;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.ImageView;import android.widget.RelativeLayout;public class MainActivity extends AppCompatActivity implements View.OnClickListener {    private static final String TAG = "MainActivity";    private ImageView ivHome;    private ImageView ivMenu;    private Button button;    private boolean isShowLevel2 = true;//是否显示2级菜单    private boolean isShowLevel3 = true;//是否显示3级菜单    private boolean isShowMenu = true;//是否显示整个菜单,包括1级,2级,3级的菜单    private RelativeLayout rlLevel1;    private RelativeLayout rlLevel2;    private RelativeLayout rlLevel3;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        initView();        initListener();    }    //绑定监听器    private void initListener() {        ivHome.setOnClickListener(this);        ivMenu.setOnClickListener(this);        button.setOnClickListener(this);    }    //初始化视图    private void initView() {        setContentView(R.layout.activity_main);        button = (Button) findViewById(R.id.button1);        ivHome = (ImageView) findViewById(R.id.iv_home);        ivMenu = (ImageView) findViewById(R.id.iv_menu);        rlLevel1 = (RelativeLayout) findViewById(R.id.rl_level1);        rlLevel2 = (RelativeLayout) findViewById(R.id.rl_level2);        rlLevel3 = (RelativeLayout) findViewById(R.id.rl_level3);    }    //绑定事件    @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.iv_home:                if (AnimUtil.animCount != 0) {                    return;                }                if (isShowLevel2) {                    Log.d(TAG, "onClick: iv_home 隐藏");                    //先隐藏三级菜单,之后再隐藏二级菜单                    int animaDelay = 0;                    if (isShowLevel3) {                        AnimUtil.closeMenu(rlLevel3, animaDelay);                        animaDelay += 200;                        isShowLevel3 = false;                    }                    AnimUtil.closeMenu(rlLevel2, animaDelay);                } else {                    Log.d(TAG, "onClick: iv_home 显示");                    AnimUtil.showMenu(rlLevel2,0);                }                isShowLevel2 = !isShowLevel2;                break;            case R.id.iv_menu:                if (AnimUtil.animCount != 0) {                    return;                }                if (isShowLevel3) {                    AnimUtil.closeMenu(rlLevel3, 0);                } else {                    AnimUtil.showMenu(rlLevel3,0);                }                isShowLevel3 = !isShowLevel3;                break;            case R.id.button1:                if(isShowMenu){                    int animDelay = 0;                    if(isShowLevel3){                        AnimUtil.closeMenu(rlLevel3,animDelay);                        animDelay += 200;                        isShowLevel3 = false;                    }                    if (isShowLevel2){                        AnimUtil.closeMenu(rlLevel2,animDelay);                        animDelay+=200;                        isShowLevel2 = false;                    }                    AnimUtil.closeMenu(rlLevel1,animDelay);                }else{                    int animDelay = 0;                    AnimUtil.showMenu(rlLevel1,animDelay);                    animDelay += 200;                    AnimUtil.showMenu(rlLevel2,animDelay);                    animDelay += 200;                    isShowLevel2 = true;                    AnimUtil.showMenu(rlLevel3,animDelay);                    isShowLevel3 = true;                }                isShowMenu = !isShowMenu;                break;        }    }}

动画播放工具类

public class AnimUtil {//    问题1:为了解决快速连续双击按钮时动画播放不完,出现的抖动的效果,使用一个计数器animCount标记动画开始个数,//    开始一个计数器加1,播放完一个计数器减1。在Activity中调用时,判断animCount的个数    public static int animCount = 0;    public static void closeMenu(RelativeLayout rl,long startOffset) {        //让父控件内部的所有子控件禁用        for (int i = 0; i < rl.getChildCount(); i++) {            View v = rl.getChildAt(i);            v.setEnabled(false);        }        //逆时针旋转180度        RotateAnimation animation = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 1.0f);        animation.setDuration(500);//        动画结束后保存原来的状态        animation.setFillAfter(true);        animation.setStartOffset(startOffset);        animation.setAnimationListener(new MyAnimationListener());        rl.startAnimation(animation);    }    public static void showMenu(RelativeLayout relativeLayout, long startOffset) {        //让父控件内的所有子控件启用        for (int i = 0; i < relativeLayout.getChildCount(); i++) {            View v = relativeLayout.getChildAt(i);            v.setEnabled(true);        }        //顺时针旋转180度        RotateAnimation animation = new RotateAnimation(-180, 0, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 1.0f);        animation.setDuration(500);        //动画结束后保存原来的状态        animation.setFillAfter(true);        animation.setStartOffset(startOffset);        animation.setAnimationListener(new MyAnimationListener());        relativeLayout.startAnimation(animation);    }//    自定义动画监听器    static class MyAnimationListener implements Animation.AnimationListener{        @Override        public void onAnimationStart(Animation animation) {            animCount++;        }        @Override        public void onAnimationEnd(Animation animation) {            animCount--;        }        @Override        public void onAnimationRepeat(Animation animation) {        }    }}

难点:

  1. 当点击第一级菜单时隐藏了二级菜单,但是点击空白区域,还是可以响应用户的输入。解决办法,在closeMenu()函数中将该布局的所有自控件将其设置为不可用。同时在showMenum()中将所有子控件设置为可用。
  2. 当用户快速连续点击时,会出现隐藏动画没有执行完,就开始执行显示动画。通过在AnimUtil中,设置一个计数器animCount,当播放一个动画时,animCount++,播放完毕,animCount–,在MainActivity中,判断animCount是否等于0,来判断动画是否播放结束。

参考

—android仿老式优酷菜单

原创粉丝点击