首页 > 系统 > Android > 正文

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

2019-12-12 04:34:46
字体:
来源:转载
供稿:网友

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

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

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

首先创建一个android工程命名为PathTest.目录结构如下图:

第二步:在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> 

运行点击效果如下:

图1:默认是在右下方这里menuResIds定义了五个菜单              


图2:点击红色菜单,菜单收回.

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

tutor:position="left_bottom" 

效果如下:

图3:自定义在左下角,六个菜单。

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

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表