Android编程实现仿优酷旋转菜单效果(附demo源码)

所属分类: 软件编程 / Android 阅读数: 1679
收藏 0 赞 0 分享

本文实例讲述了Android编程实现仿优酷旋转菜单效果。分享给大家供大家参考,具体如下:

首先,看下效果:

不好意思,不会制作动态图片,只好上传静态的了,如果谁会,请教教我吧。

首先,看下xml文件:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  android:layout_width="fill_parent" 
  android:layout_height="fill_parent" 
  android:background="#c9c9c9" > 
  <RelativeLayout 
    android:id="@+id/relate_level3" 
    android:layout_width="280dp" 
    android:layout_height="140dp" 
    android:layout_alignParentBottom="true" 
    android:layout_centerHorizontal="true" 
    android:background="@drawable/level3" > 
    <ImageButton 
     android:id="@+id/c1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentBottom="true" 
     android:layout_marginBottom="6dip" 
     android:layout_marginLeft="12dip" 
     android:background="@drawable/channel1" /> 
    <ImageButton 
     android:id="@+id/c2" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_above="@+id/c1" 
     android:layout_marginBottom="12dip" 
     android:layout_marginLeft="28dip" 
     android:background="@drawable/channel2" /> 
    <ImageButton 
     android:id="@+id/c3" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_above="@+id/c2" 
     android:layout_marginBottom="8dip" 
     android:layout_marginLeft="6dip" 
     android:layout_toRightOf="@+id/c2" 
     android:background="@drawable/channel3" /> 
    <ImageButton 
     android:id="@+id/c4" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_centerHorizontal="true" 
     android:layout_margin="6dip" 
     android:background="@drawable/channel4" /> 
    <ImageButton 
     android:id="@+id/c5" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_above="@+id/c6" 
     android:layout_marginBottom="8dip" 
     android:layout_marginRight="6dip" 
     android:layout_toLeftOf="@+id/c6" 
     android:background="@drawable/channel5" /> 
    <ImageButton 
     android:id="@+id/c6" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_above="@+id/c7" 
     android:layout_alignParentRight="true" 
     android:layout_marginBottom="12dip" 
     android:layout_marginRight="28dip" 
     android:background="@drawable/channel6" /> 
    <ImageButton 
     android:id="@+id/c7" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentBottom="true" 
     android:layout_alignParentRight="true" 
     android:layout_marginBottom="6dip" 
     android:layout_marginRight="12dip" 
     android:background="@drawable/channel7" /> 
  </RelativeLayout> 
  <RelativeLayout 
    android:id="@+id/relate_level2" 
    android:layout_width="180dp" 
    android:layout_height="90dp" 
    android:layout_alignParentBottom="true" 
    android:layout_centerHorizontal="true" 
    android:background="@drawable/level2" > 
    <ImageButton 
     android:id="@+id/menu" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_centerHorizontal="true" 
     android:layout_margin="6dip" 
     android:background="@drawable/icon_menu" /> 
    <ImageButton 
     android:id="@+id/search" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentBottom="true" 
     android:layout_margin="10dip" 
     android:background="@drawable/icon_search" /> 
    <ImageButton 
     android:id="@+id/myyouku" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentBottom="true" 
     android:layout_alignParentRight="true" 
     android:layout_margin="10dip" 
     android:background="@drawable/icon_myyouku" /> 
  </RelativeLayout> 
  <RelativeLayout 
    android:id="@+id/relate_level1" 
    android:layout_width="100dp" 
    android:layout_height="50dp" 
    android:layout_alignParentBottom="true" 
    android:layout_centerHorizontal="true" 
    android:background="@drawable/level1" > 
    <ImageButton 
     android:id="@+id/home" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentBottom="true" 
     android:layout_centerHorizontal="true" 
     android:layout_marginBottom="10dp" 
     android:background="@drawable/icon_home" /> 
  </RelativeLayout> 
</RelativeLayout>

大家看到主要有三个RalativeLayout,就是大家看到的三层,但是关于图片的倾斜 是怎样实现的呢?实际上是个假象,图片是正放的,里面图像是倾斜的。如下图:

这样大概能明白,下面就是开始动画效果了,先看下主Activity:

public class TestYoukuActivity extends Activity { 
  /** Called when the activity is first created. */ 
  private boolean areLevel2Showing = true, areLevel3Showing = true; 
  private RelativeLayout relate_level2, relate_level3; 
  private ImageButton home, menu; 
  @Override 
  public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    findViews(); 
    setListener();  
  } 
  private void findViews() { 
    relate_level2 = (RelativeLayout) findViewById(R.id.relate_level2); 
    relate_level3 = (RelativeLayout) findViewById(R.id.relate_level3); 
    home = (ImageButton) findViewById(R.id.home); 
    menu = (ImageButton) findViewById(R.id.menu); 
  } 
  private void setListener() { 
    // 给大按钮设置点击事件 
    home.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
       if (!areLevel2Showing) { 
        MyAnimation.startAnimationsIn(relate_level2, 500); 
       } else { 
        if (areLevel3Showing) { 
          MyAnimation.startAnimationsOut(relate_level2, 500, 500); 
          MyAnimation.startAnimationsOut(relate_level3, 500, 0); 
          areLevel3Showing = !areLevel3Showing; 
        } else { 
          MyAnimation.startAnimationsOut(relate_level2, 500, 0); 
        } 
       } 
       areLevel2Showing = !areLevel2Showing; 
     } 
    }); 
    menu.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
       if (!areLevel3Showing) { 
        MyAnimation.startAnimationsIn(relate_level3, 500); 
       } else { 
        MyAnimation.startAnimationsOut(relate_level3, 500, 0); 
       } 
       areLevel3Showing = !areLevel3Showing; 
     } 
    }); 
  } 
}

应该注意到了:

复制代码 代码如下:
MyAnimation.startAnimationsIn(relate_level2, 500);

看一下这个静态方法的实现:

public static void startAnimationsIn(ViewGroup viewgroup, int durationMillis) {
    viewgroup.setVisibility(0); 
    for (int i = 0; i < viewgroup.getChildCount(); i++) { 
     viewgroup.getChildAt(i).setVisibility(0); 
     viewgroup.getChildAt(i).setClickable(true); 
     viewgroup.getChildAt(i).setFocusable(true); 
    } 
    Animation animation; 
    animation = new RotateAnimation(-180, 0, Animation.RELATIVE_TO_SELF, 
       0.5f, Animation.RELATIVE_TO_SELF, 1.0f); 
    animation.setFillAfter(true); 
    animation.setDuration(durationMillis); 
    viewgroup.startAnimation(animation); 
}

RotateAnimation是画面转移旋转动画效果,看一下它的构造方法:

RotateAnimation(Context context, AttributeSet attrs)
Constructor used when a RotateAnimation is loaded from a resource.
         RotateAnimation(float fromDegrees, float toDegrees)
Constructor to use when building a RotateAnimation from code.
RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY)
Constructor to use when building a RotateAnimation from code
         RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
Constructor to use when building a RotateAnimation from code

在这里使用的是第四个构造方法:

fromDegrees:旋转的开始角度。
toDegrees:旋转的结束角度。
pivotXType:X轴的伸缩模式,可以取值为ABSOLUTE、RELATIVE_TO_SELF、RELATIVE_TO_PARENT。
pivotXValue:X坐标的伸缩值。
pivotYType:Y轴的伸缩模式,可以取值为ABSOLUTE、RELATIVE_TO_SELF、RELATIVE_TO_PARENT。
pivotYValue:Y坐标的伸缩值。

关于角度问题:

当角度为负数——表示逆时针旋转 
当角度为正数——表示顺时针旋转
(负数from——to正数:顺时针旋转)
(负数from——to负数:逆时针旋转)
(正数from——to正数:顺时针旋转)
(正数from——to负数:逆时针旋转)

关于pivotXValue:这一点的X坐标的对象被旋转,在指定的绝对数字0是左边边缘。如果pivotXType数是绝对的这个值可以是一个绝对,另外也可以是百分比(在1.0为100%)。50%是x中点,100%为右边缘。
同理,pivotYValue:这一点的Y坐标的对象被旋转,在指定的绝对数字0是顶部边缘。如果pivotYType数是绝对的这个值可以是一个绝对,另外也可以是百分比(在1.0为100%)。50%是Y中点,100%为下边缘。

然后再看下调用的其他的方法:

setFillAfter:
If fillAfter is true, the transformation that this animation performed will persist when it is finished. Defaults to false if not set. Note that this applies when using an AnimationSet to chain animations. The transformation is not applied before the AnimationSet itself starts.

如果fillAfter为真,transformation 动画将一直运行直到它完成。默认设置为假。注意:这适用于当使用一个AnimationSet连锁动画。transformation 是不适用AnimationSet本身之前开始。

setDuration:设置动画时间。

再看一下退出:

// 图标的动画(出动画) 
public static void startAnimationsOut(final ViewGroup viewgroup, 
     int durationMillis, int startOffset) { 
    Animation animation; 
    animation = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 
       0.5f, Animation.RELATIVE_TO_SELF, 1.0f); 
    animation.setFillAfter(true); 
    animation.setDuration(durationMillis); 
    animation.setStartOffset(startOffset); 
    animation.setAnimationListener(new Animation.AnimationListener() { 
     @Override 
     public void onAnimationStart(Animation arg0) {} 
     @Override 
     public void onAnimationRepeat(Animation arg0) {} 
     @Override 
     public void onAnimationEnd(Animation arg0) { 
       viewgroup.setVisibility(8); 
       for (int i = 0; i < viewgroup.getChildCount(); i++) { 
        viewgroup.getChildAt(i).setVisibility(8); 
        viewgroup.getChildAt(i).setClickable(false); 
        viewgroup.getChildAt(i).setFocusable(false); 
       } 
     } 
    }); 
    viewgroup.startAnimation(animation); 
}

有一个animation.setStartOffset(startOffset);是设置animation多长时间以后执行。

最后:代码下载地址:

此处本站下载

希望本文所述对大家Android程序设计有所帮助。

更多精彩内容其他人还在看

Android样式和主题之选择器的实例讲解

今天小编就为大家分享一篇关于Android样式和主题之选择器的实例讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
收藏 0 赞 0 分享

Android应用动态修改主题的方法示例

今天小编就为大家分享一篇关于Android应用动态修改主题的方法示例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
收藏 0 赞 0 分享

Flutter 网络请求框架封装详解

这篇文章主要介绍了Flutter 网络请求框架封装详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

Flutter倒计时/计时器的实现代码

这篇文章主要介绍了Flutter倒计时/计时器的实现代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

Android使用google breakpad捕获分析native cash

这篇文章主要介绍了Android使用google breakpad捕获分析native cash 的相关知识,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

详解Flutter WebView与JS互相调用简易指南

这篇文章主要介绍了详解Flutter WebView与JS互相调用简易指南,分为JS调用Flutter和Flutter调用JS,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

Android开发实现ListView和adapter配合显示图片和文字列表功能示例

这篇文章主要介绍了Android开发实现ListView和adapter配合显示图片和文字列表功能,涉及Android使用ListView结合adapter适配器实现图文显示功能相关的布局、解析、权限控制等操作技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

Android文字基线Baseline算法的使用讲解

今天小编就为大家分享一篇关于Android文字基线Baseline算法的使用讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
收藏 0 赞 0 分享

Flutter自定义实现神奇动效的卡片切换视图的示例代码

这篇文章主要介绍了Flutter自定义实现神奇动效的卡片切换视图的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

Android实现自定义滑动刻度尺方法示例

这篇文章主要给大家介绍了关于Android实现自定义滑动刻度尺的相关资料,文中通过示例代码介绍的非常详细,对各位Android开发者们具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
收藏 0 赞 0 分享
查看更多