SpecialCyCi/AndroidResideMenu

Cant access custom side menu layouts

Opened this issue · 3 comments

Hello ,
I like this library. Great work..

I need to add custom left side layout. But i cant access it.

resideMenu = new ResideMenu(activity, R.layout.menu_left, -1); = shows error

Seems only one constructor is available now..
resideMenu = new ResideMenu(activity); = This works

Please help to sort this out.

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: specialcyci@gmail.com
    */
    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);
    }
    }
    }

public class CustomResideMenuItem extends ResideMenuItem {
    public CustomResideMenuItem_logo(Context context) {
        super(context);
        removeAllViews();
        LayoutInflater.from(getContext()).inflate(R.layout.item_residemenu_image, this);
    }
}

Unable to add. Can you help me in that?