Android仿优酷圆形菜单学习笔记分享

Android仿优酷圆形菜单学习笔记分享,第1张

概述先来看看效果:首先来分析一下:这个菜单可以分成三个菜单:1.一级菜单(即最内圈那个菜单)

先来看看效果:

首先来分析一下:

这个菜单可以分成三个菜单:

1.一级菜单(即最内圈那个菜单)

2.二级菜单(即中间圈那个菜单)

3.三级菜单(即最外圈那个菜单)

首先,可以将这三个菜单使用相对布局

一级菜单只有一个按钮(即home),可以控制二级和三级菜单

二级菜单有三个按钮(即menu),中间那个按钮可以控制三级菜单

三级菜单有七个按钮

那先把布局文件先写出来,采用三个相对布局(即每个菜单采用一个相对布局)

<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.example.youkumenu.MainActivity" >  <!-- 三级菜单 -->  <relativeLayout    androID:ID="@+ID/level3_Rl"    androID:layout_wIDth="220dp"    androID:layout_height="110dp"    androID:layout_alignParentBottom="true"    androID:layout_centerHorizontal="true"    androID:background="@drawable/level3" >    <ImageVIEw      androID:ID="@+ID/channel1"      androID:layout_marginleft="5dp"      androID:layout_alignParentBottom="true"       androID:layout_wIDth="wrap_content"      androID:layout_height="wrap_content"      androID:src="@drawable/channel1"/>    <ImageVIEw      androID:ID="@+ID/channel2"      androID:layout_marginBottom="10dp"      androID:layout_marginleft="25dp"      androID:layout_above="@ID/channel1"      androID:layout_wIDth="wrap_content"      androID:layout_height="wrap_content"      androID:src="@drawable/channel2"/>    <ImageVIEw      androID:layout_marginBottom="1dp"      androID:layout_marginleft="52dp"      androID:layout_above="@ID/channel2"      androID:layout_wIDth="wrap_content"      androID:layout_height="wrap_content"      androID:src="@drawable/channel3"/>    <ImageVIEw      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_marginRight="5dp"      androID:layout_alignParentRight="true"      androID:layout_alignParentBottom="true"       androID:layout_wIDth="wrap_content"      androID:layout_height="wrap_content"      androID:src="@drawable/channel7"/>    <ImageVIEw      androID:ID="@+ID/channel6"      androID:layout_alignParentRight="true"      androID:layout_marginBottom="10dp"      androID:layout_marginRight="25dp"      androID:layout_above="@ID/channel7"      androID:layout_wIDth="wrap_content"      androID:layout_height="wrap_content"      androID:src="@drawable/channel6"/>    <ImageVIEw      androID:layout_marginBottom="1dp"      androID:layout_marginRight="52dp"      androID:layout_alignParentRight="true"      androID:layout_above="@ID/channel6"      androID:layout_wIDth="wrap_content"      androID:layout_height="wrap_content"      androID:src="@drawable/channel5"/>  </relativeLayout>  <!-- 二级菜单 -->  <relativeLayout    androID:ID="@+ID/level2_Rl"    androID:layout_wIDth="140dp"    androID:layout_height="70dp"    androID:layout_alignParentBottom="true"    androID:layout_centerHorizontal="true"    androID:background="@drawable/level2" >    <ImageVIEw      androID:layout_marginleft="3dp"      androID:layout_alignParentBottom="true"      androID:layout_wIDth="wrap_content"      androID:layout_height="wrap_content"      androID:src="@drawable/icon_search"/>    <ImageVIEw      androID:ID="@+ID/menu_Iv"      androID:layout_centerHorizontal="true"      androID:layout_wIDth="wrap_content"      androID:layout_height="wrap_content"      androID:src="@drawable/icon_menu"/>    <ImageVIEw      androID:ID="@+ID/myyouku_Iv"      androID:layout_marginRight="3dp"      androID:layout_alignParentBottom="true"      androID:layout_alignParentRight="true"      androID:layout_wIDth="wrap_content"      androID:layout_height="wrap_content"      androID:src="@drawable/icon_myyouku"/>  </relativeLayout>  <!-- 一级菜单 -->  <relativeLayout    androID:layout_wIDth="80dp"    androID:layout_height="40dp"    androID:layout_alignParentBottom="true"    androID:layout_centerHorizontal="true"    androID:background="@drawable/level1" >    <ImageVIEw      androID:ID="@+ID/home_Iv"      androID:layout_centerInParent="true"      androID:layout_wIDth="wrap_content"      androID:layout_height="wrap_content"      androID:src="@drawable/icon_home" />  </relativeLayout></relativeLayout>

那好,布局写好,就能看到这样的效果,只不过现在只是静态的,没有加逻辑而已

下面就该来分析下逻辑了,先来看看home(即一级菜单中间那个按钮)

点击home,会有三种情况,下面分情况考虑:

情况1.二级、三级菜单都显示,就将二、三级菜单隐藏掉

情况2.二、三级菜单都不显示的时候,就将二级菜单显示

情况3.二级菜单显示且三级菜单不显示的时候,就将二级菜单隐藏

当然我们知道,要知道菜单隐藏或者显示,只需要设个标记位即可

那要如何隐藏或显示菜单,当然是使用动画了,可以使用补间动画和

属性动画,我这里就使用补间动画

下面就该来分析下逻辑了,先来看看menu(即二级菜单中间那个按钮)

点击menu,会有三种情况,下面分情况考虑:

情况1.三级显示的时候,就将三级菜单隐藏

情况2.三级隐藏的时候,就将三级菜单显示

这个就比较简单了,就两种情况。

public class MainActivity extends Activity implements OnClickListener{  //一级菜单中的home按钮  private ImageVIEw home_Iv;  //二级菜单中的Menu按钮  private ImageVIEw menu_Iv;  //用于判断二级菜单的显示状况,true为显示,false为隐藏  private boolean level2ListPlay = true;  //用于判断二级菜单的显示状况,true为显示,false为隐藏  private boolean level3ListPlay = true;  //二级和三级菜单  private relativeLayout level2_Rl,level3_Rl;  @OverrIDe  protected voID onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentVIEw(R.layout.activity_main);    initVIEw();  }    //初始化组件  private voID initVIEw() {    home_Iv = (ImageVIEw) findVIEwByID(R.ID.home_Iv);    home_Iv.setonClickListener(this);    level2_Rl = (relativeLayout) findVIEwByID(R.ID.level2_Rl);    level3_Rl = (relativeLayout) findVIEwByID(R.ID.level3_Rl);    menu_Iv = (ImageVIEw) findVIEwByID(R.ID.menu_Iv);    menu_Iv.setonClickListener(this);  }  @OverrIDe  public voID onClick(VIEw v) {    switch (v.getID()) {    case R.ID.home_Iv:   //点击home按钮的逻辑代码      clickHomeIv();      break;    case R.ID.menu_Iv:      clickMenuIv();   //点击二级菜单中的menu按钮的逻辑代码      break;    default:      break;    }  }  //点击二级菜单中的menu按钮的逻辑代码  private voID clickMenuIv() {    //分情况考虑    //1.三级显示的时候,就将三级菜单隐藏    if (level3ListPlay) {      hIDeMenu(level3_Rl,0);      level3ListPlay = false;      return;    }    //2.三级隐藏的时候,就将三级菜单显示    if (!level3ListPlay) {      showMenu(level3_Rl);      level3ListPlay = true;      return;    }  }  //点击一级菜单中的home按钮的逻辑代码  private voID clickHomeIv() {    //分情况考虑    //1.二级、三级菜单都显示,就将二、三级菜单隐藏掉    if (level2ListPlay && level3ListPlay) {      //将二三级菜单隐藏,并改变标记      hIDeMenu(level2_Rl,300);      hIDeMenu(level3_Rl,500);      level2ListPlay = false;      level3ListPlay = false;      return;    }    //2.二、三级菜单都不显示的时候,就将二级菜单显示    if (!level2ListPlay && !level3ListPlay) {      showMenu(level2_Rl);      level2ListPlay = true;      return;    }    //3.二级菜单显示且三级菜单不显示的时候,就将二级菜单隐藏    if (level2ListPlay && !level3ListPlay) {      hIDeMenu(level2_Rl,0);      level2ListPlay = false;      return;    }  }  /**   * 显示菜单   * @param vIEw 要显示的菜单   */  private voID showMenu(relativeLayout vIEw) {//   vIEw.setVisibility(VIEw.VISIBLE);    //旋转动画    RotateAnimation animation = new RotateAnimation(-180,Animation.relative_TO_SELF,0.5f,1.0f);    animation.setDuration(500);   //设置动画持续的时间    animation.setFillAfter(true); //动画停留在动画结束的位置    vIEw.startAnimation(animation);  }  /**   * 隐藏菜单   * @param vIEw 要隐藏的菜单,startOffset 动画延迟执行的时间   */  private voID hIDeMenu(relativeLayout vIEw,long startOffset) {//   vIEw.setVisibility(VIEw.GONE);    /**      * 旋转动画      * RotateAnimation(fromdegrees,todegrees,pivotXType,pivotXValue,pivotYType,pivotYValue)      * fromdegrees 开始旋转角度      * todegrees 旋转的结束角度      * pivotXType X轴 参照物 (X轴的伸缩模式,可以取值为absolute、relative_TO_SELF)     * pivotXValue x轴 旋转的参考点(x坐标的伸缩值)      * pivotYType Y轴 参照物 (Y轴的伸缩模式,可以取值为absolute、relative_TO_SELF)     * pivotYValue Y轴 旋转的参考点 ((Y坐标的伸缩值) )     */     RotateAnimation animation = new RotateAnimation(0,-180,1.0f);    animation.setDuration(500);    animation.setFillAfter(true); //动画停留在动画结束的位置    animation.setStartOffset(startOffset);   //设置动画的延迟执行    vIEw.startAnimation(animation);  }}

写到这里,应该差不多可以看到效果了,但是细心的伙伴应该会发现两个BUG:

第一:当你快速点击一级菜单home按钮或二级菜单menu按钮的时候,会发现二级菜单或三级菜单的第一次动画还没执行完,又执行第二次动画,看起来就在晃一样。(原因:就是执行的动画都设定了一定时间,你点击的时间快于动画执行的时间)

解决办法:

对动画进行监听,当动画开始执行和结束的时候,对它进行监听,大家应该会想到用一个标记位来判断,可我们知道一个标记为只能判断两种状态,可这里有两种动画(显示的动画和隐藏的动画),一个标记位肯定不行,可以用一个Int值来控制

//用于记录有多少个动画在执行  private int annimationCount = 0;  //对动画进行监听的时候  animation.setAnimationListener(new AnimationListener() {      @OverrIDe      public voID onAnimationStart(Animation animation) {//       menu_Iv.setonClickListener(null);//       home_Iv.setonClickListener(null);        annimationCount ++;      }      @OverrIDe      public voID onAnimationRepeat(Animation animation) {      }      @OverrIDe      public voID onAnimationEnd(Animation animation) {//       menu_Iv.setonClickListener(MainActivity.this);//       home_Iv.setonClickListener(MainActivity.this);        annimationCount --;      }    //当点击的时候就可以进行判断,只要annimationCount值大于0,说明还有动画在执行    if (annimationCount > 0) {      return ;    }

第二:当二级菜单隐藏的时候,你点击二级菜单中menu按钮(虽然现在看不见)时,你会惊奇的发现三级菜单居然显示了。(原因:补间动画,没有真正的改变组件的属性,而属性动画就不一样,大家有时间可以试试属性动画做做)

解决办法:

只要当二级菜单隐藏的时候,就让二级菜单的所有选项按钮都不可点。因为二级菜单有可以能有多个按钮,所以拿到父容器,去使它的子控件失去焦点即可。

//如果要显示菜单,那么就将相应的控件设为有焦点    //获取父容器中有几个子控件    int childCount = vIEw.getChildCount();    for (int i = 0; i < childCount; i++) {      vIEw.getChildAt(i).setEnabled(true);    }

写到这里就差不多了,大家可以试试

这里把我写的完整代码贴出来:

public class MainActivity extends Activity implements OnClickListener{  //一级菜单中的home按钮  private ImageVIEw home_Iv;  //二级菜单中的Menu按钮  private ImageVIEw menu_Iv;  //用于判断二级菜单的显示状况,true为显示,false为隐藏  private boolean level2ListPlay = true;  //用于判断二级菜单的显示状况,true为显示,false为隐藏  private boolean level3ListPlay = true;  //二级和三级菜单  private relativeLayout level2_Rl,level3_Rl;  //用于记录有多少个动画在执行  private int annimationCount = 0;  @OverrIDe  protected voID onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentVIEw(R.layout.activity_main);    initVIEw();  }    //初始化组件  private voID initVIEw() {    home_Iv = (ImageVIEw) findVIEwByID(R.ID.home_Iv);    home_Iv.setonClickListener(this);    level2_Rl = (relativeLayout) findVIEwByID(R.ID.level2_Rl);    level3_Rl = (relativeLayout) findVIEwByID(R.ID.level3_Rl);    menu_Iv = (ImageVIEw) findVIEwByID(R.ID.menu_Iv);    menu_Iv.setonClickListener(this);  }  @OverrIDe  public voID onClick(VIEw v) {    switch (v.getID()) {    case R.ID.home_Iv:   //点击home按钮的逻辑代码      clickHomeIv();      break;    case R.ID.menu_Iv:      clickMenuIv();   //点击二级菜单中的menu按钮的逻辑代码      break;    default:      break;    }  }  //点击二级菜单中的menu按钮的逻辑代码  private voID clickMenuIv() {    //当点击的时候就可以进行判断,只要annimationCount值大于0,说明还有动画在执行    if (annimationCount > 0) {      return ;    }    //分情况考虑    //1.三级显示的时候,就将三级菜单隐藏    if (level3ListPlay) {      hIDeMenu(level3_Rl,0);      level3ListPlay = false;      return;    }    //2.三级隐藏的时候,就将三级菜单显示    if (!level3ListPlay) {      showMenu(level3_Rl);      level3ListPlay = true;      return;    }  }  //点击一级菜单中的home按钮的逻辑代码  private voID clickHomeIv() {    //当点击的时候就可以进行判断,只要annimationCount值大于0,说明还有动画在执行    if (annimationCount > 0) {      return ;    }    //分情况考虑    //1.二级、三级菜单都显示,就将二、三级菜单隐藏掉    if (level2ListPlay && level3ListPlay) {      //将二三级菜单隐藏,并改变标记      hIDeMenu(level2_Rl,0);      level2ListPlay = false;      return;    }  }  /**   * 显示菜单   * @param vIEw 要显示的菜单   */  private voID showMenu(relativeLayout vIEw) {//   vIEw.setVisibility(VIEw.VISIBLE);    //如果要显示菜单,那么就将相应的控件设为有焦点    //获取父容器中有几个子控件    int childCount = vIEw.getChildCount();    for (int i = 0; i < childCount; i++) {      vIEw.getChildAt(i).setEnabled(true);    }    //旋转动画    RotateAnimation animation = new RotateAnimation(-180,1.0f);    animation.setDuration(500);   //设置动画持续的时间    animation.setFillAfter(true); //动画停留在动画结束的位置    vIEw.startAnimation(animation);    animation.setAnimationListener(new AnimationListener() {      @OverrIDe      public voID onAnimationStart(Animation animation) {        //动画开始的时候回调//       menu_Iv.setonClickListener(null);//       home_Iv.setonClickListener(null);        annimationCount ++;      }      @OverrIDe      public voID onAnimationRepeat(Animation animation) {        //动画执行过程调用      }      @OverrIDe      public voID onAnimationEnd(Animation animation) {        //动画结束的时候调用//       menu_Iv.setonClickListener(MainActivity.this);//       home_Iv.setonClickListener(MainActivity.this);        annimationCount --;      }    });  }  /**   * 隐藏菜单   * @param vIEw 要隐藏的菜单,long startOffset) {//   vIEw.setVisibility(VIEw.GONE);    //如果要隐藏菜单,那么就将相应的控件设为没有焦点    //获取父容器中有几个子控件    int childCount = vIEw.getChildCount();    for (int i = 0; i < childCount; i++) {      vIEw.getChildAt(i).setEnabled(false);    }    /**      * 旋转动画      * RotateAnimation(fromdegrees,1.0f);    animation.setDuration(500);    animation.setFillAfter(true); //动画停留在动画结束的位置    animation.setStartOffset(startOffset);   //设置动画的延迟执行    vIEw.startAnimation(animation);    animation.setAnimationListener(new AnimationListener() {      @OverrIDe      public voID onAnimationStart(Animation animation) {//       menu_Iv.setonClickListener(null);//       home_Iv.setonClickListener(null);        annimationCount ++;      }      @OverrIDe      public voID onAnimationRepeat(Animation animation) {      }      @OverrIDe      public voID onAnimationEnd(Animation animation) {//       menu_Iv.setonClickListener(MainActivity.this);//       home_Iv.setonClickListener(MainActivity.this);        annimationCount --;      }    });  }}

布局文件:

<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.example.youkumenu.MainActivity" >  <!-- 三级菜单 -->  <relativeLayout    androID:ID="@+ID/level3_Rl"    androID:layout_wIDth="220dp"    androID:layout_height="110dp"    androID:layout_alignParentBottom="true"    androID:layout_centerHorizontal="true"    androID:background="@drawable/level3" >    <ImageVIEw      androID:ID="@+ID/channel1"      androID:layout_marginleft="5dp"      androID:layout_alignParentBottom="true"       androID:layout_wIDth="wrap_content"      androID:layout_height="wrap_content"      androID:src="@drawable/channel1"/>    <ImageVIEw      androID:ID="@+ID/channel2"      androID:layout_marginBottom="10dp"      androID:layout_marginleft="25dp"      androID:layout_above="@ID/channel1"      androID:layout_wIDth="wrap_content"      androID:layout_height="wrap_content"      androID:src="@drawable/channel2"/>    <ImageVIEw      androID:layout_marginBottom="1dp"      androID:layout_marginleft="52dp"      androID:layout_above="@ID/channel2"      androID:layout_wIDth="wrap_content"      androID:layout_height="wrap_content"      androID:src="@drawable/channel3"/>    <ImageVIEw      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_marginRight="5dp"      androID:layout_alignParentRight="true"      androID:layout_alignParentBottom="true"       androID:layout_wIDth="wrap_content"      androID:layout_height="wrap_content"      androID:src="@drawable/channel7"/>    <ImageVIEw      androID:ID="@+ID/channel6"      androID:layout_alignParentRight="true"      androID:layout_marginBottom="10dp"      androID:layout_marginRight="25dp"      androID:layout_above="@ID/channel7"      androID:layout_wIDth="wrap_content"      androID:layout_height="wrap_content"      androID:src="@drawable/channel6"/>    <ImageVIEw      androID:layout_marginBottom="1dp"      androID:layout_marginRight="52dp"      androID:layout_alignParentRight="true"      androID:layout_above="@ID/channel6"      androID:layout_wIDth="wrap_content"      androID:layout_height="wrap_content"      androID:src="@drawable/channel5"/>  </relativeLayout>  <!-- 二级菜单 -->  <relativeLayout    androID:ID="@+ID/level2_Rl"    androID:layout_wIDth="140dp"    androID:layout_height="70dp"    androID:layout_alignParentBottom="true"    androID:layout_centerHorizontal="true"    androID:background="@drawable/level2" >    <ImageVIEw      androID:layout_marginleft="3dp"      androID:layout_alignParentBottom="true"      androID:layout_wIDth="wrap_content"      androID:layout_height="wrap_content"      androID:src="@drawable/icon_search"/>    <ImageVIEw      androID:ID="@+ID/menu_Iv"      androID:layout_centerHorizontal="true"      androID:layout_wIDth="wrap_content"      androID:layout_height="wrap_content"      androID:src="@drawable/icon_menu"/>    <ImageVIEw      androID:ID="@+ID/myyouku_Iv"      androID:layout_marginRight="3dp"      androID:layout_alignParentBottom="true"      androID:layout_alignParentRight="true"      androID:layout_wIDth="wrap_content"      androID:layout_height="wrap_content"      androID:src="@drawable/icon_myyouku"/>  </relativeLayout>  <!-- 一级菜单 -->  <relativeLayout    androID:layout_wIDth="80dp"    androID:layout_height="40dp"    androID:layout_alignParentBottom="true"    androID:layout_centerHorizontal="true"    androID:background="@drawable/level1" >    <ImageVIEw      androID:ID="@+ID/home_Iv"      androID:layout_centerInParent="true"      androID:layout_wIDth="wrap_content"      androID:layout_height="wrap_content"      androID:src="@drawable/icon_home" />  </relativeLayout></relativeLayout>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家继续关注编程小技巧的更多精彩内容!

总结

以上是内存溢出为你收集整理的Android仿优酷圆形菜单学习笔记分享全部内容,希望文章能够帮你解决Android仿优酷圆形菜单学习笔记分享所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1149257.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存