栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 移动开发 > Android

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

Android 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

本文实例为大家分享了Android优酷圆形菜单的具体代码,供大家参考,具体内容如下

先来看看效果:

首先来分析一下:

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

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

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

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

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

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

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

三级菜单有七个按钮

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



 

 

  
  
  
  
  
  
  
 

 

 
  
  
  

 
 

 

  
 


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

下面就该来分析下逻辑了,先来看看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;
  }

 }
 
 private void showMenu(RelativeLayout view) {
//  view.setVisibility(View.VISIBLE);
  //旋转动画
  RotateAnimation animation = new RotateAnimation(-180, 0, Animation.RELATIVE_TO_SELF, 
    0.5f, Animation.RELATIVE_TO_SELF, 1.0f);
  animation.setDuration(500);  //设置动画持续的时间
  animation.setFillAfter(true); //动画停留在动画结束的位置
  view.startAnimation(animation);
 }
 
 private void hideMenu(RelativeLayout view,long startOffset) {
//  view.setVisibility(View.GONE);
   
  RotateAnimation animation = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 
    0.5f, Animation.RELATIVE_TO_SELF, 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,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;
  }

 }
 
 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, 0, Animation.RELATIVE_TO_SELF, 
    0.5f, Animation.RELATIVE_TO_SELF, 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 --;
   }
  });
 }
 
 private void hideMenu(RelativeLayout view,long startOffset) {
//  view.setVisibility(View.GONE);
  //如果要隐藏菜单,那么就将相应的控件设为没有焦点
  //获取父容器中有几个子控件
  int childCount = view.getChildCount();
  for (int i = 0; i < childCount; i++) {
   view.getChildAt(i).setEnabled(false);
  }
   
  RotateAnimation animation = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 
    0.5f, Animation.RELATIVE_TO_SELF, 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 --;
   }
  });
 }
}

布局文件:



 

 

  
  
  
  
  
  
  
 

 

 
  
  
  

 
 

 

  
 


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家继续关注考高分网的更多精彩内容!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/162548.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号