android仿老式优酷菜单

功能简述:
实现一个扇形的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仿老式优酷菜单

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值