Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Download the library and replace ResideMenu class with given below code. #159

Open
shiv2810 opened this issue Jul 17, 2019 · 0 comments
Open

Comments

@shiv2810
Copy link

Download the library and replace ResideMenu class with given below code.

package com.special.ResideMenu;

import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Build;
import android.util.DisplayMetrics;
import android.view.;
import android.view.animation.AnimationUtils;
import android.widget.
;

import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.AnimatorSet;
import com.nineoldandroids.animation.ObjectAnimator;
import com.nineoldandroids.view.ViewHelper;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

/**

  • User: special

  • Date: 13-12-10

  • Time: 下午10:44

  • Mail: [email protected]
    */
    public class ResideMenu extends FrameLayout {

    public static final int DIRECTION_LEFT = 0;
    public static final int DIRECTION_RIGHT = 1;
    private static final int PRESSED_MOVE_HORIZONTAL = 2;
    private static final int PRESSED_DOWN = 3;
    private static final int PRESSED_DONE = 4;
    private static final int PRESSED_MOVE_VERTICAL = 5;

    private ImageView imageViewShadow;
    private ImageView imageViewBackground;
    private LinearLayout layoutLeftMenu;
    private LinearLayout layoutRightMenu;
    private View scrollViewLeftMenu;
    private View scrollViewRightMenu;
    private View scrollViewMenu;
    private Context mContext;
    /**

    • Current attaching activity.
      /
      private Activity activity;
      /
      *
    • The DecorView of current activity.
      /
      private ViewGroup viewDecor;
      private TouchDisableView viewActivity;
      /
      *
    • The flag of menu opening status.
      /
      private boolean isOpened;
      private float shadowAdjustScaleX;
      private float shadowAdjustScaleY;
      /
      *
    • Views which need stop to intercept touch events.
      */
      private List ignoredViews;
      private List leftMenuItems;
      private List rightMenuItems;
      private DisplayMetrics displayMetrics = new DisplayMetrics();
      private OnMenuListener menuListener;
      private float lastRawX;
      private boolean isInIgnoredView = false;
      private int scaleDirection = DIRECTION_LEFT;
      private int pressedState = PRESSED_DOWN;
      private List disabledSwipeDirection = new ArrayList();
      // Valid scale factor is between 0.0f and 1.0f.
      private float mScaleValue = 0.5f;

    private boolean mUse3D;
    private static final int ROTATE_Y_ANGLE = 10;

    public ResideMenu(Context context) {
    super(context);
    mContext=context;
    initViews(context, -1, -1);

    }

    /**

    • This constructor provides you to create menus with your own custom
    • layouts, but if you use custom menu then do not call addMenuItem because
    • it will not be able to find default views
      */
      public ResideMenu(Context context, int customLeftMenuId,
      int customRightMenuId) {
      super(context);
      mContext=context;
      initViews(context, customLeftMenuId, customRightMenuId);
      }

    private void initViews(Context context, int customLeftMenuId,
    int customRightMenuId) {
    LayoutInflater inflater = (LayoutInflater) context
    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    inflater.inflate(R.layout.residemenu_custom, this);

     if (customLeftMenuId >= 0) {
         scrollViewLeftMenu = inflater.inflate(customLeftMenuId, this, false);
     } else {
         scrollViewLeftMenu = inflater.inflate(
                 R.layout.residemenu_custom_left_scrollview, this, false);
         layoutLeftMenu = (LinearLayout) scrollViewLeftMenu.findViewById(R.id.layout_left_menu);
     }
    
     if (customRightMenuId >= 0) {
         scrollViewRightMenu = inflater.inflate(customRightMenuId, this, false);
     } else {
         scrollViewRightMenu = inflater.inflate(
                 R.layout.residemenu_custom_right_scrollview, this, false);
         layoutRightMenu = (LinearLayout) scrollViewRightMenu.findViewById(R.id.layout_right_menu);
     }
    
     imageViewShadow = (ImageView) findViewById(R.id.iv_shadow);
     imageViewBackground = (ImageView) findViewById(R.id.iv_background);
    
     RelativeLayout menuHolder = (RelativeLayout) findViewById(R.id.sv_menu_holder);
     menuHolder.addView(scrollViewLeftMenu);
     menuHolder.addView(scrollViewRightMenu);
    

    }

    /**

    • Returns left menu view so you can findViews and do whatever you want with
      */
      public View getLeftMenuView() {
      return scrollViewLeftMenu;
      }

    /**

    • Returns right menu view so you can findViews and do whatever you want with
      */
      public View getRightMenuView() {
      return scrollViewRightMenu;
      }

    @OverRide
    protected boolean fitSystemWindows(Rect insets) {
    // Applies the content insets to the view's padding, consuming that
    // content (modifying the insets to be 0),
    // and returning true. This behavior is off by default and can be
    // enabled through setFitsSystemWindows(boolean)
    // in api14+ devices.

     Point appUsableSize = getAppUsableScreenSize(mContext);
     Point realScreenSize = getRealScreenSize(mContext);
    
     boolean hasBackKey=false;
     // navigation bar at the bottom
     if (appUsableSize.y < realScreenSize.y) {
         hasBackKey=true;
     }
    
    
    
    
     // This is added to fix soft navigationBar's overlapping to content above LOLLIPOP
     int bottomPadding = viewActivity.getPaddingBottom() + insets.bottom;
    
     if (hasBackKey ) {//there's a navigation bar
         bottomPadding += getNavigationBarHeight();
     }
    
     this.setPadding(viewActivity.getPaddingLeft() + insets.left,
             viewActivity.getPaddingTop() + insets.top,
             viewActivity.getPaddingRight() + insets.right,
             bottomPadding);
     insets.left = insets.top = insets.right = insets.bottom = 0;
     return true;
    

    }

    public static Point getAppUsableScreenSize(Context context) {
    WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Display display = windowManager.getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);
    return size;
    }

    public static Point getRealScreenSize(Context context) {
    WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Display display = windowManager.getDefaultDisplay();
    Point size = new Point();

     if (Build.VERSION.SDK_INT >= 17) {
         display.getRealSize(size);
     } else if (Build.VERSION.SDK_INT >= 14) {
         try {
             size.x = (Integer) Display.class.getMethod("getRawWidth").invoke(display);
             size.y = (Integer) Display.class.getMethod("getRawHeight").invoke(display);
         } catch (IllegalAccessException e) {} catch (InvocationTargetException e) {} catch (NoSuchMethodException e) {}
     }
    
     return size;
    

    }

    private int getNavigationBarHeight() {
    Resources resources = getResources();
    int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
    if (resourceId > 0) {
    return resources.getDimensionPixelSize(resourceId);
    }
    return 0;
    }

    /**

    • Set up the activity;
    • @param activity
      */
      public void attachToActivity(Activity activity) {
      initValue(activity);
      setShadowAdjustScaleXByOrientation();
      viewDecor.addView(this, 0);
      }

    private void initValue(Activity activity) {
    this.activity = activity;
    leftMenuItems = new ArrayList();
    rightMenuItems = new ArrayList();
    ignoredViews = new ArrayList();
    viewDecor = (ViewGroup) activity.getWindow().getDecorView();
    viewActivity = new TouchDisableView(this.activity);

     View mContent = viewDecor.getChildAt(0);
     viewDecor.removeViewAt(0);
     viewActivity.setContent(mContent);
     addView(viewActivity);
    
     ViewGroup parent = (ViewGroup) scrollViewLeftMenu.getParent();
     parent.removeView(scrollViewLeftMenu);
     parent.removeView(scrollViewRightMenu);
    

    }

    private void setShadowAdjustScaleXByOrientation() {
    int orientation = getResources().getConfiguration().orientation;
    if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
    shadowAdjustScaleX = 0.034f;
    shadowAdjustScaleY = 0.12f;
    } else if (orientation == Configuration.ORIENTATION_PORTRAIT) {
    shadowAdjustScaleX = 0.06f;
    shadowAdjustScaleY = 0.07f;
    }
    }

    /**

    • Set the background image of menu;
    • @param imageResource
      */
      public void setBackground(int imageResource) {
      imageViewBackground.setImageResource(imageResource);
      }

    /**

    • The visibility of the shadow under the activity;
    • @param isVisible
      */
      public void setShadowVisible(boolean isVisible) {
      if (isVisible)
      imageViewShadow.setBackgroundResource(R.drawable.shadow);
      else
      imageViewShadow.setBackgroundResource(0);
      }

    /**

    • Add a single item to the left menu;
    • WARNING: It will be removed from v2.0.
    • @param menuItem
      */
      @deprecated
      public void addMenuItem(ResideMenuItem menuItem) {
      this.leftMenuItems.add(menuItem);
      layoutLeftMenu.addView(menuItem);
      }

    /**

    • Add a single items;
    • @param menuItem
    • @param direction
      */
      public void addMenuItem(ResideMenuItem menuItem, int direction) {
      if (direction == DIRECTION_LEFT) {
      this.leftMenuItems.add(menuItem);
      layoutLeftMenu.addView(menuItem);
      } else {
      this.rightMenuItems.add(menuItem);
      layoutRightMenu.addView(menuItem);
      }
      }

    /**

    • WARNING: It will be removed from v2.0.
    • @param menuItems
      */
      @deprecated
      public void setMenuItems(List menuItems) {
      this.leftMenuItems = menuItems;
      rebuildMenu();
      }

    /**

    • Set menu items by a array;
    • @param menuItems
    • @param direction
      */
      public void setMenuItems(List menuItems, int direction) {
      if (direction == DIRECTION_LEFT)
      this.leftMenuItems = menuItems;
      else
      this.rightMenuItems = menuItems;
      rebuildMenu();
      }

    private void rebuildMenu() {
    if (layoutLeftMenu != null) {
    layoutLeftMenu.removeAllViews();
    for (ResideMenuItem leftMenuItem : leftMenuItems)
    layoutLeftMenu.addView(leftMenuItem);
    }

     if (layoutRightMenu != null) {
         layoutRightMenu.removeAllViews();
         for (ResideMenuItem rightMenuItem : rightMenuItems)
             layoutRightMenu.addView(rightMenuItem);
     }
    

    }

    /**

    • WARNING: It will be removed from v2.0.
    • @return
      */
      @deprecated
      public List getMenuItems() {
      return leftMenuItems;
      }

    /**

    • Return instances of menu items;
    • @return
      */
      public List getMenuItems(int direction) {
      if (direction == DIRECTION_LEFT)
      return leftMenuItems;
      else
      return rightMenuItems;
      }

    /**

    • If you need to do something on closing or opening menu,
    • set a listener here.
    • @return
      */
      public void setMenuListener(OnMenuListener menuListener) {
      this.menuListener = menuListener;
      }

    public OnMenuListener getMenuListener() {
    return menuListener;
    }

    /**

    • Show the menu;
      */
      public void openMenu(int direction) {

      setScaleDirection(direction);

      isOpened = true;
      AnimatorSet scaleDown_activity = buildScaleDownAnimation(viewActivity, mScaleValue, mScaleValue);
      AnimatorSet scaleDown_shadow = buildScaleDownAnimation(imageViewShadow,
      mScaleValue + shadowAdjustScaleX, mScaleValue + shadowAdjustScaleY);
      AnimatorSet alpha_menu = buildMenuAnimation(scrollViewMenu, 1.0f);
      scaleDown_shadow.addListener(animationListener);
      scaleDown_activity.playTogether(scaleDown_shadow);
      scaleDown_activity.playTogether(alpha_menu);
      scaleDown_activity.start();
      }

    /**

    • Close the menu;
      */
      public void closeMenu() {

      isOpened = false;
      AnimatorSet scaleUp_activity = buildScaleUpAnimation(viewActivity, 1.0f, 1.0f);
      AnimatorSet scaleUp_shadow = buildScaleUpAnimation(imageViewShadow, 1.0f, 1.0f);
      AnimatorSet alpha_menu = buildMenuAnimation(scrollViewMenu, 0.0f);
      scaleUp_activity.addListener(animationListener);
      scaleUp_activity.playTogether(scaleUp_shadow);
      scaleUp_activity.playTogether(alpha_menu);
      scaleUp_activity.start();
      }

    @deprecated
    public void setDirectionDisable(int direction) {
    disabledSwipeDirection.add(direction);
    }

    public void setSwipeDirectionDisable(int direction) {
    disabledSwipeDirection.add(direction);
    }

    private boolean isInDisableDirection(int direction) {
    return disabledSwipeDirection.contains(direction);
    }

    private void setScaleDirection(int direction) {

     int screenWidth = getScreenWidth();
     float pivotX;
     float pivotY = getScreenHeight() * 0.5f;
    
     if (direction == DIRECTION_LEFT) {
         scrollViewMenu = scrollViewLeftMenu;
         pivotX = screenWidth * 1.5f;
     } else {
         scrollViewMenu = scrollViewRightMenu;
         pivotX = screenWidth * -0.5f;
     }
    
     ViewHelper.setPivotX(viewActivity, pivotX);
     ViewHelper.setPivotY(viewActivity, pivotY);
     ViewHelper.setPivotX(imageViewShadow, pivotX);
     ViewHelper.setPivotY(imageViewShadow, pivotY);
     scaleDirection = direction;
    

    }

    /**

    • return the flag of menu status;
    • @return
      */
      public boolean isOpened() {
      return isOpened;
      }

    private OnClickListener viewActivityOnClickListener = new OnClickListener() {
    @OverRide
    public void onClick(View view) {
    if (isOpened()) closeMenu();
    }
    };

    private Animator.AnimatorListener animationListener = new Animator.AnimatorListener() {
    @OverRide
    public void onAnimationStart(Animator animation) {
    if (isOpened()) {
    showScrollViewMenu(scrollViewMenu);
    if (menuListener != null)
    menuListener.openMenu();
    }
    }

     @Override
     public void onAnimationEnd(Animator animation) {
         // reset the view;
         if (isOpened()) {
             viewActivity.setTouchDisable(true);
             viewActivity.setOnClickListener(viewActivityOnClickListener);
         } else {
             viewActivity.setTouchDisable(false);
             viewActivity.setOnClickListener(null);
             hideScrollViewMenu(scrollViewLeftMenu);
             hideScrollViewMenu(scrollViewRightMenu);
             if (menuListener != null)
                 menuListener.closeMenu();
         }
     }
    
     @Override
     public void onAnimationCancel(Animator animation) {
    
     }
    
     @Override
     public void onAnimationRepeat(Animator animation) {
    
     }
    

    };

    /**

    • A helper method to build scale down animation;

    • @param target

    • @param targetScaleX

    • @param targetScaleY

    • @return
      */
      private AnimatorSet buildScaleDownAnimation(View target, float targetScaleX, float targetScaleY) {

      AnimatorSet scaleDown = new AnimatorSet();
      scaleDown.playTogether(
      ObjectAnimator.ofFloat(target, "scaleX", targetScaleX),
      ObjectAnimator.ofFloat(target, "scaleY", targetScaleY)
      );

      if (mUse3D) {
      int angle = scaleDirection == DIRECTION_LEFT ? -ROTATE_Y_ANGLE : ROTATE_Y_ANGLE;
      scaleDown.playTogether(ObjectAnimator.ofFloat(target, "rotationY", angle));
      }

      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)
      );

      if (mUse3D) {
      scaleUp.playTogether(ObjectAnimator.ofFloat(target, "rotationY", 0));
      }

      scaleUp.setDuration(250);
      return scaleUp;
      }

    private AnimatorSet buildMenuAnimation(View target, float alpha) {

     AnimatorSet alphaAnimation = new AnimatorSet();
     alphaAnimation.playTogether(
             ObjectAnimator.ofFloat(target, "alpha", alpha)
     );
    
     alphaAnimation.setDuration(250);
     return alphaAnimation;
    

    }

    /**

    • If there were some view you don't want reside menu
    • to intercept their touch event, you could add it to
    • ignored views.
    • @param v
      */
      public void addIgnoredView(View v) {
      ignoredViews.add(v);
      }

    /**

    • Remove a view from ignored views;
    • @param v
      */
      public void removeIgnoredView(View v) {
      ignoredViews.remove(v);
      }

    /**

    • Clear the ignored view list;
      */
      public void clearIgnoredViewList() {
      ignoredViews.clear();
      }

    /**

    • If the motion event 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;
      }

    private void setScaleDirectionByRawX(float currentRawX) {
    if (currentRawX < lastRawX)
    setScaleDirection(DIRECTION_RIGHT);
    else
    setScaleDirection(DIRECTION_LEFT);
    }

    private float getTargetScale(float currentRawX) {
    float scaleFloatX = ((currentRawX - lastRawX) / getScreenWidth()) * 0.75f;
    scaleFloatX = scaleDirection == DIRECTION_RIGHT ? -scaleFloatX : scaleFloatX;

     float targetScale = ViewHelper.getScaleX(viewActivity) - scaleFloatX;
     targetScale = targetScale > 1.0f ? 1.0f : targetScale;
     targetScale = targetScale < 0.5f ? 0.5f : targetScale;
     return targetScale;
    

    }

    private float lastActionDownX, lastActionDownY;

    @OverRide
    public boolean dispatchTouchEvent(MotionEvent ev) {
    float currentActivityScaleX = ViewHelper.getScaleX(viewActivity);
    if (currentActivityScaleX == 1.0f)
    setScaleDirectionByRawX(ev.getRawX());

     switch (ev.getAction()) {
         case MotionEvent.ACTION_DOWN:
             lastActionDownX = ev.getX();
             lastActionDownY = ev.getY();
             isInIgnoredView = isInIgnoredView(ev) && !isOpened();
             pressedState = PRESSED_DOWN;
             break;
    
         case MotionEvent.ACTION_MOVE:
             if (isInIgnoredView || isInDisableDirection(scaleDirection))
                 break;
    
             if (pressedState != PRESSED_DOWN &&
                     pressedState != PRESSED_MOVE_HORIZONTAL)
                 break;
    
             int xOffset = (int) (ev.getX() - lastActionDownX);
             int yOffset = (int) (ev.getY() - lastActionDownY);
    
             if (pressedState == PRESSED_DOWN) {
                 if (yOffset > 25 || yOffset < -25) {
                     pressedState = PRESSED_MOVE_VERTICAL;
                     break;
                 }
                 if (xOffset < -50 || xOffset > 50) {
                     pressedState = PRESSED_MOVE_HORIZONTAL;
                     ev.setAction(MotionEvent.ACTION_CANCEL);
                 }
             } else if (pressedState == PRESSED_MOVE_HORIZONTAL) {
                 if (currentActivityScaleX < 0.95)
                     showScrollViewMenu(scrollViewMenu);
    
                 float targetScale = getTargetScale(ev.getRawX());
                 if (mUse3D) {
                     float angle = scaleDirection == DIRECTION_LEFT ? -ROTATE_Y_ANGLE : ROTATE_Y_ANGLE;
                         //int angle = scaleDirection == DIRECTION_LEFT ? -ROTATE_Y_ANGLE : ROTATE_Y_ANGLE;
                     angle *= (1 - targetScale) * 2;
                     ViewHelper.setRotationY(viewActivity, angle);
    
                     ViewHelper.setScaleX(imageViewShadow, targetScale - shadowAdjustScaleX);
                     ViewHelper.setScaleY(imageViewShadow, targetScale - shadowAdjustScaleY);
                 } else {
                     ViewHelper.setScaleX(imageViewShadow, targetScale + shadowAdjustScaleX);
                     ViewHelper.setScaleY(imageViewShadow, targetScale + shadowAdjustScaleY);
                 }
                 ViewHelper.setScaleX(viewActivity, targetScale);
                 ViewHelper.setScaleY(viewActivity, targetScale);
                 ViewHelper.setAlpha(scrollViewMenu, (1 - targetScale) * 2.0f);
    
                 lastRawX = ev.getRawX();
                 return true;
             }
    
             break;
    
         case MotionEvent.ACTION_UP:
    
             if (isInIgnoredView) break;
             if (pressedState != PRESSED_MOVE_HORIZONTAL) break;
    
             pressedState = PRESSED_DONE;
             if (isOpened()) {
                 if (currentActivityScaleX > 0.56f)
                     closeMenu();
                 else
                     openMenu(scaleDirection);
             } else {
                 if (currentActivityScaleX < 0.94f) {
                     openMenu(scaleDirection);
                 } else {
                     closeMenu();
                 }
             }
    
             break;
    
     }
     lastRawX = ev.getRawX();
     return super.dispatchTouchEvent(ev);
    

    }

    public int getScreenHeight() {
    activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
    return displayMetrics.heightPixels;
    }

    public int getScreenWidth() {
    activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
    return displayMetrics.widthPixels;
    }

    public void setScaleValue(float scaleValue) {
    this.mScaleValue = scaleValue;
    }

    public void setUse3D(boolean use3D) {
    mUse3D = use3D;
    }

    public interface OnMenuListener {

     /**
      * This method will be called at the finished time of opening menu animations.
      */
     public void openMenu();
    
     /**
      * This method will be called at the finished time of closing menu animations.
      */
     public void closeMenu();
    

    }

    private void showScrollViewMenu(View scrollViewMenu) {
    if (scrollViewMenu != null && scrollViewMenu.getParent() == null) {
    addView(scrollViewMenu);
    }
    }

    private void hideScrollViewMenu(View scrollViewMenu) {
    if (scrollViewMenu != null && scrollViewMenu.getParent() != null) {
    removeView(scrollViewMenu);
    }
    }
    }

Originally posted by @niteshsirohi1 in #127 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant