效果图:
主activity:
public class MenuActivity extends Activity implements View.OnClickListener{ private ResideMenu resideMenu; private MenuActivity mContext; public static void startActivity(Context context) { Intent intent = new Intent(); intent.setClass(context,MenuActivity.class); context.startActivity(intent); } /** * Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.menu_activity); mContext = this; setUpViews(); setUpMenu(); } private void setUpMenu() { // attach to current activity; resideMenu = new ResideMenu(this); resideMenu.setBackground(R.drawable.menu_background); resideMenu.attachToActivity(this); resideMenu.setMenuListener(menuListener); // create menu items; String titles[] = { "Home", "Profile", "Calendar", "Settings" }; int icon[] = { R.drawable.icon_home, R.drawable.icon_profile, R.drawable.icon_calendar, R.drawable.icon_settings }; for (int i = 0; i < titles.length; i++){ ResideMenuItem item = new ResideMenuItem(this, icon[i], titles[i]); item.setOnClickListener(this); resideMenu.addMenuItem(item); } // add gesture operation's ignored views FrameLayout ignored_view = (FrameLayout) findViewById(R.id.ignored_view); resideMenu.addIgnoredView(ignored_view); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { return resideMenu.onInterceptTouchEvent(ev) || super.dispatchTouchEvent(ev); } private void setUpViews() { Button btn_open = (Button) findViewById(R.id.btn_open_menu); btn_open.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { resideMenu.openMenu(); } }); } @Override public void onClick(View view) { resideMenu.closeMenu(); } private ResideMenu.OnMenuListener menuListener = new ResideMenu.OnMenuListener() { @Override public void openMenu() { Toast.makeText(mContext, "Menu is opened!", Toast.LENGTH_SHORT).show(); } @Override public void closeMenu() { Toast.makeText(mContext, "Menu is closed!", Toast.LENGTH_SHORT).show(); } }; }
xml:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@android:color/white" android:orientation="vertical"> <LinearLayout android:id="@+id/layout_top" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:orientation="vertical"> <ImageView android:layout_width="match_parent" android:layout_height="3dp" android:background="#2ea3fe"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:padding="7dp" android:text="RESideMenu DEMO" android:textColor="#999999" android:textSize="24sp"/> <ImageView android:layout_width="match_parent" android:layout_height="5dp" android:background="#ebebeb"/> </LinearLayout> <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_above="@+id/ignored_view" android:layout_below="@+id/layout_top" android:gravity="center" android:orientation="vertical"> <ImageView android:id="@+id/imageView" android:layout_width="60dp" android:layout_height="120dp" android:layout_gravity="center" android:scaleType="fitCenter" android:class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="@drawable/gesture"/> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:clickable="false" android:padding="5dp" android:text=" 1. Swipe right to open menu" android:textColor="#ffacacac" android:textSize="17sp"/> <Button android:id="@+id/btn_open_menu" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginTop="4dp" android:background="@drawable/button_selector" android:padding="12dp" android:text="2. Click me to open menu" android:textColor="@android:color/white" android:textSize="17sp"/> </LinearLayout> <FrameLayout android:id="@+id/ignored_view" android:layout_width="fill_parent" android:layout_height="120dp" android:layout_alignParentBottom="true" android:layout_gravity="bottom" android:orientation="vertical" android:padding="10dp"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitXY" android:class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="@drawable/frame"/> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:gravity="center" android:padding="5dp" android:text="This is an ignored view,you can’t use gesture to operate menu here." android:textColor="#9a9a9a" android:textSize="17sp"/> </FrameLayout> </RelativeLayout>
ResideMenu代码:
public class ResideMenu extends FrameLayout implements GestureDetector.OnGestureListener{ private ImageView iv_shadow; private ImageView iv_background; private LinearLayout layout_menu; private ScrollView sv_menu; private AnimatorSet scaleUp_shadow; private AnimatorSet scaleUp_activity; private AnimatorSet scaleDown_activity; private AnimatorSet scaleDown_shadow; /** the activity that view attach to */ private Activity activity; /** the decorview of the activity */ private ViewGroup view_decor; /** the viewgroup of the activity */ private ViewGroup view_activity; /** the flag of menu open status */ private boolean isOpened; private GestureDetector gestureDetector; private float shadow_ScaleX; /** the view which don't want to intercept touch event */ private List<View> ignoredViews; private List<ResideMenuItem> menuItems; private DisplayMetrics displayMetrics = new DisplayMetrics(); private OnMenuListener menuListener; public ResideMenu(Context context) { super(context); initViews(context); } private void initViews(Context context){ LayoutInflater inflater=(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); inflater.inflate(R.layout.residemenu, this); sv_menu = (ScrollView) findViewById(R.id.sv_menu); iv_shadow = (ImageView) findViewById(R.id.iv_shadow); layout_menu = (LinearLayout) findViewById(R.id.layout_menu); iv_background = (ImageView) findViewById(R.id.iv_background); } /** * use the method to set up the activity which residemenu need to show; * * @param activity */ public void attachToActivity(Activity activity){ initValue(activity); setShadowScaleXByOrientation(); buildAnimationSet(); } private void initValue(Activity activity){ this.activity = activity; menuItems = new ArrayList<ResideMenuItem>(); gestureDetector = new GestureDetector(this); ignoredViews = new ArrayList<View>(); view_decor = (ViewGroup)activity.getWindow().getDecorView(); view_activity = (ViewGroup) view_decor.getChildAt(0); } private void setShadowScaleXByOrientation(){ int orientation = getResources().getConfiguration().orientation; if (orientation == Configuration.ORIENTATION_LANDSCAPE) { shadow_ScaleX = 0.5335f; } else if (orientation == Configuration.ORIENTATION_PORTRAIT) { shadow_ScaleX = 0.56f; } } /** * set the menu background picture; * * @param imageResrouce */ public void setBackground(int imageResrouce){ iv_background.setImageResource(imageResrouce); } /** * the visiblity of shadow under the activity view; * * @param isVisible */ public void setShadowVisible(boolean isVisible){ if (isVisible) iv_shadow.setImageResource(R.drawable.shadow); else iv_shadow.setImageBitmap(null); } /** * add a single items; * * @param menuItem */ public void addMenuItem(ResideMenuItem menuItem){ this.menuItems.add(menuItem); } /** * set the menu items by array list; * * @param menuItems */ public void setMenuItems(List<ResideMenuItem> menuItems){ this.menuItems = menuItems; } public List<ResideMenuItem> getMenuItems() { return menuItems; } /** * if you need to do something on the action of closing or opening * menu, set the listener here. * * @return */ public void setMenuListener(OnMenuListener menuListener) { this.menuListener = menuListener; } public OnMenuListener getMenuListener() { return menuListener; } /** * we need the call the method before the menu show, because the * padding of activity can't get at the moment of onCreateView(); */ private void setViewPadding(){ this.setPadding(view_activity.getPaddingLeft(), view_activity.getPaddingTop(), view_activity.getPaddingRight(), view_activity.getPaddingBottom()); } /** * show the reside menu; */ public void openMenu(){ if(!isOpened){ isOpened = true; showOpenMenuRelative(); } } private void removeMenuLayout(){ ViewGroup parent = ((ViewGroup) sv_menu.getParent()); parent.removeView(sv_menu); } /** * close the reslide menu; */ public void closeMenu(){ if(isOpened){ isOpened = false; scaleUp_activity.start(); } } /** * return the flag of menu status; * * @return */ public boolean isOpened() { return isOpened; } /** * call the method relative to open menu; */ private void showOpenMenuRelative(){ setViewPadding(); scaleDown_activity.start(); // remove self if has not remove if (getParent() != null) view_decor.removeView(this); if (sv_menu.getParent() != null) removeMenuLayout(); view_decor.addView(this, 0); view_decor.addView(sv_menu); } private Animator.AnimatorListener animationListener = new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { if (isOpened){ layout_menu.removeAllViews(); showMenuDelay(); if (menuListener != null) menuListener.openMenu(); } } @Override public void onAnimationEnd(Animator animation) { // reset the view; if(!isOpened){ view_decor.removeView(ResideMenu.this); view_decor.removeView(sv_menu); if (menuListener != null) menuListener.closeMenu(); } } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }; private void showMenuDelay(){ layout_menu.removeAllViews(); for(int i = 0; i < menuItems.size() ; i ++) showMenuItem(menuItems.get(i), i); } /** * * @param menuItem * @param menu_index the position of the menu; * @return */ private void showMenuItem(ResideMenuItem menuItem,int menu_index){ layout_menu.addView(menuItem); ViewHelper.setAlpha(menuItem, 0); AnimatorSet scaleUp = new AnimatorSet(); scaleUp.playTogether( ObjectAnimator.ofFloat(menuItem, "translationX", -100.f, 0.0f), ObjectAnimator.ofFloat(menuItem, "alpha", 0.0f, 1.0f) ); scaleUp.setInterpolator(AnimationUtils.loadInterpolator(activity, android.R.anim.anticipate_overshoot_interpolator)); // with animation; scaleUp.setStartDelay(50 * menu_index); scaleUp.setDuration(400).start(); } private void buildAnimationSet(){ scaleUp_activity = buildScaleUpAnimation(view_activity,1.0f,1.0f); scaleUp_shadow = buildScaleUpAnimation(iv_shadow,1.0f,1.0f); scaleDown_activity = buildScaleDownAnimation(view_activity,0.5f,0.5f); scaleDown_shadow = buildScaleDownAnimation(iv_shadow,shadow_ScaleX,0.59f); scaleUp_activity.addListener(animationListener); scaleUp_activity.playTogether(scaleUp_shadow); scaleDown_shadow.addListener(animationListener); scaleDown_activity.playTogether(scaleDown_shadow); } /** * a helper method to build scale down animation; * * @param target * @param targetScaleX * @param targetScaleY * @return */ private AnimatorSet buildScaleDownAnimation(View target,float targetScaleX,float targetScaleY){ // set the pivotX and pivotY to scale; int pivotX = (int) (getScreenWidth() * 1.5); int pivotY = (int) (getScreenHeight() * 0.5); ViewHelper.setPivotX(target, pivotX); ViewHelper.setPivotY(target, pivotY); AnimatorSet scaleDown = new AnimatorSet(); scaleDown.playTogether( ObjectAnimator.ofFloat(target, "scaleX", targetScaleX), ObjectAnimator.ofFloat(target, "scaleY", targetScaleY) ); scaleDown.setInterpolator(AnimationUtils.loadInterpolator(activity, android.R.anim.decelerate_interpolator)); scaleDown.setDuration(250); return scaleDown; } /** * a helper method to build scale up animation; * * @param target * @param targetScaleX * @param targetScaleY * @return */ private AnimatorSet buildScaleUpAnimation(View target,float targetScaleX,float targetScaleY){ AnimatorSet scaleUp = new AnimatorSet(); scaleUp.playTogether( ObjectAnimator.ofFloat(target, "scaleX", targetScaleX), ObjectAnimator.ofFloat(target, "scaleY", targetScaleY) ); scaleUp.setDuration(250); return scaleUp; } /** * if there ware some view you don't want reside menu * to intercept their touch event,you can use the method * to set. * * @param v */ public void addIgnoredView(View v){ ignoredViews.add(v); } /** * remove the view from ignored view list; * @param v */ public void removeIgnoredView(View v){ ignoredViews.remove(v); } /** * clear the ignored view list; */ public void clearIgnoredViewList(){ ignoredViews.clear(); } /** * if the motion evnent was relative to the view * which in ignored view list,return true; * * @param ev * @return */ private boolean isInIgnoredView(MotionEvent ev) { Rect rect = new Rect(); for (View v : ignoredViews) { v.getGlobalVisibleRect(rect); if (rect.contains((int) ev.getX(), (int) ev.getY())) return true; } return false; } //-------------------------------------------------------------------------- // // GestureListener // //-------------------------------------------------------------------------- @Override public boolean onTouchEvent(MotionEvent event) { return gestureDetector.onTouchEvent(event); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { gestureDetector.onTouchEvent(ev); return super.onInterceptTouchEvent(ev); } @Override public boolean onDown(MotionEvent motionEvent) { return false; } @Override public void onShowPress(MotionEvent motionEvent) { } @Override public boolean onSingleTapUp(MotionEvent motionEvent) { return false; } @Override public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent2, float v, float v2) { return false; } @Override public void onLongPress(MotionEvent motionEvent) { } @Override public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent2, float v, float v2) { if(isInIgnoredView(motionEvent) || isInIgnoredView(motionEvent2)) return false; int distanceX = (int) (motionEvent2.getX() - motionEvent.getX()); int distanceY = (int) (motionEvent2.getY() - motionEvent.getY()); int screenWidth = (int) getScreenWidth(); if(Math.abs(distanceY) > screenWidth * 0.3) return false; if(Math.abs(distanceX) > screenWidth * 0.3){ if(distanceX > 0 && !isOpened ){ // from left to right; openMenu(); }else if(distanceX < 0 && isOpened){ // from right th left; closeMenu(); } } return false; } public int getScreenHeight(){ activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); return displayMetrics.heightPixels; } public int getScreenWidth(){ activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); return displayMetrics.widthPixels; } public interface OnMenuListener{ /** * the method will call on the finished time of opening menu's animation. */ public void openMenu(); /** * the method will call on the finished time of closing menu's animation . */ public void closeMenu(); } }
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦