国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android實現(xiàn)自定義的衛(wèi)星式菜單(弧形菜單)詳解

2019-12-12 05:33:38
字體:
供稿:網(wǎng)友

一、前言

Android 實現(xiàn)衛(wèi)星式菜單也叫弧形菜單,主要要做的工作如下:

1.動畫的處理

2.自定義ViewGroup來實現(xiàn)衛(wèi)星式菜單View

(1)自定義屬性

       a. 在attrs.xml中定義屬性

       b. 在布局中使用自定義屬性

       c. 在自定義View中讀取布局文件中的自定義屬性

(2)onMeasure 測量 child 即測量主按鈕以及菜單項

(3)onLayout 布局 child 即布局主按鈕以及菜單項

(4)設(shè)置主按鈕的選擇動畫

       a.為菜單項menuItem添加平移動畫和旋轉(zhuǎn)動畫

       b.實現(xiàn)菜單項menuItem的點擊動畫

衛(wèi)星式菜單效果截圖:

    

二、實現(xiàn)

上面介紹了原理和效果圖,下面來看看衛(wèi)星菜單類的實現(xiàn):

1.布局文件的實現(xiàn)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:xcskin="http://schemas.android.com/apk/res/com.xc.xcskin" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" >  <com.xc.xcskin.view.XCArcMenuView  android:id="@+id/arcmenu"  android:layout_width="150dp"  android:layout_height="150dp"  android:layout_alignParentBottom="true"  android:layout_alignParentLeft="true"  xcskin:position="left_bottom"  xcskin:radius="120dp" >  <RelativeLayout   android:layout_width="wrap_content"   android:layout_height="wrap_content"   android:background="@drawable/composer_button" >   <ImageView    android:id="@+id/id_button"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_centerInParent="true"    android:src="@drawable/composer_icn_plus" />  </RelativeLayout>  <ImageView    android:id="@+id/id_button"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:src="@drawable/composer_camera"    android:tag="camera" />  <ImageView    android:id="@+id/id_button"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:src="@drawable/composer_music"    android:tag="music" />  <ImageView    android:id="@+id/id_button"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:src="@drawable/composer_place"    android:tag="place" />  <ImageView    android:id="@+id/id_button"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:src="@drawable/composer_sleep"    android:tag="sleep" />  <ImageView    android:id="@+id/id_button"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:src="@drawable/composer_thought"    android:tag="thought" />  <ImageView    android:id="@+id/id_button"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:src="@drawable/composer_with"    android:tag="with" /> </com.xc.xcskin.view.XCArcMenuView>  <com.xc.xcskin.view.XCArcMenuView  android:id="@+id/arcmenu2"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_alignParentBottom="true"  android:layout_alignParentRight="true"  xcskin:position="right_bottom"  xcskin:radius="150dp" >  <RelativeLayout   android:layout_width="wrap_content"   android:layout_height="wrap_content"   android:background="@drawable/composer_button" >   <ImageView    android:id="@+id/id_button"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_centerInParent="true"    android:src="@drawable/composer_icn_plus" />  </RelativeLayout>  <ImageView    android:id="@+id/id_button"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:src="@drawable/composer_camera"    android:tag="camera" />  <ImageView    android:id="@+id/id_button"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:src="@drawable/composer_music"    android:tag="music" />  <ImageView    android:id="@+id/id_button"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:src="@drawable/composer_place"    android:tag="place" />  <ImageView    android:id="@+id/id_button"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:src="@drawable/composer_sleep"    android:tag="sleep" />  <ImageView    android:id="@+id/id_button"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:src="@drawable/composer_thought"    android:tag="thought" />  <ImageView    android:id="@+id/id_button"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:src="@drawable/composer_with"    android:tag="with" /> </com.xc.xcskin.view.XCArcMenuView>  </RelativeLayout>

2.衛(wèi)星菜單類的實現(xiàn)

package com.xc.xcskin.view;import com.xc.xcskin.R;import android.content.Context;import android.content.res.TypedArray;import android.util.AttributeSet;import android.util.Log;import android.util.TypedValue;import android.view.View;import android.view.View.OnClickListener;import android.view.ViewGroup;import android.view.animation.AlphaAnimation;import android.view.animation.Animation;import android.view.animation.Animation.AnimationListener;import android.view.animation.AnimationSet;import android.view.animation.RotateAnimation;import android.view.animation.ScaleAnimation;import android.view.animation.TranslateAnimation;/** * 衛(wèi)星式菜單View * @author caizhiming * */public class XCArcMenuView extends ViewGroup implements OnClickListener{ private static final int POS_LEFT_TOP = 0; private static final int POS_LEFT_BOTTOM = 1; private static final int POS_RIGHT_TOP = 2; private static final int POS_RIGHT_BOTTOM = 3;  private Position mPosition = Position.RIGHT_BOTTOM; private int mRadius; private Status mStatus = Status.CLOSE; //主菜的單按鈕 private View mCButton; private OnMenuItemClickListener mOnMenuItemClickListener; /**  * 菜單的狀態(tài)枚舉類  * @author caizhiming  *  */ public enum Status{  OPEN,CLOSE } /**  * 菜單的位置枚舉類  * @author caizhiming  *  */ public enum Position{  LEFT_TOP,LEFT_BOTTOM,  RIGHT_TOP,RIGHT_BOTTOM } /**  * 點擊子菜單項的回調(diào)接口  * @author caizhiming  *  */ public interface OnMenuItemClickListener {  void onClick(View view, int pos); } public void setOnMenuItemClickListener(   OnMenuItemClickListener onMenuItemClickListener) {  this.mOnMenuItemClickListener = onMenuItemClickListener; }  public XCArcMenuView(Context context) {  this(context, null);  // TODO Auto-generated constructor stub } public XCArcMenuView(Context context, AttributeSet attrs) {  this(context, attrs, 0);  // TODO Auto-generated constructor stub } public XCArcMenuView(Context context, AttributeSet attrs, int defStyle) {  super(context, attrs, defStyle);  // TODO Auto-generated constructor stub  //獲取自定義屬性  TypedArray a = context.getTheme().obtainStyledAttributes(attrs,    R.styleable.XCArcMenuView,defStyle,0);  int pos = a.getInt(R.styleable.XCArcMenuView_position , POS_RIGHT_BOTTOM);  switch (pos) {   case POS_LEFT_TOP:    mPosition = Position.LEFT_TOP;    break;   case POS_LEFT_BOTTOM:    mPosition = Position.LEFT_BOTTOM;    break;   case POS_RIGHT_TOP:    mPosition = Position.RIGHT_TOP;    break;   case POS_RIGHT_BOTTOM:    mPosition = Position.RIGHT_BOTTOM;    break;  }  mRadius = (int) a.getDimension(R.styleable.XCArcMenuView_radius,     (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 150,     getResources().getDisplayMetrics()));  Log.v("czm", "mPosition = " + mPosition + ",mRadius = "+mRadius);  a.recycle(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  // TODO Auto-generated method stub  int count = getChildCount();  for(int i = 0; i < count; i ++){   measureChild(getChildAt(i), widthMeasureSpec, heightMeasureSpec);  }  super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) {  // TODO Auto-generated method stub  if(changed){   layoutCButton();   layoutMenuItems();  } }  /**  * 布局主菜單項  */ private void layoutCButton() {  // TODO Auto-generated method stub  mCButton = getChildAt(0);  mCButton.setOnClickListener(this);  int l = 0;  int t = 0;  int width = mCButton.getMeasuredWidth();  int height = mCButton.getMeasuredHeight();  switch (mPosition) {   case LEFT_TOP:    l = 0;    t = 0;    break;    case LEFT_BOTTOM:    l = 0;    t = getMeasuredHeight() - height;    break;   case RIGHT_TOP:    l = getMeasuredWidth() - width;    t = 0;    break;   case RIGHT_BOTTOM:    l = getMeasuredWidth() - width;    t = getMeasuredHeight() - height;    break;   default:    break;  }  mCButton.layout(l, t, l + width, t + height); } /**  * 布局菜單項  */ private void layoutMenuItems() {  // TODO Auto-generated method stub  int count = getChildCount();  for (int i = 0; i < count - 1; i++) {   View child = getChildAt(i + 1);   int l = (int) (mRadius * Math.sin(Math.PI / 2 / (count - 2) * i));   int t = (int) (mRadius * Math.cos(Math.PI / 2 / (count - 2) * i));   int width = child.getMeasuredWidth();   int height = child.getMeasuredHeight();   // 如果菜單位置在底部 左下,右下   if (mPosition == Position.LEFT_BOTTOM || mPosition == Position.RIGHT_BOTTOM) {    t = getMeasuredHeight() - height - t;   }   // 右上,右下   if (mPosition == Position.RIGHT_TOP || mPosition == Position.RIGHT_BOTTOM) {    l = getMeasuredWidth() - width - l;   }   child.layout(l, t, l + width, t + height);   child.setVisibility(View.GONE);  } } @Override public void onClick(View v) {  // TODO Auto-generated method stub  mCButton = findViewById(R.id.id_button);  rotateCButton(v,0,360,300);  toggleMenu(300); } /**  * 切換菜單  */ public void toggleMenu(int duration) {  // TODO Auto-generated method stub  // 為menuItem添加平移動畫和旋轉(zhuǎn)動畫  int count = getChildCount();  for (int i = 0; i < count - 1; i++)  {   final View childView = getChildAt(i + 1);   childView.setVisibility(View.VISIBLE);   // end 0 , 0   // start   int cl = (int) (mRadius * Math.sin(Math.PI / 2 / (count - 2) * i));   int ct = (int) (mRadius * Math.cos(Math.PI / 2 / (count - 2) * i));   int xflag = 1;   int yflag = 1;   if (mPosition == Position.LEFT_TOP     || mPosition == Position.LEFT_BOTTOM)   {    xflag = -1;   }   if (mPosition == Position.LEFT_TOP     || mPosition == Position.RIGHT_TOP)   {    yflag = -1;   }   AnimationSet animset = new AnimationSet(true);   Animation tranAnim = null;   // to open   if (mStatus == Status.CLOSE)   {    tranAnim = new TranslateAnimation(xflag * cl, 0, yflag * ct, 0);    childView.setClickable(true);    childView.setFocusable(true);   } else   // to close   {    tranAnim = new TranslateAnimation(0, xflag * cl, 0, yflag * ct);    childView.setClickable(false);    childView.setFocusable(false);   }   tranAnim.setFillAfter(true);   tranAnim.setDuration(duration);   tranAnim.setStartOffset((i * 100) / count);   tranAnim.setAnimationListener(new AnimationListener()   {    @Override    public void onAnimationStart(Animation animation)    {    }    @Override    public void onAnimationRepeat(Animation animation)    {    }    @Override    public void onAnimationEnd(Animation animation)    {     if (mStatus == Status.CLOSE)     {      childView.setVisibility(View.GONE);     }    }   });   // 旋轉(zhuǎn)動畫   RotateAnimation rotateAnim = new RotateAnimation(0, 720,     Animation.RELATIVE_TO_SELF, 0.5f,     Animation.RELATIVE_TO_SELF, 0.5f);   rotateAnim.setDuration(duration);   rotateAnim.setFillAfter(true);   animset.addAnimation(rotateAnim);   animset.addAnimation(tranAnim);   childView.startAnimation(animset);   final int pos = i + 1;   childView.setOnClickListener(new OnClickListener()   {    @Override    public void onClick(View v)    {     if (mOnMenuItemClickListener != null)      mOnMenuItemClickListener.onClick(childView, pos);     menuItemAnim(pos - 1);     changeStatus();    }   });  }  // 切換菜單狀態(tài)  changeStatus();   } /**  * 選擇主菜單按鈕  *   */ private void rotateCButton(View v, float start, float end, int duration) {  // TODO Auto-generated method stub  RotateAnimation anim = new RotateAnimation(start, end,    Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,    0.5f);  anim.setDuration(duration);  anim.setFillAfter(true);  v.startAnimation(anim); } /**  * 添加menuItem的點擊動畫  *   */ private void menuItemAnim(int pos) {  for (int i = 0; i < getChildCount() - 1; i++)  {   View childView = getChildAt(i + 1);   if (i == pos)   {    childView.startAnimation(scaleBigAnim(300));   } else   {    childView.startAnimation(scaleSmallAnim(300));   }   childView.setClickable(false);   childView.setFocusable(false);  } } /**  * 為當前點擊的Item設(shè)置變小和透明度增大的動畫  * @param duration  * @return  */ private Animation scaleSmallAnim(int duration) {  AnimationSet animationSet = new AnimationSet(true);  ScaleAnimation scaleAnim = new ScaleAnimation(1.0f, 0.0f, 1.0f, 0.0f,    Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,    0.5f);  AlphaAnimation alphaAnim = new AlphaAnimation(1f, 0.0f);  animationSet.addAnimation(scaleAnim);  animationSet.addAnimation(alphaAnim);  animationSet.setDuration(duration);  animationSet.setFillAfter(true);  return animationSet; } /**  * 為當前點擊的Item設(shè)置變大和透明度降低的動畫  */ private Animation scaleBigAnim(int duration) {  AnimationSet animationSet = new AnimationSet(true);  ScaleAnimation scaleAnim = new ScaleAnimation(1.0f, 4.0f, 1.0f, 4.0f,    Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,    0.5f);  AlphaAnimation alphaAnim = new AlphaAnimation(1f, 0.0f);  animationSet.addAnimation(scaleAnim);  animationSet.addAnimation(alphaAnim);  animationSet.setDuration(duration);  animationSet.setFillAfter(true);  return animationSet; } /**  * 切換菜單狀態(tài)  */ private void changeStatus() {  mStatus = (mStatus == Status.CLOSE ? Status.OPEN    : Status.CLOSE); } /**  * 是否處于展開狀態(tài)  * @return  */ public boolean isOpen() {  return mStatus == Status.OPEN; }  }

3.使用衛(wèi)星式菜單類

package com.xc.xcskin;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.Toast;import com.xc.xcskin.view.XCArcMenuView;import com.xc.xcskin.view.XCArcMenuView.OnMenuItemClickListener;import com.xc.xcskin.view.XCGuaguakaView;import com.xc.xcskin.view.XCGuaguakaView.OnCompleteListener;/** * 使用并測試自定義衛(wèi)星式菜單View * @author caizhiming * */public class XCArcMenuViewDemo extends Activity{ @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.xc_arcmenu_view_demo);  XCArcMenuView view = (XCArcMenuView) findViewById(R.id.arcmenu);  view.setOnMenuItemClickListener(new OnMenuItemClickListener() {      @Override   public void onClick(View view, int pos) {    // TODO Auto-generated method stub    String tag = (String) view.getTag();    Toast.makeText(XCArcMenuViewDemo.this, tag, Toast.LENGTH_SHORT).show();   }  }); }}

三、總結(jié)

Android實現(xiàn)自定義的衛(wèi)星式菜單(弧形菜單)的內(nèi)容到這就基本結(jié)束了,感興趣的朋友們可以動手操作起來,只有自己實踐了才能更深的理解,希望本文對大家能有所幫助。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 南投县| 绥江县| 涞源县| 大竹县| 长丰县| 五大连池市| 鹿泉市| 凭祥市| 驻马店市| 洛宁县| 广水市| 平谷区| 邢台市| 榆林市| 张北县| 休宁县| 沅陵县| 庆安县| 杨浦区| 梁平县| 凉城县| 周至县| 许昌县| 二手房| 威远县| 南部县| 荔波县| 乌拉特中旗| 日喀则市| 巴南区| 青铜峡市| 金湖县| 八宿县| 九寨沟县| 太原市| 都兰县| 绿春县| 潍坊市| 彭州市| 天全县| 若尔盖县|