自定义View(一)-ViewGroup实现优酷菜单

自定义View的第一个学习案例

  ViewGroup是自动以View中比较常用也比较简单的一种方式,通过组合现有的UI控件,绘制出一个全新的View

效果如下:

主类实现如下:

package com.demo.youku;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    /**
     * False: hide
     * 是否显示圆环 默认显示
     * true:显示
     * false:隐藏
     */
    private Boolean showLevel1 = true;
    private Boolean showLevel2 = true;
    private Boolean showLevel3 = true;
    private ImageView iconHome;
    private ImageView iconMenu;
    private RelativeLayout level1;//第一层
    private RelativeLayout level2;//第二层
    private RelativeLayout level3;//第三层
    private Toolbar toolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        toolbar = (Toolbar) findViewById(R.id.toolbar);

        toolbar.setTitle("优酷菜单");
        //设置导航图标要在setSupportActionBar方法之后
        setSupportActionBar(toolbar);
        toolbar.setNavigationIcon(R.mipmap.icon_menu);

        iconHome = (ImageView) findViewById(R.id.home);
        iconMenu = (ImageView) findViewById(R.id.icon_menu);
        level1 = (RelativeLayout) findViewById(R.id.level1);
        level2 = (RelativeLayout) findViewById(R.id.level2);
        level3 = (RelativeLayout) findViewById(R.id.level3);

        MyOnclickListener myOnclickListener = new MyOnclickListener();

        iconHome.setOnClickListener(myOnclickListener);
        iconMenu.setOnClickListener(myOnclickListener);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //如果一级二级三级菜单显示 则关闭
                if (showLevel1 || showLevel2 || showLevel3) {
                    showLevel1 = false;
                    showLevel2 = false;
                    if (showLevel3) {
                        showLevel3 = false;
                        Tools.hideView(level3);
                        Tools.hideView(level2, 400);
                        Tools.hideView(level1, 800);
                    } else {
                        Tools.hideView(level2);
                        Tools.hideView(level1, 300);
                    }
                } else {
                    //如果都未显示 则显示一级二级菜单
                    showLevel1 = true;
                    showLevel2 = true;

                    Tools.showView(level1);
                    Tools.showView(level2);
                }
            }
        });

    }

    class MyOnclickListener implements View.OnClickListener {

        @Override
        public void onClick(View view) {
            //
            switch (view.getId()) {
                case R.id.home:
                    if (showLevel2) {
                        showLevel2 = false;
                        Tools.hideView(level2);
                        if (showLevel3) {
                            showLevel3 = false;
                            Tools.hideView(level3, 400);
                        }
                    } else {
                        showLevel2 = true;
                        Tools.showView(level2);
                    }
                    break;
                case R.id.icon_menu:
                    if (showLevel3) {
                        showLevel3 = false;
                        Tools.hideView(level3);

                    } else {
                        showLevel3 = true;
                        Tools.showView(level3);
                    }
                    break;

            }
        }
    }

}

Tools类主要用于控制View的显示和隐藏动画,提供了属性动画,不补间动画两种实现方式

package com.demo.youku;

import android.animation.ObjectAnimator;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.RotateAnimation;
import android.widget.RelativeLayout;

public class Tools {

    /**
     * 顺时针旋转0-180度隐藏view
     *
     * @param view
     */
    public static void hideView(ViewGroup view) {
        hideView(view, 0);
    }

    /**
     * 顺时针旋转180-360度显示view
     *
     * @param view
     */
    public static void showView(ViewGroup view) {
/*        RotateAnimation ra = new RotateAnimation(180, 360, view.getWidth() / 2, view.getHeight());
        ra.setDuration(500);
        ra.setFillAfter(true);
        view.startAnimation(ra);

        //启动ViewGroup中所有子元素的点击事件
        for (int i = 0; i < view.getChildCount(); i++) {
            View childView = view.getChildAt(i);
            childView.setEnabled(true);
        }*/

        ObjectAnimator animator = ObjectAnimator.ofFloat(view, "Rotation", 180, 360);
        animator.setDuration(500);
        animator.start();

        view.setPivotX(view.getWidth() / 2);
        view.setPivotX(view.getHeight());
    }

    /**
     * 延迟旋转
     *
     * @param view       需要旋转的view
     * @param setTimeOut 动画延迟时间
     */
    public static void hideView(ViewGroup view, int setTimeOut) {
        /*RotateAnimation ra = new RotateAnimation(0, 180, view.getWidth() / 2, view.getHeight());
        ra.setDuration(500);//动画时间
        ra.setFillAfter(true);//是否保留动画结束状态
        ra.setStartOffset(setTimeOut);//设置延迟时间
        view.startAnimation(ra);

        //禁用ViewGroup中错有元素的点击事件
        for (int i = 0; i < view.getChildCount(); i++) {
            View childView = view.getChildAt(i);
            childView.setEnabled(false);
        }*/
<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.demo.youku.MainActivity">

    <android.support.v7.widget.Toolbar
        android:background="?attr/colorPrimary"
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize">

    </android.support.v7.widget.Toolbar>

    <RelativeLayout
        android:id="@+id/level3"
        android:layout_width="280dp"
        android:layout_height="140dp"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:background="@mipmap/level3">

        <ImageView
            android:id="@+id/chanel1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_marginBottom="8dp"
            android:layout_marginLeft="8dp"
            android:background="@mipmap/channel1" />

        <ImageView
            android:id="@+id/chanel2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_above="@+id/chanel1"
            android:layout_marginBottom="8dp"
            android:layout_marginLeft="30dp"
            android:background="@mipmap/channel2" />

        <ImageView
            android:id="@+id/chanel3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_above="@+id/chanel2"
            android:layout_marginBottom="8dp"
            android:layout_marginLeft="60dp"
            android:background="@mipmap/channel3" />

        <ImageView
            android:id="@+id/chanel4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="8dp"
            android:background="@mipmap/channel4" />

        <ImageView
            android:id="@+id/chanel5"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:layout_marginBottom="8dp"
            android:layout_marginRight="8dp"
            android:background="@mipmap/channel5" />

        <ImageView
            android:id="@+id/chanel6"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_above="@+id/chanel5"
            android:layout_alignParentRight="true"
            android:layout_marginBottom="8dp"
            android:layout_marginRight="30dp"
            android:background="@mipmap/channel6" />

        <ImageView
            android:id="@+id/chanel7"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_above="@+id/chanel6"
            android:layout_alignParentRight="true"
            android:layout_marginBottom="8dp"
            android:layout_marginRight="60dp"
            android:background="@mipmap/channel7" />

    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/level2"
        android:layout_width="180dp"
        android:layout_height="90dp"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:background="@mipmap/level2">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_marginBottom="8dp"
            android:layout_marginLeft="8dp"
            android:background="@mipmap/icon_search" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:layout_marginBottom="8dp"
            android:layout_marginRight="8dp"
            android:background="@mipmap/icon_myyouku" />

        <ImageView
            android:id="@+id/icon_menu"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="4dp"
            android:background="@mipmap/icon_menu" />
    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/level1"
        android:layout_width="100dp"
        android:layout_height="50dp"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:background="@mipmap/level1">

        <ImageView
            android:id="@+id/home"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:background="@mipmap/icon_home" />

    </RelativeLayout>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="ViewGrou之优酷菜单"
        android:textSize="24sp" />

</RelativeLayout>

        animator.setStartDelay(setTimeOut);
        animator.start();

        view.setPivotX(view.getWidth() / 2);
        view.setPivotY(view.getHeight());
    }
}

页面布局如下,布局中使用Toolbar代替ActionBar:主要需要更换默认主题:Theme.AppCompat.Light.NoActionBar

时间: 2024-08-24 23:49:34

自定义View(一)-ViewGroup实现优酷菜单的相关文章

模仿优酷菜单

转载注明出处:    http://blog.csdn.net/forwardyzk/article/details/42554691 在开发中,会使用菜单,现在模拟一下优酷的菜单效果. 其实效果都是由android基本的动画效果组成的,在合适的时间显示对应的动画,即可展示出不一样的效果. 思路: 1.自定义类RotateMenuView继承RelativeLayout. 2.在需要加载的布局文件中,添加对应的菜单View. 3.定义菜单进入和出去的动画效果,使用旋转动画,进来顺时针,出去的时候

android自定义控件之模仿优酷菜单

去年的优酷HD版有过这样一种菜单,如下图: 应用打开之后,先是三个弧形的三级菜单,点击实体键menu之后,这三个菜单依次旋转退出,再点击实体键menu之后,一级菜单会旋转进入,点击一级菜单,二级菜单旋转进入,点击二级菜单的menu键,三级菜单旋转进入,再次点击二级菜单的旋转键,三级菜单又会旋转退出,这时再点击一级菜单,二级菜单退出,最后点击实体menu键,一级菜单退出. 总体来说实现这样的功能: (1)点击实体menu键时,如果界面上有菜单显示,不管有几个,全部依次退出,如果界面上没有菜单显示,

Android优酷菜单组件自定义

主要做的就是模仿优酷手机客户端的底部菜单控件的实现.先来几张图片,点击中间的home,显示二级菜单,点击二级菜单的menu,显示三级菜单. 这是实现起来最简单的一个布局,但是从中学会了自定义动画和一些布局的基本知识,从中还是收获很大的. 首先是定义布局文件,三个菜单条其实就是三个relativelayout,level1,level2,level3,然后每个菜单条中的小标题就加到对应的相对布局中. <RelativeLayout xmlns:android="http://schemas.

Android 自定义View、ViewGroup和自定义属性

一.Android自定义view属性 1.在res/values/styles.xml文件里面声明一个我们自定义的属性: <resources> <!--name为声明的"属性集合"名,可以随便取,但是最好是设置为跟我们的View一样的名称--> <declare-styleable name="CircleView"> <!--声明我们的属性,名称为default_size,取值类型为尺寸类型(dp,px等)-->

Android自定义View(RollWeekView-炫酷的星期日期选择控件)

转载请标明出处: http://blog.csdn.net/xmxkf/article/details/53420889 本文出自:[openXu的博客] 目录: 1分析 2定义控件布局 3定义CustomWeekView 4重写onMeasure 5点击后执行动画 7重置预备控件 源码下载 ??最近收到一个自定义控件的需求,需要做一个日期选择控件,实现图如下: ???? ??一次展示一个星期的5天,中间放大的为当前选中的:如果点击了其中一个日期,比如星期五,那么整体向左滑动,并将星期五慢慢放大

Android中自定义View、ViewGroup理论基础详解

Android自身提供了许多widgets,但是有时候这些widgets并不能满足我们的需求,这时我们就需要自定义View,本文会详细说明自定义View的各种理论基础,只有理解了这些知识,我们才能更好地实现各种功能的控件. 我觉得自定义View中最重要的部分就是绘图和交互,自定义的绘图使得你的View与众不同,交互使用户可以与你的View进行交互,而绘图的前提是View的量算与布局,交互的基础是触摸事件,所以量算.布局.绘图.触摸事件这些是自定义View的核心. 除此之外,一个设计友好的自定义V

android自定义view、viewgroup、复合组件(1)

自定义红点的imageview RedTipImageView.java import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android

优酷菜单

Android中RelativeLayout各个属性的含义 android:layout_above="@id/xxx"  --将控件置于给定ID控件之上android:layout_below="@id/xxx"  --将控件置于给定ID控件之下 android:layout_toLeftOf="@id/xxx"  --将控件的右边缘和给定ID控件的左边缘对齐android:layout_toRightOf="@id/xxx"

Android仿优酷菜单效果

一.效果图 二.主要的技术点 1.RelativeLayout布局 2.RotateAnimation旋转动画 三.需求 1.点击二级菜单中的“menu”键控制三级菜单的进入和退出动画效果: 2.点击一级菜单中的“home”键控制二级和三级菜单的进入和退出效果: 3.点击手机上的菜单键控制一级.二级和三级菜单的进入和退出效果. 四.实例代码 1.布局文件:activity_main.xml <RelativeLayout xmlns:android="http://schemas.andr