欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android高手进阶教程(二十六)之---Android超仿Path菜单的功能实现!

程序员文章站 2024-03-01 14:51:28
hi~大家好,出来创业快3个月了,一切还不错,前一段时间用了业余时间搞了个问答类网站yqma.想做中国的*,哈哈,只是yy下,希望大家多多支持!...

hi~大家好,出来创业快3个月了,一切还不错,前一段时间用了业余时间搞了个问答类网站yqma.想做中国的*,哈哈,只是yy下,希望大家多多支持!

好了,今天给大家分享的是path菜单的简单实现,可以支持自定义方向(左上,右上,右下,左下),并且可以自定义菜单的个数,难点就是菜单的摆放位置(动态设置margin),还有动画的实现,其实动画只是简单用了个translateanimation,n个菜单一起移动的时候感觉很cool~

这里也用到了自定义标签,这里不懂的童鞋可以看我 android高手进阶教程(四)之----android 中自定义属性(attr.xml,typedarray)的使用! 这篇文章.好了废话不多说了,

首先创建一个android工程命名为pathtest.目录结构如下图:Android高手进阶教程(二十六)之---Android超仿Path菜单的功能实现!

第二步:在values文件夹下新建一个attrs.xml文件,代码如下:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
  <declare-styleable name="pathmenuview">  
    <attr name="position">  
      <enum name="left_top" value="0"></enum> 
      <enum name="right_top" value="1"></enum> 
      <enum name="right_bottom" value="2"></enum> 
      <enum name="left_bottom" value="3"></enum> 
    </attr> 
  </declare-styleable>  
</resources> 

第三步:新建一个pathmenuview.java这个就是我们自定义的path菜单控件,代码如下:

package com.tutor.path; 
 
import androidcontentcontext; 
import androidcontentrestypedarray; 
import androidutilattributeset; 
import androidviewgravity; 
import androidviewview; 
import androidviewviewgroup; 
import androidviewanimationanimation; 
import androidviewanimationanticipateinterpolator; 
import androidviewanimationovershootinterpolator; 
import androidviewanimationtranslateanimation; 
import androidwidgetframelayout; 
import androidwidgetimageview; 
 
 
/** 
 * @author frankiewei 
 * 超级仿path菜单 
 * position定义菜单的位置,目前支持:左上;右上;右下;左下四个方向。 
 * menuresids定义出现的菜单的资源id 
 */ 
public class pathmenuview extends framelayout { 
   
  private static final int left_top = 0; 
   
  private static final int right_top = 1; 
   
  private static final int right_bottom = 2; 
   
  private static final int left_bottom = 3; 
   
   
  /** 
   * 默认的位置是在右下角 
   */ 
  private int position = 3; 
   
  /** 
   * 那个圆形菜单 
   */ 
  private imageview mhome; 
   
  /** 
   * 上下文 
   */ 
  private context mcontext; 
   
   
  /** 
   * 设备的宽度 
   */ 
  private int mwidth = 0; 
   
  /** 
   * 设备的高度 
   */ 
  private int mheight = 0; 
   
  /** 
   * 设备的density 
   */ 
  private float mdensity; 
   
  /** 
   * 菜单是否显示 
   */ 
  private boolean bmenushow; 
   
  private static int xoffset   = 15; 
  private static int yoffset   = -13; 
   
  /** 
   * 菜单的资源个数 
   */ 
  private int[] menuresids = {rdrawablecomposer_camera,rdrawablecomposer_music, 
      rdrawablecomposer_sleep,rdrawablecomposer_music,rdrawablecomposer_place}; 
   
 
  public pathmenuview(context context){ 
    super(context); 
    setupviews(); 
  } 
   
  public pathmenuview(context context, attributeset attrs) { 
    super(context, attrs); 
    typedarray a = contextobtainstyledattributes(attrs,  
        rstyleablepathmenuview); 
     
    position = agetint(rstyleablepathmenuview_position,3); 
     
    arecycle(); 
    setupviews(); 
  } 
   
  private void setupviews(){ 
    mcontext = getcontext(); 
 
    mheight = mcontextgetresources()getdisplaymetrics()heightpixels; 
    mwidth = mcontextgetresources()getdisplaymetrics()widthpixels; 
    mdensity = mcontextgetresources()getdisplaymetrics()density; 
     
    xoffset = (int) (667 * mdensity); 
    yoffset = (int) (667 * mdensity); 
     
    mhome = new imageview(mcontext); 
     
    mhomesetimageresource(rdrawablecomposer_button); 
    mhomesetonclicklistener(listener); 
     
    addview(mhome); 
     
    layoutparams mhomeparams = (framelayoutlayoutparams)mhomegetlayoutparams(); 
    mhomeparamswidth = layoutparamswrap_content; 
    mhomeparamsheight = layoutparamswrap_content; 
     
    switch (position) { 
    case left_top: 
      mhomeparamsgravity = gravityleft | gravitytop; 
      for (int i = 0; i < menuresidslength; i++) { 
 
        int width_padding = mwidth / ((menuresidslength - 1) * 2); 
        int height_padding = mheight / ((menuresidslength - 1) * 2); 
 
        imageview imageview = new imageview(mcontext); 
        imageviewsetimageresource(menuresids[i]); 
        addview(imageview); 
        layoutparams params = (framelayoutlayoutparams) imageview 
            getlayoutparams(); 
        paramswidth = layoutparamswrap_content; 
        paramsheight = layoutparamswrap_content; 
        paramsleftmargin = mwidth / 2 
            - ((menuresidslength - i - 1) * width_padding); 
        paramstopmargin = mheight / 2 - i * height_padding; 
        paramsgravity = gravityleft | gravitytop; 
        imageviewsetlayoutparams(params); 
 
      } 
       
      break; 
    case right_top: 
      mhomeparamsgravity = gravityright | gravitytop; 
      for (int i = 0; i < menuresidslength; i++) { 
 
        int width_padding = mwidth / ((menuresidslength - 1) * 2); 
        int height_padding = mheight / ((menuresidslength - 1) * 2); 
 
        imageview imageview = new imageview(mcontext); 
        imageviewsetimageresource(menuresids[i]); 
        addview(imageview); 
        layoutparams params = (framelayoutlayoutparams) imageview 
            getlayoutparams(); 
        paramswidth = layoutparamswrap_content; 
        paramsheight = layoutparamswrap_content; 
        paramsrightmargin = mwidth / 2 
            - ((menuresidslength - i - 1) * width_padding); 
        paramstopmargin = mheight / 2 - i * height_padding; 
        paramsgravity = gravityright | gravitytop; 
        imageviewsetlayoutparams(params); 
 
      } 
      break; 
    case right_bottom: 
      mhomeparamsgravity = gravityright | gravitybottom; 
      for (int i = 0; i < menuresidslength; i++) { 
 
        int width_padding = mwidth / ((menuresidslength - 1) * 2); 
        int height_padding = mheight / ((menuresidslength - 1) * 2); 
 
        imageview imageview = new imageview(mcontext); 
        imageviewsetimageresource(menuresids[i]); 
        addview(imageview); 
        layoutparams params = (framelayoutlayoutparams) imageview 
            getlayoutparams(); 
        paramswidth = layoutparamswrap_content; 
        paramsheight = layoutparamswrap_content; 
        paramsrightmargin = mwidth / 2 
            - ((menuresidslength - i - 1) * width_padding); 
        paramsbottommargin = mheight / 2 - i * height_padding; 
        paramsgravity = gravityright | gravitybottom; 
        imageviewsetlayoutparams(params); 
 
      } 
      break; 
    case left_bottom: 
      mhomeparamsgravity = gravityleft | gravitybottom; 
      for(int i = 0; i < menuresidslength; i++){ 
         
        int width_padding = mwidth / ((menuresidslength - 1) * 2); 
        int height_padding = mheight / ((menuresidslength -1) * 2); 
         
        imageview imageview = new imageview(mcontext); 
        imageviewsetimageresource(menuresids[i]); 
        addview(imageview); 
        layoutparams params = (framelayoutlayoutparams)imageviewgetlayoutparams(); 
        paramswidth = layoutparamswrap_content; 
        paramsheight = layoutparamswrap_content;      
        paramsleftmargin = mwidth / 2 - ((menuresidslength - i - 1) * width_padding); 
        paramsbottommargin = mheight / 2 - i * height_padding; 
        paramsgravity = gravityleft | gravitybottom; 
        imageviewsetlayoutparams(params);            
      } 
      break; 
    default: 
        break; 
    }   
     
    mhomesetlayoutparams(mhomeparams);    
  } 
   
  private onclicklistener listener = new onclicklistener() { 
     
    public void onclick(view v) { 
      if (!bmenushow) { 
        startanimationin(pathmenuviewthis, 300); 
      } else { 
        startanimationout(pathmenuviewthis, 300); 
      } 
      bmenushow = !bmenushow; 
    } 
  }; 
   
   
  /** 
   * 菜单隐藏动画 
   * 
   * @param group 
   * @param duration 
   */ 
  private void startanimationin(viewgroup group, int duration) { 
    for (int i = 1; i < groupgetchildcount(); i++) { 
      imageview imageview = (imageview) groupgetchildat(i); 
      imageviewsetvisibility(0); 
      marginlayoutparams mlp = (marginlayoutparams) imageview 
          getlayoutparams(); 
       
       
      animation animation = null; 
       
       
      switch (position) { 
      case left_top: 
        animation = new translateanimation(0f,-mlpleftmargin+xoffset,0f,-mlptopmargin + yoffset); 
        break; 
      case right_top: 
        animation = new translateanimation(mlprightmargin - xoffset,0f,-mlptopmargin + yoffset,0f); 
        break;      
      case left_bottom: 
        animation = new translateanimation(0f, -mlpleftmargin+ xoffset, 0f, -yoffset + mlpbottommargin); 
        break; 
         
      case right_bottom: 
        animation = new translateanimation(mlprightmargin-xoffset,0f,-yoffset + mlpbottommargin, 0f); 
        break; 
      default: 
        break; 
      } 
 
      animationsetfillafter(true); 
      animationsetduration(duration); 
      animationsetstartoffset((i * 100) / (-1 + groupgetchildcount())); 
      animationsetinterpolator(new overshootinterpolator(2f)); 
      imageviewstartanimation(animation); 
 
    } 
  } 
   
  /** 
   * 菜单显示动画 
   * 
   * @param group 
   * @param duration 
   */ 
  private void startanimationout(viewgroup group,int duration){ 
    for (int i = 1; i < groupgetchildcount(); i++) { 
      final imageview imageview = (imageview) group 
          getchildat(i); 
      marginlayoutparams mlp = (marginlayoutparams) imageviewgetlayoutparams(); 
       
      animation animation = null; 
       
      switch (position) { 
      case left_top: 
        animation = new translateanimation(-mlpleftmargin+xoffset,0f,-mlptopmargin + yoffset,0f); 
        break; 
      case right_top: 
        animation = new translateanimation(0f,mlprightmargin - xoffset,0f,-mlptopmargin + yoffset); 
        break; 
 
      case left_bottom: 
        animation = new translateanimation(-mlpleftmargin+xoffset,0f, -yoffset + mlpbottommargin,0f); 
        break; 
 
      case right_bottom: 
        animation = new translateanimation(0f,mlprightmargin-xoffset, 0f,-yoffset + mlpbottommargin); 
        break; 
      default: 
        break; 
      } 
       
      animationsetfillafter(true);animationsetduration(duration); 
      animationsetstartoffset(((groupgetchildcount()-i) * 100) 
          / (-1 + groupgetchildcount())); 
      animationsetinterpolator(new anticipateinterpolator(2f)); 
      imageviewstartanimation(animation); 
    } 
  } 
 
} 

第四步:pathtestactivity.java以及用到的布局文件main.xml代码如下:

pathtestactivity.java(基本没修改代码)代码如下:

package comtutorpath; 
 
import androidappactivity; 
import androidosbundle; 
 
public class pathtestactivity extends activity { 
 
  @override 
  public void oncreate(bundle savedinstancestate) { 
    superoncreate(savedinstancestate); 
    setcontentview(rlayoutmain);   
  } 
} 

main.xml代码如下:

<?xml version="0" encoding="utf-8"?> 
<linearlayout xmlns:android="http://schemasandroidcom/apk/res/android" 
  xmlns:tutor="http://schemasandroidcom/apk/res/comtutorpath" 
  android:layout_width="fill_parent" 
  android:layout_height="fill_parent" 
  android:orientation="vertical" > 
 
  <comtutorpathpathmenuview 
    android:id="@+id/text" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    tutor:position="right_bottom" 
     /> 
 
</linearlayout> 

运行点击效果如下:
Android高手进阶教程(二十六)之---Android超仿Path菜单的功能实现!
图1:默认是在右下方这里menuresids定义了五个菜单              

Android高手进阶教程(二十六)之---Android超仿Path菜单的功能实现!
图2:点击红色菜单,菜单收回.

下面我们修改main.xml的tutor属性为left_bottom,并且修改pathmenuview.java中的menuresids.

tutor:position="left_bottom" 

效果如下:
Android高手进阶教程(二十六)之---Android超仿Path菜单的功能实现!
图3:自定义在左下角,六个菜单。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。