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

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

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

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

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



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

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources>
  3. <declare-styleable name="PathMenuView">
  4. <attr name="position">
  5. <enum name="left_top" value="0"></enum>
  6. <enum name="right_top" value="1"></enum>
  7. <enum name="right_bottom" value="2"></enum>
  8. <enum name="left_bottom" value="3"></enum>
  9. </attr>
  10. </declare-styleable>
  11. </resources>
<?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菜单控件,代码如下:

  1. package com.tutor.path;
  2. import android.content.Context;
  3. import android.content.res.TypedArray;
  4. import android.util.AttributeSet;
  5. import android.view.Gravity;
  6. import android.view.View;
  7. import android.view.ViewGroup;
  8. import android.view.animation.Animation;
  9. import android.view.animation.AnticipateInterpolator;
  10. import android.view.animation.OvershootInterpolator;
  11. import android.view.animation.TranslateAnimation;
  12. import android.widget.FrameLayout;
  13. import android.widget.ImageView;
  14. /**
  15. * @author frankiewei.
  16. * 超级仿path菜单
  17. * position定义菜单的位置,目前支持:左上;右上;右下;左下四个方向。
  18. * menuResIds定义出现的菜单的资源ID
  19. */
  20. public class PathMenuView extends FrameLayout {
  21. private static final int LEFT_TOP = 0;
  22. private static final int RIGHT_TOP = 1;
  23. private static final int RIGHT_BOTTOM = 2;
  24. private static final int LEFT_BOTTOM = 3;
  25. /**
  26. * 默认的位置是在右下角.
  27. */
  28. private int position = 3;
  29. /**
  30. * 那个圆形菜单.
  31. */
  32. private ImageView mHome;
  33. /**
  34. * 上下文.
  35. */
  36. private Context mContext;
  37. /**
  38. * 设备的宽度.
  39. */
  40. private int mWIDTH = 0;
  41. /**
  42. * 设备的高度.
  43. */
  44. private int mHEIGHT = 0;
  45. /**
  46. * 设备的density.
  47. */
  48. private float mDensity;
  49. /**
  50. * 菜单是否显示.
  51. */
  52. private boolean bMenuShow;
  53. private static int xOffset = 15;
  54. private static int yOffset = -13;
  55. /**
  56. * 菜单的资源个数.
  57. */
  58. private int[] menuResIds = {R.drawable.composer_camera,R.drawable.composer_music,
  59. R.drawable.composer_sleep,R.drawable.composer_music,R.drawable.composer_place};
  60. public PathMenuView(Context context){
  61. super(context);
  62. setupViews();
  63. }
  64. public PathMenuView(Context context, AttributeSet attrs) {
  65. super(context, attrs);
  66. TypedArray a = context.obtainStyledAttributes(attrs,
  67. R.styleable.PathMenuView);
  68. position = a.getInt(R.styleable.PathMenuView_position,3);
  69. a.recycle();
  70. setupViews();
  71. }
  72. private void setupViews(){
  73. mContext = getContext();
  74. mHEIGHT = mContext.getResources().getDisplayMetrics().heightPixels;
  75. mWIDTH = mContext.getResources().getDisplayMetrics().widthPixels;
  76. mDensity = mContext.getResources().getDisplayMetrics().density;
  77. xOffset = (int) (10.667 * mDensity);
  78. yOffset = (int) (8.667 * mDensity);
  79. mHome = new ImageView(mContext);
  80. mHome.setImageResource(R.drawable.composer_button);
  81. mHome.setOnClickListener(listener);
  82. addView(mHome);
  83. LayoutParams mHomeparams = (FrameLayout.LayoutParams)mHome.getLayoutParams();
  84. mHomeparams.width = LayoutParams.WRAP_CONTENT;
  85. mHomeparams.height = LayoutParams.WRAP_CONTENT;
  86. switch (position) {
  87. case LEFT_TOP:
  88. mHomeparams.gravity = Gravity.LEFT | Gravity.TOP;
  89. for (int i = 0; i < menuResIds.length; i++) {
  90. int width_padding = mWIDTH / ((menuResIds.length - 1) * 2);
  91. int height_padding = mHEIGHT / ((menuResIds.length - 1) * 2);
  92. ImageView imageView = new ImageView(mContext);
  93. imageView.setImageResource(menuResIds[i]);
  94. addView(imageView);
  95. LayoutParams params = (FrameLayout.LayoutParams) imageView
  96. .getLayoutParams();
  97. params.width = LayoutParams.WRAP_CONTENT;
  98. params.height = LayoutParams.WRAP_CONTENT;
  99. params.leftMargin = mWIDTH / 2
  100. - ((menuResIds.length - i - 1) * width_padding);
  101. params.topMargin = mHEIGHT / 2 - i * height_padding;
  102. params.gravity = Gravity.LEFT | Gravity.TOP;
  103. imageView.setLayoutParams(params);
  104. }
  105. break;
  106. case RIGHT_TOP:
  107. mHomeparams.gravity = Gravity.RIGHT | Gravity.TOP;
  108. for (int i = 0; i < menuResIds.length; i++) {
  109. int width_padding = mWIDTH / ((menuResIds.length - 1) * 2);
  110. int height_padding = mHEIGHT / ((menuResIds.length - 1) * 2);
  111. ImageView imageView = new ImageView(mContext);
  112. imageView.setImageResource(menuResIds[i]);
  113. addView(imageView);
  114. LayoutParams params = (FrameLayout.LayoutParams) imageView
  115. .getLayoutParams();
  116. params.width = LayoutParams.WRAP_CONTENT;
  117. params.height = LayoutParams.WRAP_CONTENT;
  118. params.rightMargin = mWIDTH / 2
  119. - ((menuResIds.length - i - 1) * width_padding);
  120. params.topMargin = mHEIGHT / 2 - i * height_padding;
  121. params.gravity = Gravity.RIGHT | Gravity.TOP;
  122. imageView.setLayoutParams(params);
  123. }
  124. break;
  125. case RIGHT_BOTTOM:
  126. mHomeparams.gravity = Gravity.RIGHT | Gravity.BOTTOM;
  127. for (int i = 0; i < menuResIds.length; i++) {
  128. int width_padding = mWIDTH / ((menuResIds.length - 1) * 2);
  129. int height_padding = mHEIGHT / ((menuResIds.length - 1) * 2);
  130. ImageView imageView = new ImageView(mContext);
  131. imageView.setImageResource(menuResIds[i]);
  132. addView(imageView);
  133. LayoutParams params = (FrameLayout.LayoutParams) imageView
  134. .getLayoutParams();
  135. params.width = LayoutParams.WRAP_CONTENT;
  136. params.height = LayoutParams.WRAP_CONTENT;
  137. params.rightMargin = mWIDTH / 2
  138. - ((menuResIds.length - i - 1) * width_padding);
  139. params.bottomMargin = mHEIGHT / 2 - i * height_padding;
  140. params.gravity = Gravity.RIGHT | Gravity.BOTTOM;
  141. imageView.setLayoutParams(params);
  142. }
  143. break;
  144. case LEFT_BOTTOM:
  145. mHomeparams.gravity = Gravity.LEFT | Gravity.BOTTOM;
  146. for(int i = 0; i < menuResIds.length; i++){
  147. int width_padding = mWIDTH / ((menuResIds.length - 1) * 2);
  148. int height_padding = mHEIGHT / ((menuResIds.length -1) * 2);
  149. ImageView imageView = new ImageView(mContext);
  150. imageView.setImageResource(menuResIds[i]);
  151. addView(imageView);
  152. LayoutParams params = (FrameLayout.LayoutParams)imageView.getLayoutParams();
  153. params.width = LayoutParams.WRAP_CONTENT;
  154. params.height = LayoutParams.WRAP_CONTENT;
  155. params.leftMargin = mWIDTH / 2 - ((menuResIds.length - i - 1) * width_padding);
  156. params.bottomMargin = mHEIGHT / 2 - i * height_padding;
  157. params.gravity = Gravity.LEFT | Gravity.BOTTOM;
  158. imageView.setLayoutParams(params);
  159. }
  160. break;
  161. default:
  162. break;
  163. }
  164. mHome.setLayoutParams(mHomeparams);
  165. }
  166. private OnClickListener listener = new OnClickListener() {
  167. public void onClick(View v) {
  168. if (!bMenuShow) {
  169. startAnimationIn(PathMenuView.this, 300);
  170. } else {
  171. startAnimationOut(PathMenuView.this, 300);
  172. }
  173. bMenuShow = !bMenuShow;
  174. }
  175. };
  176. /**
  177. * 菜单隐藏动画.
  178. *
  179. * @param group
  180. * @param duration
  181. */
  182. private void startAnimationIn(ViewGroup group, int duration) {
  183. for (int i = 1; i < group.getChildCount(); i++) {
  184. ImageView imageview = (ImageView) group.getChildAt(i);
  185. imageview.setVisibility(0);
  186. MarginLayoutParams mlp = (MarginLayoutParams) imageview
  187. .getLayoutParams();
  188. Animation animation = null;
  189. switch (position) {
  190. case LEFT_TOP:
  191. animation = new TranslateAnimation(0F,-mlp.leftMargin+xOffset,0F,-mlp.topMargin + yOffset);
  192. break;
  193. case RIGHT_TOP:
  194. animation = new TranslateAnimation(mlp.rightMargin - xOffset,0F,-mlp.topMargin + yOffset,0F);
  195. break;
  196. case LEFT_BOTTOM:
  197. animation = new TranslateAnimation(0F, -mlp.leftMargin+ xOffset, 0F, -yOffset + mlp.bottomMargin);
  198. break;
  199. case RIGHT_BOTTOM:
  200. animation = new TranslateAnimation(mlp.rightMargin-xOffset,0F,-yOffset + mlp.bottomMargin, 0F);
  201. break;
  202. default:
  203. break;
  204. }
  205. animation.setFillAfter(true);
  206. animation.setDuration(duration);
  207. animation.setStartOffset((i * 100) / (-1 + group.getChildCount()));
  208. animation.setInterpolator(new OvershootInterpolator(2F));
  209. imageview.startAnimation(animation);
  210. }
  211. }
  212. /**
  213. * 菜单显示动画.
  214. *
  215. * @param group
  216. * @param duration
  217. */
  218. private void startAnimationOut(ViewGroup group,int duration){
  219. for (int i = 1; i < group.getChildCount(); i++) {
  220. final ImageView imageview = (ImageView) group
  221. .getChildAt(i);
  222. MarginLayoutParams mlp = (MarginLayoutParams) imageview.getLayoutParams();
  223. Animation animation = null;
  224. switch (position) {
  225. case LEFT_TOP:
  226. animation = new TranslateAnimation(-mlp.leftMargin+xOffset,0F,-mlp.topMargin + yOffset,0F);
  227. break;
  228. case RIGHT_TOP:
  229. animation = new TranslateAnimation(0F,mlp.rightMargin - xOffset,0F,-mlp.topMargin + yOffset);
  230. break;
  231. case LEFT_BOTTOM:
  232. animation = new TranslateAnimation(-mlp.leftMargin+xOffset,0F, -yOffset + mlp.bottomMargin,0F);
  233. break;
  234. case RIGHT_BOTTOM:
  235. animation = new TranslateAnimation(0F,mlp.rightMargin-xOffset, 0F,-yOffset + mlp.bottomMargin);
  236. break;
  237. default:
  238. break;
  239. }
  240. animation.setFillAfter(true);animation.setDuration(duration);
  241. animation.setStartOffset(((group.getChildCount()-i) * 100)
  242. / (-1 + group.getChildCount()));
  243. animation.setInterpolator(new AnticipateInterpolator(2F));
  244. imageview.startAnimation(animation);
  245. }
  246. }
  247. }
package com.tutor.path;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnticipateInterpolator;
import android.view.animation.OvershootInterpolator;
import android.view.animation.TranslateAnimation;
import android.widget.FrameLayout;
import android.widget.ImageView;


/**
 * @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 = {R.drawable.composer_camera,R.drawable.composer_music,
			R.drawable.composer_sleep,R.drawable.composer_music,R.drawable.composer_place};
	

	public PathMenuView(Context context){
		super(context);
		setupViews();
	}
	
	public PathMenuView(Context context, AttributeSet attrs) {
		super(context, attrs);
		TypedArray a = context.obtainStyledAttributes(attrs,  
                R.styleable.PathMenuView);
		
		position = a.getInt(R.styleable.PathMenuView_position,3);
		
		a.recycle();
		setupViews();
	}
	
	private void setupViews(){
		mContext = getContext();

		mHEIGHT = mContext.getResources().getDisplayMetrics().heightPixels;
		mWIDTH = mContext.getResources().getDisplayMetrics().widthPixels;
		mDensity = mContext.getResources().getDisplayMetrics().density;
		
		xOffset = (int) (10.667 * mDensity);
		yOffset = (int) (8.667 * mDensity);
		
		mHome = new ImageView(mContext);
		
		mHome.setImageResource(R.drawable.composer_button);
		mHome.setOnClickListener(listener);
		
		addView(mHome);
		
		LayoutParams mHomeparams = (FrameLayout.LayoutParams)mHome.getLayoutParams();
		mHomeparams.width = LayoutParams.WRAP_CONTENT;
		mHomeparams.height = LayoutParams.WRAP_CONTENT;
		
		switch (position) {
		case LEFT_TOP:
			mHomeparams.gravity = Gravity.LEFT | Gravity.TOP;
			for (int i = 0; i < menuResIds.length; i++) {

				int width_padding = mWIDTH / ((menuResIds.length - 1) * 2);
				int height_padding = mHEIGHT / ((menuResIds.length - 1) * 2);

				ImageView imageView = new ImageView(mContext);
				imageView.setImageResource(menuResIds[i]);
				addView(imageView);
				LayoutParams params = (FrameLayout.LayoutParams) imageView
						.getLayoutParams();
				params.width = LayoutParams.WRAP_CONTENT;
				params.height = LayoutParams.WRAP_CONTENT;
				params.leftMargin = mWIDTH / 2
						- ((menuResIds.length - i - 1) * width_padding);
				params.topMargin = mHEIGHT / 2 - i * height_padding;
				params.gravity = Gravity.LEFT | Gravity.TOP;
				imageView.setLayoutParams(params);

			}
			
			break;
		case RIGHT_TOP:
			mHomeparams.gravity = Gravity.RIGHT | Gravity.TOP;
			for (int i = 0; i < menuResIds.length; i++) {

				int width_padding = mWIDTH / ((menuResIds.length - 1) * 2);
				int height_padding = mHEIGHT / ((menuResIds.length - 1) * 2);

				ImageView imageView = new ImageView(mContext);
				imageView.setImageResource(menuResIds[i]);
				addView(imageView);
				LayoutParams params = (FrameLayout.LayoutParams) imageView
						.getLayoutParams();
				params.width = LayoutParams.WRAP_CONTENT;
				params.height = LayoutParams.WRAP_CONTENT;
				params.rightMargin = mWIDTH / 2
						- ((menuResIds.length - i - 1) * width_padding);
				params.topMargin = mHEIGHT / 2 - i * height_padding;
				params.gravity = Gravity.RIGHT | Gravity.TOP;
				imageView.setLayoutParams(params);

			}
			break;
		case RIGHT_BOTTOM:
			mHomeparams.gravity = Gravity.RIGHT | Gravity.BOTTOM;
			for (int i = 0; i < menuResIds.length; i++) {

				int width_padding = mWIDTH / ((menuResIds.length - 1) * 2);
				int height_padding = mHEIGHT / ((menuResIds.length - 1) * 2);

				ImageView imageView = new ImageView(mContext);
				imageView.setImageResource(menuResIds[i]);
				addView(imageView);
				LayoutParams params = (FrameLayout.LayoutParams) imageView
						.getLayoutParams();
				params.width = LayoutParams.WRAP_CONTENT;
				params.height = LayoutParams.WRAP_CONTENT;
				params.rightMargin = mWIDTH / 2
						- ((menuResIds.length - i - 1) * width_padding);
				params.bottomMargin = mHEIGHT / 2 - i * height_padding;
				params.gravity = Gravity.RIGHT | Gravity.BOTTOM;
				imageView.setLayoutParams(params);

			}
			break;
		case LEFT_BOTTOM:
			mHomeparams.gravity = Gravity.LEFT | Gravity.BOTTOM;
			for(int i = 0; i < menuResIds.length; i++){
				
				int width_padding = mWIDTH / ((menuResIds.length - 1) * 2);
				int height_padding = mHEIGHT / ((menuResIds.length -1) * 2);
				
			    ImageView imageView = new ImageView(mContext);
				imageView.setImageResource(menuResIds[i]);
				addView(imageView);
				LayoutParams params = (FrameLayout.LayoutParams)imageView.getLayoutParams();
				params.width = LayoutParams.WRAP_CONTENT;
				params.height = LayoutParams.WRAP_CONTENT;			
				params.leftMargin = mWIDTH / 2 - ((menuResIds.length - i - 1) * width_padding);
				params.bottomMargin = mHEIGHT / 2 - i * height_padding;
				params.gravity = Gravity.LEFT | Gravity.BOTTOM;
				imageView.setLayoutParams(params);						
			}
			break;
		default:
				break;
		}	
		
		mHome.setLayoutParams(mHomeparams);		
	}
	
	private OnClickListener listener = new OnClickListener() {
		
		public void onClick(View v) {
			if (!bMenuShow) {
				startAnimationIn(PathMenuView.this, 300);
			} else {
				startAnimationOut(PathMenuView.this, 300);
			}
			bMenuShow = !bMenuShow;
		}
	};
	
	
	/**
	 * 菜单隐藏动画.
	 * 
	 * @param group
	 * @param duration
	 */
	private void startAnimationIn(ViewGroup group, int duration) {
		for (int i = 1; i < group.getChildCount(); i++) {
			ImageView imageview = (ImageView) group.getChildAt(i);
			imageview.setVisibility(0);
			MarginLayoutParams mlp = (MarginLayoutParams) imageview
					.getLayoutParams();
			
			
			Animation animation = null;
			
			
			switch (position) {
			case LEFT_TOP:
				animation = new TranslateAnimation(0F,-mlp.leftMargin+xOffset,0F,-mlp.topMargin + yOffset);
				break;
			case RIGHT_TOP:
				animation = new TranslateAnimation(mlp.rightMargin - xOffset,0F,-mlp.topMargin + yOffset,0F);
				break;			
			case LEFT_BOTTOM:
				animation = new TranslateAnimation(0F, -mlp.leftMargin+ xOffset, 0F, -yOffset + mlp.bottomMargin);
				break;
				
			case RIGHT_BOTTOM:
				animation = new TranslateAnimation(mlp.rightMargin-xOffset,0F,-yOffset + mlp.bottomMargin, 0F);
				break;
			default:
				break;
			}

			animation.setFillAfter(true);
			animation.setDuration(duration);
			animation.setStartOffset((i * 100) / (-1 + group.getChildCount()));
			animation.setInterpolator(new OvershootInterpolator(2F));
			imageview.startAnimation(animation);

		}
	}
	
	/**
	 * 菜单显示动画.
	 * 
	 * @param group
	 * @param duration
	 */
	private void startAnimationOut(ViewGroup group,int duration){
		for (int i = 1; i < group.getChildCount(); i++) {
			final ImageView imageview = (ImageView) group
					.getChildAt(i);
			MarginLayoutParams mlp = (MarginLayoutParams) imageview.getLayoutParams();
			
			Animation animation = null;
			
			switch (position) {
			case LEFT_TOP:
				animation = new TranslateAnimation(-mlp.leftMargin+xOffset,0F,-mlp.topMargin + yOffset,0F);
				break;
			case RIGHT_TOP:
				animation = new TranslateAnimation(0F,mlp.rightMargin - xOffset,0F,-mlp.topMargin + yOffset);
				break;

			case LEFT_BOTTOM:
				animation = new TranslateAnimation(-mlp.leftMargin+xOffset,0F, -yOffset + mlp.bottomMargin,0F);
				break;

			case RIGHT_BOTTOM:
				animation = new TranslateAnimation(0F,mlp.rightMargin-xOffset, 0F,-yOffset + mlp.bottomMargin);
				break;
			default:
				break;
			}
			
			animation.setFillAfter(true);animation.setDuration(duration);
			animation.setStartOffset(((group.getChildCount()-i) * 100)
					/ (-1 + group.getChildCount()));
			animation.setInterpolator(new AnticipateInterpolator(2F));
			imageview.startAnimation(animation);
		}
	}

}

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

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

  1. package com.tutor.path;
  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. public class PathTestActivity extends Activity {
  5. @Override
  6. public void onCreate(Bundle savedInstanceState) {
  7. super.onCreate(savedInstanceState);
  8. setContentView(R.layout.main);
  9. }
  10. }
package com.tutor.path;

import android.app.Activity;
import android.os.Bundle;

public class PathTestActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);   
    }
}

main.xml代码如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tutor="http://schemas.android.com/apk/res/com.tutor.path"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent"
  6. android:orientation="vertical" >
  7. <com.tutor.path.PathMenuView
  8. android:id="@+id/text"
  9. android:layout_width="fill_parent"
  10. android:layout_height="fill_parent"
  11. tutor:position="right_bottom"
  12. />
  13. </LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tutor="http://schemas.android.com/apk/res/com.tutor.path"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <com.tutor.path.PathMenuView
        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.

  1. tutor:position="left_bottom"
tutor:position="left_bottom"

效果如下:

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

好了,今天就讲到这里了,菜单的圆弧不是很圆哈,凑合着学习,我也来无耻下,如果想要源代码的,可以去我的http://www.yqma.net注册一个用户,并且提一个问题,或者回答一个问题,我会把源代码发到你的邮箱里!谢谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值