自定义控件
自定义控件---优酷菜单demo
第一步:实现三个圆环(最里面的圆环,中间圆环,最外面的圆环)
- <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" >
- <RelativeLayout
- android:id="@+id/level3"
- android:layout_width="280dp"
- android:layout_height="140dp"
- android:layout_alignParentBottom="true"
- android:layout_centerHorizontal="true"
- android:background="@drawable/level3" >
- </RelativeLayout>
- <RelativeLayout
- android:id="@+id/level2"
- android:layout_width="180dp"
- android:layout_height="90dp"
- android:layout_alignParentBottom="true"
- android:layout_centerHorizontal="true"
- android:background="@drawable/level2" >
- </RelativeLayout>
- <RelativeLayout
- android:id="@+id/level1"
- android:layout_width="100dp"
- android:layout_height="50dp"
- android:layout_alignParentBottom="true"
- android:layout_centerHorizontal="true"
- android:background="@drawable/level1" >
- </RelativeLayout>
- </RelativeLayout>
第二步:实现三个圆环里面的图标
- <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" >
- <RelativeLayout
- android:id="@+id/level3"
- android:layout_width="280dp"
- android:layout_height="140dp"
- android:layout_alignParentBottom="true"
- android:layout_centerHorizontal="true"
- android:background="@drawable/level3" >
- <ImageView
- android:id="@+id/channel1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:background="@drawable/channel1"
- android:layout_alignParentBottom="true"
- android:layout_marginLeft="10dp"
- android:layout_marginBottom="10dp"
- />
- <ImageView
- android:id="@+id/channel2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:background="@drawable/channel2"
- android:layout_above="@id/channel1"
- android:layout_alignLeft="@id/channel1"
- android:layout_marginLeft="20dp"
- android:layout_marginBottom="10dp"
- />
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_above="@+id/channel2"
- android:layout_alignLeft="@+id/channel2"
- android:layout_marginBottom="8dp"
- android:layout_marginLeft="35dp"
- android:background="@drawable/channel3" />
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerHorizontal="true"
- android:background="@drawable/channel4"
- android:layout_marginTop="6dp"/>
- <ImageView
- android:id="@+id/channel7"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:background="@drawable/channel7"
- android:layout_alignParentBottom="true"
- android:layout_alignParentRight="true"
- android:layout_marginRight="10dp"
- android:layout_marginBottom="10dp"
- />
- <ImageView
- android:id="@+id/channel6"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_above="@id/channel7"
- android:layout_alignRight="@id/channel7"
- android:layout_marginBottom="10dp"
- android:layout_marginRight="20dp"
- android:background="@drawable/channel6" />
- <ImageView
- android:id="@+id/channel5"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_above="@id/channel6"
- android:layout_alignRight="@id/channel6"
- android:layout_marginBottom="8dp"
- android:layout_marginRight="35dp"
- android:background="@drawable/channel5" />
- </RelativeLayout>
- <RelativeLayout
- android:id="@+id/level2"
- android:layout_width="180dp"
- android:layout_height="90dp"
- android:layout_alignParentBottom="true"
- android:layout_centerHorizontal="true"
- android:background="@drawable/level2" >
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:background="@drawable/icon_search"
- android:layout_margin="10dp"
- android:layout_alignParentBottom="true"
- />
- <ImageView
- android:id="@+id/icon_menu"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerHorizontal="true"
- android:layout_marginTop="5dp"
- android:background="@drawable/icon_menu" />
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:background="@drawable/icon_myyouku"
- android:layout_alignParentBottom="true"
- android:layout_alignParentRight="true"
- android:layout_margin="10dp"
- />
- </RelativeLayout>
- <RelativeLayout
- android:id="@+id/level1"
- android:layout_width="100dp"
- android:layout_height="50dp"
- android:layout_alignParentBottom="true"
- android:layout_centerHorizontal="true"
- android:background="@drawable/level1" >
- <ImageView
- android:id="@+id/icon_home"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerInParent="true"
- android:background="@drawable/icon_home" />
- </RelativeLayout>
- </RelativeLayout>
优酷代码实现:
旋转原理图分析:
第一步:二级,三级菜单的显示和隐藏
MainActivity.java
- package com.example.youkumenu;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.ImageView;
- import android.widget.RelativeLayout;
- public class MainActivity extends Activity implements OnClickListener {
- private RelativeLayout level1, level2, level3;
- private ImageView icon_home, icon_menu;
- /** 判断三级菜单是否显示 true显示 false隐藏 */
- private boolean isLevel3Show = true;
- /** 判断二级菜单是否显示 true显示 false隐藏 */
- private boolean isLevel2Show = true;
- /** 判断一级菜单是否显示 true显示 false隐藏 */
- private boolean isLevel1Show = true;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- // 初始化空间
- level1 = (RelativeLayout) findViewById(R.id.level1);
- level2 = (RelativeLayout) findViewById(R.id.level2);
- level3 = (RelativeLayout) findViewById(R.id.level3);
- icon_home = (ImageView) findViewById(R.id.icon_home);
- icon_menu = (ImageView) findViewById(R.id.icon_menu);
- // 设置主页与菜单按钮的监听事件
- icon_home.setOnClickListener(this);
- icon_menu.setOnClickListener(this);
- }
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.icon_menu://响应menu图标的监听事件
- if(isLevel3Show){
- //隐藏三级菜单
- Tools.hiddenView(level3);
- isLevel3Show = false;
- }else{
- //显示三级菜单
- Tools.showView(level3);
- isLevel3Show = true;
- }
- break;
- case R.id.icon_home://响应home图标的监听事件
- if(isLevel2Show){
- //如果二级菜单是显示状态,那么隐藏二级菜单
- Tools.hiddenView(level2);
- isLevel2Show = false;
- //同时判断,三级菜单的状态,如果是显示,同样也隐藏三级菜单
- if(isLevel3Show){
- Tools.hiddenView(level3);
- isLevel3Show = false;
- }
- }else{
- //如果二级菜单是隐藏状态,那么显示二级菜单
- Tools.showView(level2);
- isLevel2Show = true;
- }
- break;
- }
- }
- }
- package com.example.youkumenu;
- import android.view.View;
- import android.view.animation.RotateAnimation;
- public class Tools {
- public static void showView(View view) {
- RotateAnimation ra = new RotateAnimation(180,360, view.getWidth()/2, view.getHeight());
- //设置动画的运行时间
- ra.setDuration(500);
- //动画执行完后,保持现有的状态
- ra.setFillAfter(true);
- //让view执行动画
- view.startAnimation(ra);
- }
- public static void hiddenView(View view) {
- /**
- * RotateAnimation 中的四个参数:
- * fromDegrees 从多少度
- * toDegrees 到多少度
- * pivotX 中心点的x 坐标
- * pivotY 中心点的Y坐标
- */
- RotateAnimation ra = new RotateAnimation(0, 180, view.getWidth()/2, view.getHeight());
- //设置动画的运行时间
- ra.setDuration(500);
- //动画执行完后,保持现有的状态
- ra.setFillAfter(true);
- //让view执行动画
- view.startAnimation(ra);
- }
- }
第二步:设置延迟动画setStartOffset()方法和代码重构
Tools.java
- package com.example.youkumenu;
- import android.view.View;
- import android.view.animation.RotateAnimation;
- public class Tools {
- public static void showView(View view) {
- showView(view, 0);
- }
- public static void hiddenView(View view) {
- hiddenView(view, 0);
- }
- public static void hiddenView(View view, int startOffset) {
- /**
- * RotateAnimation 中的四个参数:
- * fromDegrees 从多少度
- * toDegrees 到多少度
- * pivotX 中心点的x坐标
- * pivotY 中心点的Y坐标
- */
- RotateAnimation ra = new RotateAnimation(0, 180, view.getWidth() / 2,
- view.getHeight());
- // 设置动画的运行时间
- ra.setDuration(500);
- // 动画执行完后,保持现有的状态
- ra.setFillAfter(true);
- // 设置动画执行的延时时间
- ra.setStartOffset(startOffset);
- // 让view执行动画
- view.startAnimation(ra);
- }
- public static void showView(View view, int startOffset) {
- RotateAnimation ra = new RotateAnimation(180, 360, view.getWidth() / 2,
- view.getHeight());
- // 设置动画的运行时间
- ra.setDuration(500);
- // 动画执行完后,保持现有的状态
- ra.setFillAfter(true);
- // 设置动画执行的延时时间
- ra.setStartOffset(startOffset);
- // 让view执行动画
- view.startAnimation(ra);
- }
- }
第三步:监听手机menu按键实现菜单的隐藏和显示
MainActivity.java:
- package com.example.youkumenu;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.KeyEvent;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.ImageView;
- import android.widget.RelativeLayout;
- public class MainActivity extends Activity implements OnClickListener {
- private RelativeLayout level1, level2, level3;
- private ImageView icon_home, icon_menu;
- /** 判断三级菜单是否显示 true显示 false隐藏 */
- private boolean isLevel3Show = true;
- /** 判断二级菜单是否显示 true显示 false隐藏 */
- private boolean isLevel2Show = true;
- /** 判断一级菜单是否显示 true显示 false隐藏 */
- private boolean isLevel1Show = true;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- // 初始化空间
- level1 = (RelativeLayout) findViewById(R.id.level1);
- level2 = (RelativeLayout) findViewById(R.id.level2);
- level3 = (RelativeLayout) findViewById(R.id.level3);
- icon_home = (ImageView) findViewById(R.id.icon_home);
- icon_menu = (ImageView) findViewById(R.id.icon_menu);
- // 设置主页与菜单按钮的监听事件
- icon_home.setOnClickListener(this);
- icon_menu.setOnClickListener(this);
- }
- /**
- * 当点击手机按键的时候,触发该方法
- * keyCode点击按键代表的值
- * event按键事件
- */
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- //判断是否点击menu按钮
- if(keyCode == KeyEvent.KEYCODE_MENU){
- //判断一级菜单
- //如果是隐藏状态,那么就显示一级菜单和二级菜单
- if(!isLevel1Show){
- Tools.showView(level1);
- isLevel1Show = true;
- //同时显示二级菜单
- Tools.showView(level2,200);
- isLevel2Show = true;
- }else{
- //如果一级菜单是显示状态
- //隐藏一级菜单 同时判断 ,隐藏二,三级菜单
- Tools.hiddenView(level1);
- isLevel1Show = false;
- if(isLevel2Show){
- Tools.hiddenView(level2,200);
- isLevel2Show = false;
- if(isLevel3Show){
- Tools.hiddenView(level3, 300);
- isLevel3Show = false;
- }
- }
- }
- return true;
- }
- return super.onKeyDown(keyCode, event);
- }
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.icon_menu://响应menu图标的监听事件
- if(isLevel3Show){
- //隐藏三级菜单
- Tools.hiddenView(level3);
- isLevel3Show = false;
- }else{
- //显示三级菜单
- Tools.showView(level3);
- isLevel3Show = true;
- }
- break;
- case R.id.icon_home://响应home图标的监听事件
- if(isLevel2Show){
- //如果二级菜单是显示状态,那么隐藏二级菜单
- Tools.hiddenView(level2);
- isLevel2Show = false;
- //同时判断,三级菜单的状态,如果是显示,同样也隐藏三级菜单
- if(isLevel3Show){
- Tools.hiddenView(level3,500);
- isLevel3Show = false;
- }
- }else{
- //如果二级菜单是隐藏状态,那么显示二级菜单
- Tools.showView(level2);
- isLevel2Show = true;
- }
- break;
- }
- }
- }
优酷效果图的整体完成和bug的修复:
仔细观察效果图:会发现一点点的小bug。当我们通过menu按键隐藏一二三级菜单的时候,我们点击布局的空白处,同样会出现某些级的菜单。我们这里修复这个bug
- package com.example.youkumenu;
- import android.view.View;
- import android.view.ViewGroup;
- import android.view.animation.RotateAnimation;
- public class Tools {
- public static void showView(ViewGroup view) {
- showView(view, 0);
- }
- public static void hiddenView(ViewGroup view) {
- hiddenView(view, 0);
- }
- public static void hiddenView(ViewGroup view, int startOffset) {
- /**
- * RotateAnimation 中的四个参数:
- * fromDegrees 从多少度
- * toDegrees 到多少度
- * pivotX 中心点的x坐标
- * pivotY 中心点的Y坐标
- */
- RotateAnimation ra = new RotateAnimation(0, 180, view.getWidth() / 2,
- view.getHeight());
- // 设置动画的运行时间
- ra.setDuration(500);
- // 动画执行完后,保持现有的状态
- ra.setFillAfter(true);
- // 设置动画执行的延时时间
- ra.setStartOffset(startOffset);
- // 让view执行动画
- view.startAnimation(ra);
- <span style="color:#cc33cc;">for (int i = 0; i < view.getChildCount(); i++) {
- View child = view.getChildAt(i);
- child.setVisibility(View.GONE);
- }</span>
- }
- public static void showView(ViewGroup view, int startOffset) {
- RotateAnimation ra = new RotateAnimation(180, 360, view.getWidth() / 2,
- view.getHeight());
- // 设置动画的运行时间
- ra.setDuration(500);
- // 动画执行完后,保持现有的状态
- ra.setFillAfter(true);
- // 设置动画执行的延时时间
- ra.setStartOffset(startOffset);
- // 让view执行动画
- view.startAnimation(ra);
- <span style="color:#cc33cc;">/**
- * ViewGroup中的方法介绍:
- * getChildCount()返回子View的数量
- * getChildAt(i)获得指定小标的子view
- */
- for (int i = 0; i < view.getChildCount(); i++) {
- View child = view.getChildAt(i);
- child.setVisibility(View.VISIBLE);
- }</span>
- }
- }