diff --git a/example/res/drawable/shadow_right.xml b/example/res/drawable/shadow_right.xml
new file mode 100644
index 000000000..df27938c1
--- /dev/null
+++ b/example/res/drawable/shadow_right.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/example/res/layout/test.xml b/example/res/layout/test.xml
new file mode 100644
index 000000000..33281374a
--- /dev/null
+++ b/example/res/layout/test.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/example/src/com/slidingmenu/example/BaseActivity.java b/example/src/com/slidingmenu/example/BaseActivity.java
index 7d23bf012..39741e857 100644
--- a/example/src/com/slidingmenu/example/BaseActivity.java
+++ b/example/src/com/slidingmenu/example/BaseActivity.java
@@ -12,6 +12,8 @@
import android.support.v4.app.ListFragment;
import android.support.v4.view.ViewPager;
import android.view.MenuItem;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
import com.slidingmenu.lib.SlidingMenu;
import com.slidingmenu.lib.app.SlidingFragmentActivity;
@@ -20,29 +22,22 @@ public class BaseActivity extends SlidingFragmentActivity {
private int mTitleRes;
protected ListFragment mFrag;
-
+
public BaseActivity(int titleRes) {
mTitleRes = titleRes;
}
-
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
-
- setTitle(mTitleRes);
- // set the Behind View
- setBehindContentView(R.layout.menu_frame);
- FragmentTransaction t = this.getSupportFragmentManager().beginTransaction();
- mFrag = new SampleListFragment();
- t.replace(R.id.menu_frame, mFrag);
- t.commit();
+ setTitle(mTitleRes);
+
+ addLeft();
// customize the SlidingMenu
SlidingMenu sm = getSlidingMenu();
sm.setShadowWidthRes(R.dimen.shadow_width);
- sm.setShadowDrawable(R.drawable.shadow);
- sm.setBehindOffsetRes(R.dimen.actionbar_home_width);
// customize the ActionBar
if (Build.VERSION.SDK_INT >= 11) {
@@ -50,16 +45,50 @@ public void onCreate(Bundle savedInstanceState) {
}
}
+ private void addLeft() {
+ FrameLayout left = new FrameLayout(this);
+ left.setId("LEFT".hashCode());
+ setBehindLeftContentView(left);
+ getSupportFragmentManager()
+ .beginTransaction()
+ .replace("LEFT".hashCode(), new SampleListFragment())
+ .commit();
+
+ SlidingMenu sm = getSlidingMenu();
+ sm.setShadowDrawable(R.drawable.shadow, SlidingMenu.LEFT);
+ sm.setBehindOffsetRes(R.dimen.actionbar_home_width, SlidingMenu.LEFT);
+ }
+
+ private void addRight() {
+ FrameLayout right = new FrameLayout(this);
+ right.setId("RIGHT".hashCode());
+ this.setBehindRightContentView(right);
+ getSupportFragmentManager()
+ .beginTransaction()
+ .replace("RIGHT".hashCode(), new SampleListFragment())
+ .commit();
+
+ SlidingMenu sm = getSlidingMenu();
+ sm.setShadowDrawable(R.drawable.shadow_right, SlidingMenu.RIGHT);
+ sm.setBehindOffsetRes(R.dimen.actionbar_home_width, SlidingMenu.RIGHT);
+ }
+
+// @Override
+// public void onResume() {
+// super.onResume();
+// getSlidingMenu().showAbove();
+// }
+
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
- toggle();
+ toggle(SlidingMenu.LEFT);
return true;
}
return super.onOptionsItemSelected(item);
}
-
+
public class PagerAdapter extends FragmentPagerAdapter {
private List mFragments = new ArrayList();
private ViewPager mPager;
@@ -68,6 +97,8 @@ public PagerAdapter(FragmentManager fm, ViewPager vp) {
super(fm);
mPager = vp;
mPager.setAdapter(this);
+ for (int i = 0; i < 3; i++)
+ addTab(new SampleListFragment());
}
public void addTab(Fragment frag) {
@@ -84,5 +115,5 @@ public int getCount() {
return mFragments.size();
}
}
-
+
}
diff --git a/example/src/com/slidingmenu/example/CustomAnimation.java b/example/src/com/slidingmenu/example/CustomAnimation.java
index 63308dbcd..31eac6dba 100644
--- a/example/src/com/slidingmenu/example/CustomAnimation.java
+++ b/example/src/com/slidingmenu/example/CustomAnimation.java
@@ -27,8 +27,8 @@ public void onCreate(Bundle savedInstanceState) {
SlidingMenu sm = getSlidingMenu();
setSlidingActionBarEnabled(true);
- sm.setBehindScrollScale(0.0f);
- sm.setBehindCanvasTransformer(mTransformer);
+ sm.setBehindScrollScale(0.0f, SlidingMenu.BOTH);
+ sm.setBehindCanvasTransformer(mTransformer, SlidingMenu.BOTH);
}
@Override
diff --git a/example/src/com/slidingmenu/example/CustomRotateAnimation.java b/example/src/com/slidingmenu/example/CustomRotateAnimation.java
index a9f8d65ff..55e734c37 100644
--- a/example/src/com/slidingmenu/example/CustomRotateAnimation.java
+++ b/example/src/com/slidingmenu/example/CustomRotateAnimation.java
@@ -4,6 +4,7 @@
import android.os.Bundle;
import android.view.animation.Interpolator;
+import com.slidingmenu.lib.SlidingMenu;
import com.slidingmenu.lib.SlidingMenu.CanvasTransformer;
public class CustomRotateAnimation extends CustomAnimation {
@@ -31,7 +32,7 @@ public void transformCanvas(Canvas canvas, float percentOpen) {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- getSlidingMenu().setBehindScrollScale(1);
+ getSlidingMenu().setBehindScrollScale(1, SlidingMenu.BOTH);
}
}
diff --git a/example/src/com/slidingmenu/example/PropertiesActivity.java b/example/src/com/slidingmenu/example/PropertiesActivity.java
index 7f8bd4a1a..14f0f3015 100644
--- a/example/src/com/slidingmenu/example/PropertiesActivity.java
+++ b/example/src/com/slidingmenu/example/PropertiesActivity.java
@@ -15,15 +15,15 @@ public class PropertiesActivity extends BaseActivity {
public PropertiesActivity() {
super(R.string.properties);
}
-
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setSlidingActionBarEnabled(true);
-
+
setContentView(R.layout.properties);
-
+
// touch mode stuff
RadioGroup touchAbove = (RadioGroup) findViewById(R.id.touch_above);
touchAbove.check(R.id.touch_above_margin);
@@ -40,7 +40,7 @@ public void onCheckedChanged(RadioGroup group, int checkedId) {
}
}
});
-
+
RadioGroup touchBehind = (RadioGroup) findViewById(R.id.touch_behind);
touchBehind.check(R.id.touch_behind_margin);
touchBehind.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@@ -57,7 +57,7 @@ public void onCheckedChanged(RadioGroup group, int checkedId) {
}
});
-
+
// scroll scale stuff
SeekBar scrollScale = (SeekBar) findViewById(R.id.scroll_scale);
scrollScale.setMax(1000);
@@ -70,11 +70,11 @@ public void onProgressChanged(SeekBar seekBar, int progress,
public void onStartTrackingTouch(SeekBar seekBar) { }
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
- getSlidingMenu().setBehindScrollScale((float) seekBar.getProgress()/seekBar.getMax());
+ getSlidingMenu().setBehindScrollScale((float) seekBar.getProgress()/seekBar.getMax(), SlidingMenu.BOTH);
}
});
-
-
+
+
// behind width stuff
SeekBar behindWidth = (SeekBar) findViewById(R.id.behind_width);
behindWidth.setMax(1000);
@@ -88,11 +88,11 @@ public void onStartTrackingTouch(SeekBar seekBar) { }
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
float percent = (float) seekBar.getProgress()/seekBar.getMax();
- getSlidingMenu().setBehindWidth((int) (percent * getSlidingMenu().getWidth()));
+ getSlidingMenu().setBehindWidth((int) (percent * getSlidingMenu().getWidth()), SlidingMenu.BOTH);
}
});
-
-
+
+
// fading stuff
CheckBox fadeEnabled = (CheckBox) findViewById(R.id.fade_enabled);
fadeEnabled.setChecked(true);
diff --git a/example/src/com/slidingmenu/example/SlidingTitleBar.java b/example/src/com/slidingmenu/example/SlidingTitleBar.java
index b781a1ba5..f66600120 100644
--- a/example/src/com/slidingmenu/example/SlidingTitleBar.java
+++ b/example/src/com/slidingmenu/example/SlidingTitleBar.java
@@ -1,6 +1,9 @@
package com.slidingmenu.example;
+import com.slidingmenu.lib.SlidingMenu;
+
import android.os.Bundle;
+import android.support.v4.view.ViewPager;
public class SlidingTitleBar extends BaseActivity {
@@ -14,11 +17,17 @@ public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// set the Above View
- setContentView(R.layout.content_frame);
- getSupportFragmentManager()
- .beginTransaction()
- .replace(R.id.content_frame, new SampleListFragment())
- .commit();
+// setContentView(R.layout.content_frame);
+// getSupportFragmentManager()
+// .beginTransaction()
+// .replace(R.id.content_frame, new SampleListFragment())
+// .commit();
+
+ ViewPager vp = new ViewPager(this);
+ vp.setId("VP".hashCode());
+ vp.setAdapter(new PagerAdapter(getSupportFragmentManager(), vp));
+ setContentView(vp);
+ getSlidingMenu().setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
setSlidingActionBarEnabled(true);
}
diff --git a/library/AndroidManifest.xml b/library/AndroidManifest.xml
index 86b1a3a77..6e6ac9404 100644
--- a/library/AndroidManifest.xml
+++ b/library/AndroidManifest.xml
@@ -11,10 +11,18 @@
-
-
-
-
+
+
+
+
\ No newline at end of file
diff --git a/library/res/drawable/custom_up.xml b/library/res/drawable/custom_up.xml
new file mode 100644
index 000000000..189367d0a
--- /dev/null
+++ b/library/res/drawable/custom_up.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/res/values/attrs.xml b/library/res/values/attrs.xml
index 461440384..d65a6c56f 100644
--- a/library/res/values/attrs.xml
+++ b/library/res/values/attrs.xml
@@ -17,16 +17,22 @@
+
+
+
+
+
-
+
+
-
+
-
+
diff --git a/library/res/values/styles.xml b/library/res/values/styles.xml
new file mode 100644
index 000000000..3df4c7504
--- /dev/null
+++ b/library/res/values/styles.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/src/com/slidingmenu/lib/CustomUpIndicator.java b/library/src/com/slidingmenu/lib/CustomUpIndicator.java
new file mode 100644
index 000000000..4384cadb6
--- /dev/null
+++ b/library/src/com/slidingmenu/lib/CustomUpIndicator.java
@@ -0,0 +1,45 @@
+package com.slidingmenu.lib;
+
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.RectF;
+import android.graphics.drawable.Drawable;
+
+public class CustomUpIndicator extends Drawable {
+
+ public static Paint mPaint;
+ private RectF mRect;
+
+ @Override
+ public void draw(Canvas canvas) {
+ // TODO Auto-generated method stub
+ mPaint.setARGB(0, 255, 0, 0);
+
+ mRect.left = 0.0f;
+ mRect.top = 0.0f;
+ mRect.right = 50.0f;
+ mRect.bottom = 50.0f;
+
+ canvas.drawRect(mRect, mPaint);
+ }
+
+ @Override
+ public int getOpacity() {
+ return PixelFormat.OPAQUE;
+ }
+
+ @Override
+ public void setAlpha(int alpha) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter cf) {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/library/src/com/slidingmenu/lib/CustomViewAbove.java b/library/src/com/slidingmenu/lib/CustomViewAbove.java
index 1628d4717..aaa293f9b 100644
--- a/library/src/com/slidingmenu/lib/CustomViewAbove.java
+++ b/library/src/com/slidingmenu/lib/CustomViewAbove.java
@@ -1,7 +1,10 @@
package com.slidingmenu.lib;
import android.content.Context;
-import android.graphics.*;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.v4.view.KeyEventCompat;
@@ -48,14 +51,16 @@ public float getInterpolation(float t) {
}
};
- private FrameLayout mMenu;
- private FrameLayout mContent;
+ private FrameLayout mMenuLeft;
+ private FrameLayout mMenuRight;
+ protected FrameLayout mContent;
private int mCurItem;
private Scroller mScroller;
private int mShadowWidth;
- private Drawable mShadowDrawable;
+ private Drawable mShadowDrawableLeft;
+ private Drawable mShadowDrawableRight;
private boolean mScrollingCacheEnabled;
@@ -90,8 +95,9 @@ public float getInterpolation(float t) {
private int mFlingDistance;
private boolean mLastTouchAllowed = false;
- private final int mSlidingMenuThreshold = 10;
- private CustomViewBehind mCustomViewBehind;
+ private final int mSlidingMenuThreshold = 16;
+ private CustomViewBehind mViewBehindLeft;
+ private CustomViewBehind mViewBehindRight;
private boolean mEnabled = true;
private OnPageChangeListener mOnPageChangeListener;
@@ -183,13 +189,23 @@ void initCustomViewAbove(boolean isAbove) {
setInternalPageChangeListener(new SimpleOnPageChangeListener() {
public void onPageSelected(int position) {
- if (mCustomViewBehind != null) {
+ if (mViewBehindLeft != null) {
switch (position) {
case 0:
- mCustomViewBehind.setChildrenEnabled(true);
+ mViewBehindLeft.setChildrenEnabled(true);
break;
case 1:
- mCustomViewBehind.setChildrenEnabled(false);
+ mViewBehindLeft.setChildrenEnabled(false);
+ break;
+ }
+ }
+ if (mViewBehindRight != null) {
+ switch (position) {
+ case 1:
+ mViewBehindRight.setChildrenEnabled(false);
+ break;
+ case 2:
+ mViewBehindRight.setChildrenEnabled(true);
break;
}
}
@@ -200,10 +216,12 @@ public void onPageSelected(int position) {
final float density = context.getResources().getDisplayMetrics().density;
mFlingDistance = (int) (MIN_DISTANCE_FOR_FLING * density);
- mMenu = new FrameLayout(getContext());
- super.addView(mMenu);
+ mMenuLeft = new FrameLayout(getContext());
+ super.addView(mMenuLeft);
mContent = new FrameLayout(getContext());
super.addView(mContent);
+ mMenuRight = new FrameLayout(getContext());
+ super.addView(mMenuRight);
if (isAbove) {
View v = new LinearLayout(getContext());
@@ -243,18 +261,24 @@ void setCurrentItemInternal(int item, boolean smoothScroll, boolean always) {
}
void setCurrentItemInternal(int item, boolean smoothScroll, boolean always, int velocity) {
- if (!always && mCurItem == item && mMenu != null && mContent != null) {
+ if (!always && mCurItem == item && mMenuLeft != null && mContent != null) {
setScrollingCacheEnabled(false);
return;
}
- if (item < 0) {
- item = 0;
- } else if (item >= 2) {
- item = 1;
+
+ int start = mViewBehindLeft == null ? 1 : 0;
+ int end = mViewBehindRight == null ? 1 : 2;
+ // TODO count accordingly
+ if (item < start) {
+ item = start;
+ } else if (item > end) {
+ item = end;
}
+
final boolean dispatchSelected = mCurItem != item;
mCurItem = item;
- final int destX = getChildLeft(mCurItem);
+ final int destX = this.getDestScrollX(mCurItem);
+
if (dispatchSelected && mOnPageChangeListener != null) {
mOnPageChangeListener.onPageSelected(item);
}
@@ -334,10 +358,16 @@ public int getShadowWidth() {
*
* @param d Drawable to display between pages
*/
- public void setShadowDrawable(Drawable d) {
- mShadowDrawable = d;
+ public void setShadowDrawable(Drawable d, int side) {
+ if (side == SlidingMenu.LEFT) {
+ mShadowDrawableLeft = d;
+ } else if (side == SlidingMenu.RIGHT) {
+ mShadowDrawableRight = d;
+ } else if (side == SlidingMenu.BOTH) {
+ mShadowDrawableLeft = d;
+ mShadowDrawableRight = d;
+ }
if (d != null) refreshDrawableState();
- setWillNotDraw(d == null);
invalidate();
}
@@ -346,21 +376,21 @@ public void setShadowDrawable(Drawable d) {
*
* @param resId Resource ID of a drawable to display between pages
*/
- public void setShadowDrawable(int resId) {
- setShadowDrawable(getContext().getResources().getDrawable(resId));
+ public void setShadowDrawable(int resId, int side) {
+ setShadowDrawable(getContext().getResources().getDrawable(resId), side);
}
@Override
protected boolean verifyDrawable(Drawable who) {
- return super.verifyDrawable(who) || who == mShadowDrawable;
+ return super.verifyDrawable(who) || who == mShadowDrawableLeft || who == mShadowDrawableRight;
}
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
- final Drawable d = mShadowDrawable;
+ final Drawable d = mShadowDrawableLeft;
if (d != null && d.isStateful()) {
d.setState(getDrawableState());
}
@@ -376,11 +406,31 @@ float distanceInfluenceForSnapDuration(float f) {
return (float) FloatMath.sin(f);
}
- public int getDestScrollX() {
- if (isMenuOpen()) {
- return getBehindWidth();
+ public int getDestScrollX(int i) {
+ switch (i) {
+ case 0:
+ return 0;
+ case 1:
+ return mContent.getLeft();
+ case 2:
+ return mContent.getLeft() + mViewBehindRight.getWidth();
+ }
+ throw new RuntimeException("This should never happen!");
+ }
+
+ public int getRightScrollBound() {
+ if (mViewBehindRight != null) {
+ return mContent.getLeft() + mViewBehindRight.getWidth();
} else {
+ return mContent.getLeft();
+ }
+ }
+
+ public int getLeftScrollBound() {
+ if (mViewBehindLeft != null) {
return 0;
+ } else {
+ return mContent.getLeft();
}
}
@@ -393,28 +443,49 @@ public int getChildRight(int i) {
return getChildLeft(i) + getChildWidth(i);
}
- public boolean isMenuOpen() {
+ public boolean isRightOpen() {
+ if (mViewBehindRight == null)
+ return false;
+
+ return getCurrentItem() == 2;
+ }
+
+ public boolean isLeftOpen() {
+ if (mViewBehindLeft == null) {
+ return false;
+ }
+
return getCurrentItem() == 0;
}
public int getCustomWidth() {
- int i = isMenuOpen()? 0 : 1;
+ int i = 1;
+ i = isLeftOpen()? 0 : i;
+ i = isRightOpen()? 2 : i;
return getChildWidth(i);
}
public int getChildWidth(int i) {
- if (i <= 0) {
- return getBehindWidth();
- } else {
- return getChildAt(i).getWidth();
- }
+ try {
+ switch (i) {
+ case 0:
+ return mViewBehindLeft.getWidth();
+ case 1:
+ return mContent.getWidth();
+ case 2:
+ return mViewBehindRight.getWidth();
+ }
+ } catch (NullPointerException e) { }
+ return 0;
}
public int getBehindWidth() {
- if (mCustomViewBehind == null) {
- return 0;
+ if (mViewBehindLeft != null) {
+ return mViewBehindLeft.getWidth();
+ } else if (mViewBehindRight != null) {
+ return mViewBehindRight.getWidth();
} else {
- return mCustomViewBehind.getWidth();
+ return 0;
}
}
@@ -455,10 +526,14 @@ void smoothScrollTo(int x, int y, int velocity) {
int dy = y - sy;
if (dx == 0 && dy == 0) {
completeScroll();
- if (isMenuOpen()) {
+ if (isLeftOpen()) {
+ if (mOpenedListener != null)
+ mOpenedListener.onOpened(SlidingMenu.LEFT);
+ } else if (isRightOpen()) {
if (mOpenedListener != null)
- mOpenedListener.onOpened();
+ mOpenedListener.onOpened(SlidingMenu.RIGHT);
} else {
+
if (mClosedListener != null)
mClosedListener.onClosed();
}
@@ -490,21 +565,26 @@ void smoothScrollTo(int x, int y, int velocity) {
}
protected void setMenu(View v) {
- if (mMenu.getChildCount() > 0) {
- mMenu.removeAllViews();
+ if (mMenuLeft.getChildCount() > 0) {
+ mMenuLeft.removeAllViews();
}
- mMenu.addView(v);
+ mMenuLeft.addView(v);
}
public void setContent(View v) {
if (mContent.getChildCount() > 0) {
mContent.removeAllViews();
}
- mContent.addView(v);
+ if (v != null)
+ mContent.addView(v);
}
- public void setCustomViewBehind(CustomViewBehind cvb) {
- mCustomViewBehind = cvb;
+ public void setViewBehindLeft(CustomViewBehind cvb) {
+ mViewBehindLeft = cvb;
+ }
+
+ public void setViewBehindRight(CustomViewBehind cvb) {
+ mViewBehindRight = cvb;
}
@Override
@@ -519,7 +599,8 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mContent.measure(contentWidth, contentHeight);
final int menuWidth = getChildMeasureSpec(widthMeasureSpec, 0, getBehindWidth());
- mMenu.measure(menuWidth, contentHeight);
+ mMenuLeft.measure(menuWidth, contentHeight);
+ mMenuRight.measure(menuWidth, contentHeight);
}
@Override
@@ -541,10 +622,10 @@ protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int height = b - t;
int contentLeft = getChildLeft(1);
- float percentOpen = getPercentOpen();
- int offset = (int) (mScrollX * (1 - mScrollScale));
- mMenu.layout(0, 0, width, height);
+ mMenuLeft.layout(0, 0, width, height);
mContent.layout(contentLeft, 0, contentLeft + width, height);
+ mMenuRight.layout(contentLeft + width, 0, contentLeft + 2*width, height);
+ this.setCurrentItemInternal(mCurItem, false, true);
}
@@ -616,9 +697,12 @@ private void completeScroll() {
if (oldX != x || oldY != y) {
scrollTo(x, y);
}
- if (isMenuOpen()) {
+ if (isLeftOpen()) {
if (mOpenedListener != null)
- mOpenedListener.onOpened();
+ mOpenedListener.onOpened(SlidingMenu.LEFT);
+ } else if (isRightOpen()) {
+ if (mOpenedListener != null)
+ mOpenedListener.onOpened(SlidingMenu.RIGHT);
} else {
if (mClosedListener != null)
mClosedListener.onClosed();
@@ -647,12 +731,22 @@ protected int getTouchModeBehind() {
}
private boolean thisTouchAllowed(MotionEvent ev) {
- if (isMenuOpen()) {
+ int x = (int) (ev.getX() + mScrollX);
+ if (isLeftOpen()) {
+ switch (mTouchModeBehind) {
+ case SlidingMenu.TOUCHMODE_FULLSCREEN:
+ return true;
+ case SlidingMenu.TOUCHMODE_MARGIN:
+ return x >= getBehindWidth() && x <= getWidth();
+ default:
+ return false;
+ }
+ } else if (isRightOpen()) {
switch (mTouchModeBehind) {
case SlidingMenu.TOUCHMODE_FULLSCREEN:
return true;
case SlidingMenu.TOUCHMODE_MARGIN:
- return ev.getX() >= getBehindWidth() && ev.getX() <= getWidth();
+ return x <= mContent.getRight();
default:
return false;
}
@@ -663,12 +757,35 @@ private boolean thisTouchAllowed(MotionEvent ev) {
case SlidingMenu.TOUCHMODE_MARGIN:
int pixels = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
mSlidingMenuThreshold, getResources().getDisplayMetrics());
- return ev.getX() >= 0 && ev.getX() <= pixels;
+ int left = mContent.getLeft();
+ int right = mContent.getRight();
+ boolean bool = false;
+ if (mViewBehindLeft != null)
+ bool |= (x >= left && x <= pixels + left);
+ if (mViewBehindRight != null)
+ bool |= (x <= right && x >= right - pixels);
+ return bool;
default:
return false;
}
}
}
+
+ private boolean thisSlideAllowed(float dx) {
+ boolean allowed = false;
+ if (isLeftOpen()) {
+ allowed = dx < 0;
+ } else if (isRightOpen()) {
+ allowed = dx > 0;
+ } else {
+ if (mViewBehindLeft != null)
+ allowed |= dx > 0;
+ if (mViewBehindRight != null)
+ allowed |= dx < 0;
+ }
+ Log.v(TAG, "this slide allowed " + allowed);
+ return allowed;
+ }
private boolean mIsUnableToDrag;
@@ -681,9 +798,6 @@ public boolean onInterceptTouchEvent(MotionEvent ev) {
final int action = ev.getAction() & MotionEventCompat.ACTION_MASK;
- if (action == MotionEvent.ACTION_DOWN)
- Log.v(TAG, "Received ACTION_DOWN");
-
if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
mIsBeingDragged = false;
mIsUnableToDrag = false;
@@ -714,7 +828,7 @@ else if (mIsUnableToDrag)
final float xDiff = Math.abs(dx);
final float y = MotionEventCompat.getY(ev, pointerIndex);
final float yDiff = Math.abs(y - mLastMotionY);
- if (xDiff > mTouchSlop && xDiff > yDiff) {
+ if (xDiff > mTouchSlop && xDiff > yDiff && thisSlideAllowed(dx)) {
if (DEBUG) Log.v(TAG, "Starting drag! from onInterceptTouch");
mIsBeingDragged = true;
mLastMotionX = x;
@@ -725,15 +839,13 @@ else if (mIsUnableToDrag)
break;
case MotionEvent.ACTION_DOWN:
- mActivePointerId = ev.getAction() & ((Build.VERSION.SDK_INT >= 8) ? MotionEvent.ACTION_POINTER_INDEX_MASK :
- MotionEvent.ACTION_POINTER_ID_MASK);
- Log.v(TAG, "active pointer id : " + mActivePointerId);
+ mActivePointerId = ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK;
mLastMotionX = mInitialMotionX = MotionEventCompat.getX(ev, mActivePointerId);
mLastMotionY = MotionEventCompat.getY(ev, mActivePointerId);
if (thisTouchAllowed(ev)) {
mIsBeingDragged = false;
mIsUnableToDrag = false;
- if (isMenuOpen() && mInitialMotionX > getBehindWidth())
+ if ((isLeftOpen() || isRightOpen()) && mTouchModeBehind == SlidingMenu.TOUCHMODE_MARGIN)
return true;
} else {
mIsUnableToDrag = true;
@@ -816,8 +928,8 @@ public boolean onTouchEvent(MotionEvent ev) {
mLastMotionX = x;
float oldScrollX = getScrollX();
float scrollX = oldScrollX + deltaX;
- final float leftBound = 0;
- final float rightBound = getBehindWidth();
+ final float leftBound = getLeftScrollBound();
+ final float rightBound = getRightScrollBound();
if (scrollX < leftBound) {
scrollX = leftBound;
} else if (scrollX > rightBound) {
@@ -835,23 +947,24 @@ public boolean onTouchEvent(MotionEvent ev) {
velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
int initialVelocity = (int) VelocityTrackerCompat.getXVelocity(
velocityTracker, mActivePointerId);
- final int widthWithMargin = getChildWidth(mCurItem) + mShadowWidth;
+ final int widthWithMargin = getChildWidth(mCurItem);
final int scrollX = getScrollX();
- final int currentPage = scrollX / widthWithMargin;
final float pageOffset = (float) (scrollX % widthWithMargin) / widthWithMargin;
final int activePointerIndex =
MotionEventCompat.findPointerIndex(ev, mActivePointerId);
final float x = MotionEventCompat.getX(ev, activePointerIndex);
final int totalDelta = (int) (x - mInitialMotionX);
- int nextPage = determineTargetPage(currentPage, pageOffset, initialVelocity,
+ int nextPage = determineTargetPage(mCurItem, pageOffset, initialVelocity,
totalDelta);
setCurrentItemInternal(nextPage, true, true, initialVelocity);
mActivePointerId = INVALID_POINTER;
endDrag();
- } else if (isMenuOpen()) {
+ } else if (isLeftOpen()) {
// close the menu
setCurrentItem(1);
+ } else if (isRightOpen()) {
+ setCurrentItem(1);
}
break;
case MotionEvent.ACTION_CANCEL:
@@ -879,84 +992,110 @@ public boolean onTouchEvent(MotionEvent ev) {
return true;
}
- private float mScrollScale;
+ private float mScrollScaleLeft;
+ private float mScrollScaleRight;
- public float getScrollScale() {
- return mScrollScale;
+ public float getScrollScale(int side) {
+ if (side == SlidingMenu.LEFT) {
+ return mScrollScaleLeft;
+ } else {
+ return mScrollScaleRight;
+ }
}
- public void setScrollScale(float f) {
+ public void setScrollScale(float f, int side) {
if (f < 0 && f > 1)
- throw new IllegalStateException("ScrollScale must be between 0 and 1");
- mScrollScale = f;
+ throw new IllegalArgumentException("ScrollScale must be between 0 and 1");
+ if (side == SlidingMenu.LEFT) {
+ mScrollScaleLeft = f;
+ } else if (side == SlidingMenu.RIGHT) {
+ mScrollScaleRight = f;
+ } else if (side == SlidingMenu.BOTH) {
+ mScrollScaleLeft = f;
+ mScrollScaleRight = f;
+ }
}
@Override
public void scrollTo(int x, int y) {
super.scrollTo(x, y);
mScrollX = x;
- if (mCustomViewBehind != null && mEnabled) {
- mCustomViewBehind.scrollTo((int)(x*mScrollScale), y);
+ // adjust visibility so we don't have any layout issues
+ if (mViewBehindLeft != null) {
+ if (x < getBehindWidth()) {
+ if (mViewBehindLeft.getVisibility() != View.VISIBLE) {
+ mViewBehindLeft.setVisibility(View.VISIBLE);
+ }
+ } else if (mViewBehindLeft.getVisibility() != View.INVISIBLE){
+ mViewBehindLeft.setVisibility(View.INVISIBLE);
+ }
+ }
+ if (mViewBehindRight != null) {
+ if (x > mContent.getLeft()) {
+ if (mViewBehindRight.getVisibility() != View.VISIBLE) {
+ mViewBehindRight.setVisibility(View.VISIBLE);
+ }
+ } else if (mViewBehindRight.getVisibility() != View.INVISIBLE){
+ mViewBehindRight.setVisibility(View.INVISIBLE);
+ }
}
- if (mShadowDrawable != null || mSelectorDrawable != null)
+ // scroll the behind views
+ if (mViewBehindLeft != null && mEnabled) {
+ mViewBehindLeft.scrollTo((int)(x*mScrollScaleLeft), y);
+ }
+ if (mViewBehindRight != null && mEnabled) {
+ int x2 = (int) ((x - mContent.getLeft() - mViewBehindRight.getWidth()) * mScrollScaleRight);
+ Log.v(TAG, "scrolling right to " + x2);
+ mViewBehindRight.scrollTo(x2, y);
+ }
+
+ if (mShadowDrawableLeft != null || mSelectorDrawable != null)
invalidate();
}
private int determineTargetPage(int currentPage, float pageOffset, int velocity, int deltaX) {
int targetPage;
- if (Math.abs(deltaX) > mFlingDistance && Math.abs(velocity) > mMinimumVelocity) {
- targetPage = velocity > 0 ? currentPage : currentPage + 1;
+ if (Math.abs(deltaX) > (float)mFlingDistance && Math.abs(velocity) > mMinimumVelocity) {
+ targetPage = velocity > 0 ? currentPage - 1 : currentPage + 1;
} else {
- targetPage = (int) (currentPage + pageOffset + 0.5f);
+ targetPage = (int) ((deltaX > 0) ?
+ (currentPage + pageOffset - 0.5f) : (currentPage - pageOffset + 0.5f));
+ if ((deltaX > 0 && targetPage > currentPage) || (deltaX < 0 && targetPage < currentPage))
+ targetPage = currentPage;
}
return targetPage;
}
- protected float getPercentOpen() {
- return (getBehindWidth() - mScrollX) / getBehindWidth();
+ protected float getPercentOpenLeft() {
+ return (getBehindWidth() - mScrollX) / mViewBehindLeft.getWidth();
+ }
+
+ protected float getPercentOpenRight() {
+ return (getWidth() - (mContent.getRight() - mScrollX)) / mViewBehindRight.getWidth();
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
final int behindWidth = getBehindWidth();
- // Draw the margin drawable if needed.
- if (mShadowWidth > 0 && mShadowDrawable != null) {
- final int left = behindWidth - mShadowWidth;
- mShadowDrawable.setBounds(left, 0, left + mShadowWidth, getHeight());
- mShadowDrawable.draw(canvas);
+ // Draw the margin drawable if needed
+ if (mShadowWidth > 0) {
+ if (mShadowDrawableLeft != null) {
+ final int left = behindWidth - mShadowWidth;
+ mShadowDrawableLeft.setBounds(left, 0, left + mShadowWidth, getHeight());
+ mShadowDrawableLeft.draw(canvas);
+ }
+ if (mShadowDrawableRight != null) {
+ mShadowDrawableRight.setBounds(mContent.getRight(), 0, mContent.getRight() + mShadowWidth, getHeight());
+ mShadowDrawableRight.draw(canvas);
+ }
}
if (mFadeEnabled)
- onDrawBehindFade(canvas, getPercentOpen());
+ onDrawBehindFade(canvas);
if (mSelectorEnabled)
- onDrawMenuSelector(canvas, getPercentOpen());
- }
-
- /**
- * Pads our content window so that it fits within the system windows.
- * @param insets The insets by which we need to offset our view.
- * @return True since we handled the padding change.
- */
- @Override
- protected boolean fitSystemWindows(Rect insets) {
-
- if (mContent != null) {
- int leftPadding = mContent.getPaddingLeft() + insets.left;
- int rightPadding = mContent.getPaddingRight() + insets.right;
- int topPadding = mContent.getPaddingTop() + insets.top;
- int bottomPadding = mContent.getPaddingBottom() + insets.bottom;
- mContent.setPadding(leftPadding, topPadding, rightPadding, bottomPadding);
- return true;
- }
-
- return super.fitSystemWindows(insets);
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
+ onDrawMenuSelector(canvas);
}
// variables for drawing
@@ -970,21 +1109,31 @@ protected void onDraw(Canvas canvas) {
private Bitmap mSelectorDrawable;
private View mSelectedView;
-
- private void onDrawBehindFade(Canvas canvas, float openPercent) {
- final int alpha = (int) (mFadeDegree * 255 * Math.abs(1-openPercent));
- if (alpha > 0) {
- mBehindFadePaint.setColor(Color.argb(alpha, 0, 0, 0));
- canvas.drawRect(0, 0, getBehindWidth(), getHeight(), mBehindFadePaint);
+ private void onDrawBehindFade(Canvas canvas) {
+ int alpha;
+ if (mViewBehindLeft != null) {
+ alpha = (int) (mFadeDegree * 255 * Math.abs(1-getPercentOpenLeft()));
+ if (alpha > 0) {
+ mBehindFadePaint.setColor(Color.argb(alpha, 0, 0, 0));
+ canvas.drawRect(0, 0, getBehindWidth(), getHeight(), mBehindFadePaint);
+ }
+ }
+ if (mViewBehindRight != null) {
+ alpha = (int) (mFadeDegree * 255 * Math.abs(1-getPercentOpenRight()));
+ if (alpha > 0) {
+ mBehindFadePaint.setColor(Color.argb(alpha, 0, 0, 0));
+ canvas.drawRect(mContent.getRight(), 0, mContent.getRight() + mViewBehindRight.getWidth(),
+ getHeight(), mBehindFadePaint);
+ }
}
}
- private void onDrawMenuSelector(Canvas canvas, float openPercent) {
+ private void onDrawMenuSelector(Canvas canvas) {
if (mSelectorDrawable != null && mSelectedView != null) {
String tag = (String) mSelectedView.getTag(R.id.selected_view);
if (tag.equals(TAG+"SelectedView")) {
int right = getChildLeft(1);
- int left = (int) (right - mSelectorDrawable.getWidth() * openPercent);
+ int left = (int) (right - mSelectorDrawable.getWidth() * getPercentOpenLeft());
canvas.save();
canvas.clipRect(left, 0, right, getHeight());
diff --git a/library/src/com/slidingmenu/lib/CustomViewBehind.java b/library/src/com/slidingmenu/lib/CustomViewBehind.java
index 7fe8d3829..abd134381 100644
--- a/library/src/com/slidingmenu/lib/CustomViewBehind.java
+++ b/library/src/com/slidingmenu/lib/CustomViewBehind.java
@@ -8,23 +8,26 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Transformation;
+import android.widget.RelativeLayout;
import com.slidingmenu.lib.SlidingMenu.CanvasTransformer;
public class CustomViewBehind extends CustomViewAbove {
private static final String TAG = "CustomViewBehind";
+ public static final int LEFT = 0;
+ public static final int RIGHT = 1;
private CustomViewAbove mViewAbove;
+ private int mMode;
private CanvasTransformer mTransformer;
private boolean mChildrenEnabled;
- public CustomViewBehind(Context context) {
- this(context, null);
- }
-
- public CustomViewBehind(Context context, AttributeSet attrs) {
- super(context, attrs, false);
+ public CustomViewBehind(Context context, int mode) {
+ super(context);
+ if (mode != LEFT && mode != RIGHT)
+ throw new IllegalStateException("mode must be LEFT or RIGHT");
+ mMode = mode;
}
public void setCustomViewAbove(CustomViewAbove customViewAbove) {
@@ -45,10 +48,17 @@ public void setCanvasTransformer(CanvasTransformer t) {
public int getChildLeft(int i) {
return 0;
}
+
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ final int width = r - l;
+ final int height = b - t;
+ mContent.layout(0, 0, width, height);
+ }
@Override
public int getCustomWidth() {
- int i = isMenuOpen()? 0 : 1;
+ int i = isLeftOpen()? 0 : 1;
return getChildWidth(i);
}
@@ -66,11 +76,6 @@ public int getBehindWidth() {
return params.width;
}
- @Override
- public void setContent(View v) {
- super.setMenu(v);
- }
-
public void setChildrenEnabled(boolean enabled) {
mChildrenEnabled = enabled;
}
@@ -96,7 +101,16 @@ public boolean onTouchEvent(MotionEvent e) {
protected void dispatchDraw(Canvas canvas) {
if (mTransformer != null) {
canvas.save();
- mTransformer.transformCanvas(canvas, mViewAbove.getPercentOpen());
+ float percent = 0.0f;
+ switch (mMode) {
+ case LEFT:
+ percent = mViewAbove.getPercentOpenLeft();
+ break;
+ case RIGHT:
+ percent = mViewAbove.getPercentOpenRight();
+ break;
+ }
+ mTransformer.transformCanvas(canvas, percent);
super.dispatchDraw(canvas);
canvas.restore();
} else
diff --git a/library/src/com/slidingmenu/lib/SlidingMenu.java b/library/src/com/slidingmenu/lib/SlidingMenu.java
index 3564719ec..e7cd4fc93 100644
--- a/library/src/com/slidingmenu/lib/SlidingMenu.java
+++ b/library/src/com/slidingmenu/lib/SlidingMenu.java
@@ -15,6 +15,7 @@
import android.support.v4.os.ParcelableCompat;
import android.support.v4.os.ParcelableCompatCreatorCallbacks;
import android.util.AttributeSet;
+import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
@@ -27,20 +28,27 @@
public class SlidingMenu extends RelativeLayout {
+ public static final String TAG = "SlidingMenu";
+
public static final int TOUCHMODE_MARGIN = 0;
public static final int TOUCHMODE_FULLSCREEN = 1;
+ public static final int LEFT = 0x0100;
+ public static final int RIGHT = 0x1000;
+ public static final int BOTH = LEFT | RIGHT;
+
private CustomViewAbove mViewAbove;
- private CustomViewBehind mViewBehind;
+ private CustomViewBehind mViewBehindLeft;
+ private CustomViewBehind mViewBehindRight;
private OnOpenListener mOpenListener;
private OnCloseListener mCloseListener;
- private boolean mSlidingEnabled;
+ private boolean mSlidingEnabled;
+ private int mMode;
public static void attachSlidingMenu(Activity activity, SlidingMenu sm, boolean slidingTitle) {
-
if (sm.getParent() != null)
- throw new IllegalStateException("SlidingMenu cannot be attached to another view when" +
+ throw new IllegalArgumentException("SlidingMenu cannot be attached to another view when" +
" calling the static method attachSlidingMenu");
if (slidingTitle) {
@@ -70,7 +78,7 @@ public interface OnOpenListener {
}
public interface OnOpenedListener {
- public void onOpened();
+ public void onOpened(int side);
}
public interface OnCloseListener {
@@ -95,25 +103,20 @@ public SlidingMenu(Context context, AttributeSet attrs) {
public SlidingMenu(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
-
- LayoutParams behindParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
- mViewBehind = new CustomViewBehind(context);
- addView(mViewBehind, behindParams);
+ // above view
LayoutParams aboveParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
mViewAbove = new CustomViewAbove(context);
addView(mViewAbove, aboveParams);
- // register the CustomViewBehind2 with the CustomViewAbove
- mViewAbove.setCustomViewBehind(mViewBehind);
- mViewBehind.setCustomViewAbove(mViewAbove);
mViewAbove.setOnPageChangeListener(new OnPageChangeListener() {
- public static final int POSITION_OPEN = 0;
+ public static final int POSITION_LEFT_OPEN = 0;
public static final int POSITION_CLOSE = 1;
+ public static final int POSITION_RIGHT_OPEN = 2;
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) { }
public void onPageSelected(int position) {
- if (position == POSITION_OPEN && mOpenListener != null) {
+ if ((position == POSITION_LEFT_OPEN || position == POSITION_RIGHT_OPEN) && mOpenListener != null) {
mOpenListener.onOpen();
} else if (position == POSITION_CLOSE && mCloseListener != null) {
mCloseListener.onClose();
@@ -125,31 +128,37 @@ public void onPageSelected(int position) {
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.SlidingMenu);
// set the above and behind views if defined in xml
int viewAbove = ta.getResourceId(R.styleable.SlidingMenu_viewAbove, -1);
- if (viewAbove != -1)
+ if (viewAbove != -1) {
setContent(viewAbove);
- int viewBehind = ta.getResourceId(R.styleable.SlidingMenu_viewBehind, -1);
- if (viewBehind != -1)
- setMenu(viewBehind);
- int touchModeAbove = ta.getInt(R.styleable.SlidingMenu_aboveTouchMode, TOUCHMODE_MARGIN);
+ }
+ int viewBehindLeft = ta.getResourceId(R.styleable.SlidingMenu_viewBehindLeft, -1);
+ if (viewBehindLeft != -1) {
+ mMode |= LEFT;
+ setViewBehind(viewBehindLeft, LEFT);
+ }
+ int viewBehindRight = ta.getResourceId(R.styleable.SlidingMenu_viewBehindRight, -1);
+ if (viewBehindRight != -1) {
+ mMode |= RIGHT;
+ setViewBehind(viewBehindRight, RIGHT);
+ }
+ int touchModeAbove = ta.getInt(R.styleable.SlidingMenu_touchModeAbove, TOUCHMODE_MARGIN);
setTouchModeAbove(touchModeAbove);
- int touchModeBehind = ta.getInt(R.styleable.SlidingMenu_behindTouchMode, TOUCHMODE_MARGIN);
+ int touchModeBehind = ta.getInt(R.styleable.SlidingMenu_touchModeBehind, TOUCHMODE_MARGIN);
setTouchModeBehind(touchModeBehind);
-
int offsetBehind = (int) ta.getDimension(R.styleable.SlidingMenu_behindOffset, -1);
int widthBehind = (int) ta.getDimension(R.styleable.SlidingMenu_behindWidth, -1);
- if (offsetBehind != -1 && widthBehind != -1)
+ if (offsetBehind != -1 && widthBehind != -1) {
throw new IllegalStateException("Cannot set both behindOffset and behindWidth for a SlidingMenu");
- else if (offsetBehind != -1)
- setBehindOffset(offsetBehind);
- else if (widthBehind != -1)
- setBehindWidth(widthBehind);
- else
- setBehindOffset(0);
+ } else if (offsetBehind != -1) {
+ setBehindOffset(offsetBehind, mMode);
+ } else if (widthBehind != -1) {
+ setBehindWidth(widthBehind, mMode);
+ }
float scrollOffsetBehind = ta.getFloat(R.styleable.SlidingMenu_behindScrollScale, 0.33f);
- setBehindScrollScale(scrollOffsetBehind);
+ setBehindScrollScale(scrollOffsetBehind, mMode);
int shadowRes = ta.getResourceId(R.styleable.SlidingMenu_shadowDrawable, -1);
if (shadowRes != -1) {
- setShadowDrawable(shadowRes);
+ setShadowDrawable(shadowRes, mMode);
}
int shadowWidth = (int) ta.getDimension(R.styleable.SlidingMenu_shadowWidth, 0);
setShadowWidth(shadowWidth);
@@ -164,6 +173,38 @@ else if (widthBehind != -1)
setSelectorDrawable(selectorRes);
}
+ private void initializeLeft() {
+ if (mViewBehindLeft == null) {
+ LayoutParams behindParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
+ mViewBehindLeft = new CustomViewBehind(getContext(), CustomViewBehind.LEFT);
+ addView(mViewBehindLeft, 0, behindParams);
+ mViewAbove.setViewBehindLeft(mViewBehindLeft);
+ mViewBehindLeft.setCustomViewAbove(mViewAbove);
+ }
+ }
+
+ private void initializeRight() {
+ if (mViewBehindRight == null) {
+ LayoutParams behindParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
+ mViewBehindRight = new CustomViewBehind(getContext(), CustomViewBehind.RIGHT);
+ addView(mViewBehindRight, 0, behindParams);
+ mViewAbove.setViewBehindRight(mViewBehindRight);
+ mViewBehindRight.setCustomViewAbove(mViewAbove);
+ }
+ }
+
+ public void removeViewBehind(int side) {
+ if (isLeft(side)) {
+ mViewAbove.setViewBehindLeft(null);
+ removeView(mViewBehindLeft);
+ mViewBehindLeft = null;
+ } else if (isRight(side)) {
+ mViewAbove.setViewBehindRight(null);
+ removeView(mViewBehindRight);
+ mViewBehindRight = null;
+ }
+ }
+
public void setContent(int res) {
setContent(LayoutInflater.from(getContext()).inflate(res, null));
}
@@ -174,13 +215,54 @@ public void setContent(View v) {
showAbove();
}
- public void setMenu(int res) {
- setMenu(LayoutInflater.from(getContext()).inflate(res, null));
+ public void setViewBehind(int res, int side) {
+ setViewBehind(LayoutInflater.from(getContext()).inflate(res, null), side);
+ }
+
+ public void setViewBehind(View v, int side) {
+ checkSide(side);
+ if (side == LEFT) {
+ initializeLeft();
+ if (v == null) {
+ removeViewBehind(LEFT);
+ } else {
+ initializeLeft();
+ mViewBehindLeft.setContent(v);
+ mViewBehindLeft.invalidate();
+ }
+ } else {
+ initializeRight();
+ if (v == null) {
+ removeViewBehind(RIGHT);
+ } else {
+ initializeRight();
+ mViewBehindRight.setContent(v);
+ mViewBehindRight.invalidate();
+ }
+ }
+ }
+
+ private void checkSide(int side) {
+ if (!isLeft(side) && !isRight(side))
+ throw new IllegalArgumentException("Side must be SlidingMenu.LEFT or SlidingMenu.RIGHT");
+ }
+
+ private void checkSideStrict(int side) {
+ checkSide(side);
+ if (isLeft(side) && mViewBehindLeft == null)
+ throw new IllegalArgumentException("You have to add a behind left " +
+ "view before you can reference it");
+ if (isRight(side) && mViewBehindRight == null)
+ throw new IllegalArgumentException("You have to add a behind right " +
+ "view before you can reference it");
+ }
+
+ private boolean isLeft(int side) {
+ return (side & LEFT) == LEFT;
}
- public void setMenu(View v) {
- mViewBehind.setMenu(v);
- mViewBehind.invalidate();
+ private boolean isRight(int side) {
+ return (side & RIGHT) == RIGHT;
}
public void setSlidingEnabled(boolean b) {
@@ -191,30 +273,20 @@ public boolean isSlidingEnabled() {
return mViewAbove.isSlidingEnabled();
}
- /**
- *
- * @param b Whether or not the SlidingMenu is in a static mode
- * (i.e. nothing is moving and everything is showing)
- */
- public void setStatic(boolean b) {
- if (b) {
- setSlidingEnabled(false);
- mViewAbove.setCustomViewBehind(null);
- mViewAbove.setCurrentItem(1);
- mViewBehind.setCurrentItem(0);
- } else {
- mViewAbove.setCurrentItem(1);
- mViewBehind.setCurrentItem(1);
- mViewAbove.setCustomViewBehind(mViewBehind);
- setSlidingEnabled(true);
- }
- }
-
/**
* Shows the behind view
*/
- public void showBehind() {
- mViewAbove.setCurrentItem(0);
+ public void showBehind(int side) {
+ checkSideStrict(side);
+
+ if (isLeft(side) && isRight(side))
+ throw new IllegalArgumentException("Can't show both left and right");
+
+ if (isLeft(side)) {
+ mViewAbove.setCurrentItem(0);
+ } else if (isRight(side)) {
+ mViewAbove.setCurrentItem(2);
+ }
}
/**
@@ -225,35 +297,64 @@ public void showAbove() {
}
/**
- *
+ *
* @return Whether or not the behind view is showing
*/
public boolean isBehindShowing() {
- return mViewAbove.getCurrentItem() == 0;
+ return mViewAbove.getCurrentItem() == 0 || mViewAbove.getCurrentItem() == 2;
}
/**
- *
+ *
* @return The margin on the right of the screen that the behind view scrolls to
*/
- public int getBehindOffset() {
- return ((RelativeLayout.LayoutParams)mViewBehind.getLayoutParams()).rightMargin;
+ public int getBehindOffset(int side) {
+ checkSideStrict(side);
+ if (isLeft(side)) {
+ return ((RelativeLayout.LayoutParams)mViewBehindLeft.getLayoutParams()).rightMargin;
+ } else {
+ return ((RelativeLayout.LayoutParams)mViewBehindRight.getLayoutParams()).leftMargin;
+ }
}
/**
- *
+ *
* @param i The margin on the right of the screen that the behind view scrolls to
*/
- public void setBehindOffset(int i) {
- RelativeLayout.LayoutParams params = ((RelativeLayout.LayoutParams)mViewBehind.getLayoutParams());
- int bottom = params.bottomMargin;
- int top = params.topMargin;
- int left = params.leftMargin;
- params.setMargins(left, top, i, bottom);
+ public void setBehindOffset(int i, int side) {
+ checkSideStrict(side);
+ if (isLeft(side)) {
+ // behind left
+ RelativeLayout.LayoutParams params = ((RelativeLayout.LayoutParams)mViewBehindLeft.getLayoutParams());
+ int bottom = params.bottomMargin;
+ int top = params.topMargin;
+ int left = params.leftMargin;
+ params.setMargins(left, top, i, bottom);
+ }
+ if (isRight(side)) {
+ // behind right
+ RelativeLayout.LayoutParams params = ((RelativeLayout.LayoutParams)mViewBehindRight.getLayoutParams());
+ int bottom = params.bottomMargin;
+ int top = params.topMargin;
+ int right = params.rightMargin;
+ Log.v(TAG, "left margin" + i);
+ params.setMargins(i, top, right, bottom);
+ }
+ requestLayout();
+ showAbove();
+ }
+
+ /**
+ *
+ * @param res The dimension resource to be set as the behind offset
+ */
+ public void setBehindOffsetRes(int res, int side) {
+ int i = (int) getContext().getResources().getDimension(res);
+ setBehindOffset(i, side);
}
@SuppressWarnings("deprecation")
- public void setBehindWidth(int i) {
+ public void setBehindWidth(int i, int side) {
int width;
Display display = ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay();
@@ -267,37 +368,34 @@ public void setBehindWidth(int i) {
} catch (Exception e) {
width = display.getWidth();
}
- setBehindOffset(width-i);
- }
-
- /**
- *
- * @param res The dimension resource to be set as the behind offset
- */
- public void setBehindOffsetRes(int res) {
- int i = (int) getContext().getResources().getDimension(res);
- setBehindOffset(i);
+ setBehindOffset(width-i, side);
}
/**
- *
+ *
* @return The scale of the parallax scroll
*/
- public float getBehindScrollScale() {
- return mViewAbove.getScrollScale();
+ public float getBehindScrollScale(int side) {
+ return mViewAbove.getScrollScale(side);
}
/**
- *
+ *
* @param f The scale of the parallax scroll (i.e. 1.0f scrolls 1 pixel for every
* 1 pixel that the above view scrolls and 0.0f scrolls 0 pixels)
*/
- public void setBehindScrollScale(float f) {
- mViewAbove.setScrollScale(f);
+ public void setBehindScrollScale(float f, int side) {
+ mViewAbove.setScrollScale(f, side);
}
- public void setBehindCanvasTransformer(CanvasTransformer t) {
- mViewBehind.setCanvasTransformer(t);
+ public void setBehindCanvasTransformer(CanvasTransformer t, int side) {
+ checkSideStrict(side);
+ if (isLeft(side)) {
+ mViewBehindLeft.setCanvasTransformer(t);
+ }
+ if (isRight(side)) {
+ mViewBehindRight.setCanvasTransformer(t);
+ }
}
public int getTouchModeAbove() {
@@ -306,26 +404,26 @@ public int getTouchModeAbove() {
public void setTouchModeAbove(int i) {
if (i != TOUCHMODE_FULLSCREEN && i != TOUCHMODE_MARGIN) {
- throw new IllegalStateException("TouchMode must be set to either" +
+ throw new IllegalArgumentException("TouchMode must be set to either" +
"TOUCHMODE_FULLSCREEN or TOUCHMODE_MARGIN.");
}
mViewAbove.setTouchMode(i);
}
public int getTouchModeBehind() {
- return mViewBehind.getTouchMode();
+ return mViewAbove.getTouchModeBehind();
}
public void setTouchModeBehind(int i) {
if (i != TOUCHMODE_FULLSCREEN && i != TOUCHMODE_MARGIN) {
- throw new IllegalStateException("TouchMode must be set to either" +
+ throw new IllegalArgumentException("TouchMode must be set to either " +
"TOUCHMODE_FULLSCREEN or TOUCHMODE_MARGIN.");
}
- mViewBehind.setTouchMode(i);
+ mViewAbove.setTouchModeBehind(i);
}
- public void setShadowDrawable(int resId) {
- mViewAbove.setShadowDrawable(resId);
+ public void setShadowDrawable(int resId, int side) {
+ mViewAbove.setShadowDrawable(resId, side);
}
public void setShadowWidthRes(int resId) {
@@ -380,6 +478,7 @@ public void setOnClosedListener(OnClosedListener listener) {
private static class SavedState extends BaseSavedState {
boolean mBehindShowing;
+ int mMode;
public SavedState(Parcelable superState) {
super(superState);
@@ -387,7 +486,8 @@ public SavedState(Parcelable superState) {
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
- out.writeBooleanArray(new boolean[]{mBehindShowing});
+ out.writeValue(mBehindShowing);
+ out.writeInt(mMode);
}
public static final Parcelable.Creator CREATOR
@@ -404,9 +504,8 @@ public SavedState[] newArray(int size) {
SavedState(Parcel in) {
super(in);
- boolean[] showing = new boolean[1];
- in.readBooleanArray(showing);
- mBehindShowing = showing[0];
+ mBehindShowing = (Boolean) in.readValue(null);
+ mMode = in.readInt();
}
}
@@ -415,6 +514,7 @@ protected Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState ss = new SavedState(superState);
ss.mBehindShowing = isBehindShowing();
+ ss.mMode = mMode;
return ss;
}
@@ -429,7 +529,7 @@ protected void onRestoreInstanceState(Parcelable state) {
super.onRestoreInstanceState(ss.getSuperState());
if (ss.mBehindShowing) {
- showBehind();
+ showBehind(ss.mMode);
} else {
showAbove();
}
@@ -438,13 +538,14 @@ protected void onRestoreInstanceState(Parcelable state) {
@Override
protected boolean fitSystemWindows(Rect insets) {
- int leftPadding = getPaddingLeft() + insets.left;
- int rightPadding = getPaddingRight() + insets.right;
- int topPadding = getPaddingTop() + insets.top;
- int bottomPadding = getPaddingBottom() + insets.bottom;
- this.setPadding(leftPadding, topPadding, rightPadding, bottomPadding);
+ int leftPadding = getPaddingLeft() + insets.left;
+ int rightPadding = getPaddingRight() + insets.right;
+ int topPadding = insets.top;
+ int bottomPadding = insets.bottom;
+ this.setPadding(leftPadding, topPadding, rightPadding, bottomPadding);
- return super.fitSystemWindows(insets);
+ // return false to propagate the fit to our child views
+ return false;
}
}
\ No newline at end of file
diff --git a/library/src/com/slidingmenu/lib/app/SlidingActivity.java b/library/src/com/slidingmenu/lib/app/SlidingActivity.java
index fb74ec180..88341b1c9 100644
--- a/library/src/com/slidingmenu/lib/app/SlidingActivity.java
+++ b/library/src/com/slidingmenu/lib/app/SlidingActivity.java
@@ -49,32 +49,46 @@ public void setContentView(View v, LayoutParams params) {
mHelper.registerAboveContentView(v, params);
}
- public void setBehindContentView(int id) {
- setBehindContentView(getLayoutInflater().inflate(id, null));
+ // behind left view
+ public void setBehindLeftContentView(int id) {
+ setBehindLeftContentView(getLayoutInflater().inflate(id, null));
}
- public void setBehindContentView(View v) {
- setBehindContentView(v, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
+ public void setBehindLeftContentView(View v) {
+ setBehindLeftContentView(v, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
- public void setBehindContentView(View v, LayoutParams params) {
- mHelper.setBehindContentView(v, params);
+ public void setBehindLeftContentView(View v, LayoutParams params) {
+ mHelper.setBehindLeftContentView(v);
+ }
+
+ // behind right view
+ public void setBehindRightContentView(int id) {
+ setBehindRightContentView(getLayoutInflater().inflate(id, null));
+ }
+
+ public void setBehindRightContentView(View v) {
+ setBehindRightContentView(v, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
+ }
+
+ public void setBehindRightContentView(View v, LayoutParams params) {
+ mHelper.setBehindRightContentView(v);
}
public SlidingMenu getSlidingMenu() {
return mHelper.getSlidingMenu();
}
- public void toggle() {
- mHelper.toggle();
+ public void toggle(int side) {
+ mHelper.toggle(side);
}
public void showAbove() {
mHelper.showAbove();
}
- public void showBehind() {
- mHelper.showBehind();
+ public void showBehind(int side) {
+ mHelper.showBehind(side);
}
public void setSlidingActionBarEnabled(boolean b) {
diff --git a/library/src/com/slidingmenu/lib/app/SlidingActivityBase.java b/library/src/com/slidingmenu/lib/app/SlidingActivityBase.java
index 319b86e75..14f0b4a0a 100644
--- a/library/src/com/slidingmenu/lib/app/SlidingActivityBase.java
+++ b/library/src/com/slidingmenu/lib/app/SlidingActivityBase.java
@@ -7,14 +7,16 @@
public interface SlidingActivityBase {
- public void setBehindContentView(View v, LayoutParams p);
+ public void setBehindLeftContentView(View v, LayoutParams p);
+
+ public void setBehindRightContentView(View v, LayoutParams p);
public SlidingMenu getSlidingMenu();
- public void toggle();
+ public void toggle(int side);
public void showAbove();
- public void showBehind();
+ public void showBehind(int side);
}
diff --git a/library/src/com/slidingmenu/lib/app/SlidingActivityHelper.java b/library/src/com/slidingmenu/lib/app/SlidingActivityHelper.java
index 85ba50fd7..bab2cba8d 100644
--- a/library/src/com/slidingmenu/lib/app/SlidingActivityHelper.java
+++ b/library/src/com/slidingmenu/lib/app/SlidingActivityHelper.java
@@ -19,11 +19,13 @@ public class SlidingActivityHelper {
private SlidingMenu mSlidingMenu;
private View mViewAbove;
- private View mViewBehind;
+ private View mViewBehindLeft;
+ private View mViewBehindRight;
private boolean mBroadcasting = false;
private boolean mOnPostCreateCalled = false;
private boolean mEnableSlide = true;
+ private boolean mUseCustomUp = false;
public SlidingActivityHelper(Activity activity) {
mActivity = activity;
@@ -31,16 +33,21 @@ public SlidingActivityHelper(Activity activity) {
public void onCreate(Bundle savedInstanceState) {
mSlidingMenu = (SlidingMenu) LayoutInflater.from(mActivity).inflate(R.layout.slidingmenumain, null);
+// mActivity.getTheme().applyStyle(R.style.CustomUp, true);
}
public void onPostCreate(Bundle savedInstanceState) {
- if (mViewBehind == null || mViewAbove == null) {
- throw new IllegalStateException("Both setBehindContentView must be called " +
+ if ((mViewBehindLeft == null && mViewBehindRight == null) || mViewAbove == null) {
+ throw new IllegalStateException("Both setBehind[Left|Right]ContentView must be called " +
"in onCreate in addition to setContentView.");
}
+ if (mViewBehindLeft == null)
+ mSlidingMenu.setViewBehind(null, SlidingMenu.LEFT);
+ if (mViewBehindRight == null)
+ mSlidingMenu.setViewBehind(null, SlidingMenu.RIGHT);
mOnPostCreateCalled = true;
-
+
// get the window background
TypedArray a = mActivity.getTheme().obtainStyledAttributes(new int[] {android.R.attr.windowBackground});
int background = a.getResourceId(0, 0);
@@ -75,6 +82,12 @@ public void setSlidingActionBarEnabled(boolean b) {
mEnableSlide = b;
}
+ public void useCustomUpIndicator() {
+ if (mOnPostCreateCalled)
+ throw new IllegalStateException("useCustomUpIndicator must be called in onCreate.");
+ mUseCustomUp = true;
+ }
+
public View findViewById(int id) {
View v;
if (mSlidingMenu != null) {
@@ -95,20 +108,25 @@ public void setContentView(View v) {
mActivity.setContentView(v);
}
- public void setBehindContentView(View v, LayoutParams params) {
- mViewBehind = v;
- mSlidingMenu.setMenu(mViewBehind);
+ public void setBehindLeftContentView(View v) {
+ mViewBehindLeft = v;
+ mSlidingMenu.setViewBehind(mViewBehindLeft, SlidingMenu.LEFT);
+ }
+
+ public void setBehindRightContentView(View v) {
+ mViewBehindRight = v;
+ mSlidingMenu.setViewBehind(mViewBehindRight, SlidingMenu.RIGHT);
}
public SlidingMenu getSlidingMenu() {
return mSlidingMenu;
}
- public void toggle() {
+ public void toggle(int side) {
if (mSlidingMenu.isBehindShowing()) {
showAbove();
} else {
- showBehind();
+ showBehind(side);
}
}
@@ -116,8 +134,8 @@ public void showAbove() {
mSlidingMenu.showAbove();
}
- public void showBehind() {
- mSlidingMenu.showBehind();
+ public void showBehind(int side) {
+ mSlidingMenu.showBehind(side);
}
public boolean onKeyUp(int keyCode, KeyEvent event) {
diff --git a/library/src/com/slidingmenu/lib/app/SlidingFragmentActivity.java b/library/src/com/slidingmenu/lib/app/SlidingFragmentActivity.java
index 8f4651017..cd294654d 100644
--- a/library/src/com/slidingmenu/lib/app/SlidingFragmentActivity.java
+++ b/library/src/com/slidingmenu/lib/app/SlidingFragmentActivity.java
@@ -49,32 +49,46 @@ public void setContentView(View v, LayoutParams params) {
mHelper.registerAboveContentView(v, params);
}
- public void setBehindContentView(int id) {
- setBehindContentView(getLayoutInflater().inflate(id, null));
+ // behind left view
+ public void setBehindLeftContentView(int id) {
+ setBehindLeftContentView(getLayoutInflater().inflate(id, null));
}
- public void setBehindContentView(View v) {
- setBehindContentView(v, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
+ public void setBehindLeftContentView(View v) {
+ setBehindLeftContentView(v, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
- public void setBehindContentView(View v, LayoutParams params) {
- mHelper.setBehindContentView(v, params);
+ public void setBehindLeftContentView(View v, LayoutParams params) {
+ mHelper.setBehindLeftContentView(v);
}
+ // behind right view
+ public void setBehindRightContentView(int id) {
+ setBehindRightContentView(getLayoutInflater().inflate(id, null));
+ }
+
+ public void setBehindRightContentView(View v) {
+ setBehindRightContentView(v, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
+ }
+
+ public void setBehindRightContentView(View v, LayoutParams params) {
+ mHelper.setBehindRightContentView(v);
+ }
+
public SlidingMenu getSlidingMenu() {
return mHelper.getSlidingMenu();
}
- public void toggle() {
- mHelper.toggle();
+ public void toggle(int side) {
+ mHelper.toggle(side);
}
public void showAbove() {
mHelper.showAbove();
}
- public void showBehind() {
- mHelper.showBehind();
+ public void showBehind(int side) {
+ mHelper.showBehind(side);
}
public void setSlidingActionBarEnabled(boolean b) {
diff --git a/library/src/com/slidingmenu/lib/app/SlidingListActivity.java b/library/src/com/slidingmenu/lib/app/SlidingListActivity.java
index 38860653a..3b589d392 100644
--- a/library/src/com/slidingmenu/lib/app/SlidingListActivity.java
+++ b/library/src/com/slidingmenu/lib/app/SlidingListActivity.java
@@ -53,32 +53,46 @@ public void setContentView(View v, LayoutParams params) {
mHelper.registerAboveContentView(v, params);
}
- public void setBehindContentView(int id) {
- setBehindContentView(getLayoutInflater().inflate(id, null));
+ // behind left view
+ public void setBehindLeftContentView(int id) {
+ setBehindLeftContentView(getLayoutInflater().inflate(id, null));
}
- public void setBehindContentView(View v) {
- setBehindContentView(v, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
+ public void setBehindLeftContentView(View v) {
+ setBehindLeftContentView(v, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
- public void setBehindContentView(View v, LayoutParams params) {
- mHelper.setBehindContentView(v, params);
+ public void setBehindLeftContentView(View v, LayoutParams params) {
+ mHelper.setBehindLeftContentView(v);
+ }
+
+ // behind right view
+ public void setBehindRightContentView(int id) {
+ setBehindRightContentView(getLayoutInflater().inflate(id, null));
+ }
+
+ public void setBehindRightContentView(View v) {
+ setBehindRightContentView(v, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
+ }
+
+ public void setBehindRightContentView(View v, LayoutParams params) {
+ mHelper.setBehindRightContentView(v);
}
public SlidingMenu getSlidingMenu() {
return mHelper.getSlidingMenu();
}
- public void toggle() {
- mHelper.toggle();
+ public void toggle(int side) {
+ mHelper.toggle(side);
}
public void showAbove() {
mHelper.showAbove();
}
- public void showBehind() {
- mHelper.showBehind();
+ public void showBehind(int side) {
+ mHelper.showBehind(side);
}
public void setSlidingActionBarEnabled(boolean b) {
diff --git a/library/src/com/slidingmenu/lib/app/SlidingMapActivity.java b/library/src/com/slidingmenu/lib/app/SlidingMapActivity.java
index 27fbea3ef..b2af04af8 100644
--- a/library/src/com/slidingmenu/lib/app/SlidingMapActivity.java
+++ b/library/src/com/slidingmenu/lib/app/SlidingMapActivity.java
@@ -50,32 +50,46 @@ public void setContentView(View v, LayoutParams params) {
mHelper.registerAboveContentView(v, params);
}
- public void setBehindContentView(int id) {
- setBehindContentView(getLayoutInflater().inflate(id, null));
+ // behind left view
+ public void setBehindLeftContentView(int id) {
+ setBehindLeftContentView(getLayoutInflater().inflate(id, null));
}
- public void setBehindContentView(View v) {
- setBehindContentView(v, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
+ public void setBehindLeftContentView(View v) {
+ setBehindLeftContentView(v, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
- public void setBehindContentView(View v, LayoutParams params) {
- mHelper.setBehindContentView(v, params);
+ public void setBehindLeftContentView(View v, LayoutParams params) {
+ mHelper.setBehindLeftContentView(v);
+ }
+
+ // behind right view
+ public void setBehindRightContentView(int id) {
+ setBehindRightContentView(getLayoutInflater().inflate(id, null));
+ }
+
+ public void setBehindRightContentView(View v) {
+ setBehindRightContentView(v, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
+ }
+
+ public void setBehindRightContentView(View v, LayoutParams params) {
+ mHelper.setBehindRightContentView(v);
}
public SlidingMenu getSlidingMenu() {
return mHelper.getSlidingMenu();
}
- public void toggle() {
- mHelper.toggle();
+ public void toggle(int side) {
+ mHelper.toggle(side);
}
public void showAbove() {
mHelper.showAbove();
}
- public void showBehind() {
- mHelper.showBehind();
+ public void showBehind(int side) {
+ mHelper.showBehind(side);
}
public void setSlidingActionBarEnabled(boolean b) {