1.优酷菜单
实现效果如下:
分析实现原理
当我们去做一个效果的时候,要考虑是否有多种方案去实现。
如果有,就把所以的方案列举出来,并且用最简单或者你最熟悉的一种方式去实现该功能。
通过布局实现效果
实现步骤
1_创建工程:01.优酷菜单
2_实现三个圆环-最里面的圆环
3_实现三个圆环-中间园环
4_实现三个圆环-最外环
5_最里环的的图标
6_中间环的图标
7_最外环的图标的左边部分
8_最外环的图标的右边部分
布局分析
level3 会覆盖其他level,所以需要调整一下顺序
用到的一些图片素材
布局文件代码
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<RelativeLayout
android:id="@+id/level3"
android:layout_width="280dip"
android:layout_height="140dip"
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:layout_alignParentBottom="true"
android:layout_marginBottom="10dip"
android:layout_marginLeft="10dip"
android:src="@drawable/channel1" />
<ImageView
android:id="@+id/channel2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/channel1"
android:layout_marginBottom="10dip"
android:layout_marginLeft="35dip"
android:src="@drawable/channel2" />
<ImageView
android:id="@+id/channel3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/channel2"
android:layout_marginBottom="10dip"
android:layout_marginLeft="75dip"
android:src="@drawable/channel3" />
<ImageView
android:layout_marginTop="5dip"
android:id="@+id/channel4"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/channel4" />
<ImageView
android:id="@+id/channel7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="10dip"
android:layout_alignParentRight="true"
android:layout_marginRight="10dip"
android:src="@drawable/channel7" />
<ImageView
android:id="@+id/channel6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/channel7"
android:layout_marginBottom="10dip"
android:layout_marginRight="35dip"
android:layout_alignParentRight="true"
android:src="@drawable/channel6" />
<ImageView
android:id="@+id/channel5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/channel6"
android:layout_marginBottom="10dip"
android:layout_marginRight="75dip"
android:layout_alignParentRight="true"
android:src="@drawable/channel5" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/level2"
android:layout_width="180dip"
android:layout_height="90dip"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="@drawable/level2" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="10dip"
android:layout_marginLeft="10dip"
android:src="@drawable/icon_search" />
<ImageView
android:id="@+id/icon_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="5dip"
android:src="@drawable/icon_menu" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="10dip"
android:layout_marginRight="10dip"
android:src="@drawable/icon_myyouku" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/level1"
android:layout_width="100dip"
android:layout_height="50dip"
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:src="@drawable/icon_home" />
</RelativeLayout>
</RelativeLayout>
代码处理逻辑
1_初始化三环的控件,并设置icon_menu和icon_menu的点击事件
首先初始化视图
private ImageView icon_home;
private ImageView icon_menu;
private RelativeLayout level1;
private RelativeLayout level2;
private RelativeLayout level3;
/**
* 初始化视图
*/
private void initView()
{
icon_home = (ImageView) findViewById(R.id.icon_home);
icon_menu = (ImageView) findViewById(R.id.icon_menu);
level1 = (RelativeLayout) findViewById(R.id.level1);
level2 = (RelativeLayout) findViewById(R.id.level2);
level3 = (RelativeLayout) findViewById(R.id.level3);
}
设置监听
/**
* 监听
*/
private void initListener()
{
icon_home.setOnClickListener(this);
icon_menu.setOnClickListener(this);
level1.setOnClickListener(this);
level2.setOnClickListener(this);
level3.setOnClickListener(this);
}
2_菜单的显示和隐藏
先定义一个标志位,默认显示三级菜单
/**
* 是否显示第三圆环
* true:显示
* false隐藏
*/
private boolean isShowLevel3=true;
在监听事件的回调方法中,处理逻辑,如果icon_menu是显示状态就隐藏,且将isShowLevel3的值置为false,反之同理
case R.id.icon_menu:
if(isShowLevel3)
{
//隐藏
isShowLevel3=false;
Tools.hideView(level3);
}
else
{
//显示
isShowLevel3=true;
Tools.showView(level3);
}
break;
case R.id.icon_home:
//如果三级菜单和二级菜单是显示,都设置隐藏
if(isShowLevel2)
{
//隐藏二级菜单
isShowLevel2=false;
Tools.hideView(level2);
if(isShowLevel3)
{
//隐藏三级菜单
isShowLevel3=false;
Tools.hideView(level3);
}
}
else
{
//如果都是隐藏的,二级菜单显示
//显示二级菜单
isShowLevel2=true;
Tools.showView(level2);
}
break;
这里提供了一个Tools工具类,主要用于封装一些隐藏显示等操作,类中涉及一些动画的操作,先上一张图把原理整明白。
public static void showView(ViewGroup view, int startOffset)
{
ObjectAnimator animator=ObjectAnimator.ofFloat(view, "rotation",180,360);//rotation为float类型,所以用ofFloat
animator.setDuration(500);
animator.setStartDelay(startOffset);
animator.start();
//确定旋转中心
view.setPivotX(view.getWidth()/2);
view.setPivotY(view.getHeight());//控件的高
}
public static void hideView(ViewGroup view, int startOffset)
{
ObjectAnimator animator=ObjectAnimator.ofFloat(view, "rotation", 0,180);
animator.setDuration(500);//动画持续时间
animator.setStartDelay(startOffset);//延迟多久后播放动画
animator.start();
//确定旋转中心
view.setPivotX(view.getWidth()/2);
view.setPivotY(view.getHeight());
}
4_设置延迟动画setStartOffset()方法和代码重构
animator.setStartDelay(startOffset);//延迟多久后播放动画
代码重构主要是服用代码,提供参数不同的同名方法
public static void hideView(ViewGroup view)
{
hideView(view,0);
}
public static void showView(ViewGroup view)
{
showView(view,0);
}
5._监听手机menu按键实现菜单隐藏和显示
MainActivity中重写onKeyDown()方法
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if(keyCode==KeyEvent.KEYCODE_MENU)
{
//如果一级,二级,三级菜单是显示的就全部隐藏
if(isShowLevel)
{
isShowLevel=false;
Tools.hideView(level1);
if(isShowLevel2)
{
//隐藏二级菜单
isShowLevel2=false;
Tools.hideView(level2);
if(isShowLevel3)
{
//隐藏三级菜单
isShowLevel3=false;
Tools.hideView(level3);
}
}
}
else
{
//如果一级,二级菜单隐藏,就显示
//显示一级菜单
isShowLevel=true;
Tools.showView(level1);
//显示二级菜单
isShowLevel2 = true;
Tools.showView(level2,200);
}
return true;//表示已经处理掉了
}
return super.onKeyDown(keyCode, event);
}
06_优酷效果的完成和bug修复
bug:使用补间动画带来的bug,单击隐藏后,点击任然生效
方式一:
在hideView()方法中添加如下代码,前提是应该把相对布局转换为ViewGroup,因为转换为View,部分属性会丢失,不能操作子view。得到每一个子View。
for(i<view.getChildCount();i++)
{
view children = view.getChildAt(i);//实际上就是ImageView
children.setEnabled(false);//隐藏的时候不可以点击
}
同样在showView()方法中添加如下代码
for(i<view.getChildCount();i++)
{
view children = view.getChildAt(i);
children.setEnabled(true);//显示的时候可以点击
}
方式二:属性动画(动画的具体原理等知识参考动画相关的笔记)
ObjectAnimator animator=ObjectAnimator.ofFloat(view, "rotation",180,360);//rotation为float类型,所以用ofFloat
animator.setDuration(500);
animator.setStartDelay(startOffset);
animator.start();
//确定旋转中心,控件自身旋转的坐标,是以当前控件的左上方为原点坐标。
view.setPivotX(view.getWidth()/2);
view.setPivotY(view.getHeight());//控件的高