Android高手進(jìn)階教程(二十六)之---Android超仿Path菜單的功能實現(xiàn)!
Hi~大家好,出來創(chuàng)業(yè)快3個月了,一切還不錯,前一段時間用了業(yè)余時間搞了個問答類網(wǎng)站YQMA.想做中國的stackoverflow,哈哈,只是YY下,希望大家多多支持!
好了,今天給大家分享的是Path菜單的簡單實現(xiàn),可以支持自定義方向(左上,右上,右下,左下),并且可以自定義菜單的個數(shù),難點就是菜單的擺放位置(動態(tài)設(shè)置margin),還有動畫的實現(xiàn),其實動畫只是簡單用了個TranslateAnimation,N個菜單一起移動的時候感覺很cool~
這里也用到了自定義標(biāo)簽,這里不懂的童鞋可以看我 Android高手進(jìn)階教程(四)之----Android 中自定義屬性(attr.xml,TypedArray)的使用! 這篇文章.好了廢話不多說了,
首先創(chuàng)建一個android工程命名為PathTest.目錄結(jié)構(gòu)如下圖:
第二步:在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定義出現(xiàn)的菜單的資源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; /** * 默認(rèn)的位置是在右下角 */ private int position = 3; /** * 那個圓形菜單 */ private ImageView mHome; /** * 上下文 */ private Context mContext; /** * 設(shè)備的寬度 */ private int mWIDTH = 0; /** * 設(shè)備的高度 */ private int mHEIGHT = 0; /** * 設(shè)備的density */ private float mDensity; /** * 菜單是否顯示 */ private boolean bMenuShow; private static int xOffset = 15; private static int yOffset = -13; /** * 菜單的資源個數(shù) */ 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:默認(rèn)是在右下方這里menuResIds定義了五個菜單
圖2:點擊紅色菜單,菜單收回.
下面我們修改main.xml的tutor屬性為left_bottom,并且修改PathMenuView.java中的menuResIds.
tutor:position="left_bottom"
效果如下:
圖3:自定義在左下角,六個菜單。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
退出Android程序時清除所有activity的實現(xiàn)方法
這篇文章主要介紹了退出Android程序時清除所有activity的實現(xiàn)方法,詳細(xì)分析了Android退出時清除activity的原理與實現(xiàn)技巧,需要的朋友可以參考下2016-04-04android H5本地緩存加載優(yōu)化的實戰(zhàn)
這篇文章主要介紹了android H5本地緩存加載優(yōu)化的實戰(zhàn),幫助大家更好的理解和學(xué)習(xí)使用Android,感興趣的朋友可以了解下2021-04-04Android實現(xiàn)Listview異步加載網(wǎng)絡(luò)圖片并動態(tài)更新的方法
這篇文章主要介紹了Android實現(xiàn)Listview異步加載網(wǎng)絡(luò)圖片并動態(tài)更新的方法,結(jié)合實例形式詳細(xì)分析了ListView異步加載數(shù)據(jù)的操作步驟與具體實現(xiàn)技巧,需要的朋友可以參考下2016-08-08Android 使用版本控制工具時添加忽略文件的方式(詳解)
下面小編就為大家?guī)硪黄狝ndroid 使用版本控制工具時添加忽略文件的方式(詳解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-01-01