package com.jeremyfeinstein.slidingmenu.lib; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.Log; import android.util.TypedValue; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu.CanvasTransformer; public class CustomViewBehind extends ViewGroup { private static final String TAG = "CustomViewBehind"; //��Ե�������ٽ�ֵ private static final int MARGIN_THRESHOLD = 48; // dips //��ʼ��������ģʽ private int mTouchMode = SlidingMenu.TOUCHMODE_MARGIN; //�����Ϸ���ͼ private CustomViewAbove mViewAbove; //����������ͼ private View mContent; private View mSecondaryContent; //���廬����Ե���ٽ�ֵ private int mMarginThreshold; //��ȵ�ƫ���� private int mWidthOffset; private CanvasTransformer mTransformer; //�Ƿ��ܹ�ʹ������ͼ private boolean mChildrenEnabled; public CustomViewBehind(Context context) { this(context, null); } public CustomViewBehind(Context context, AttributeSet attrs) { super(context, attrs); mMarginThreshold = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, MARGIN_THRESHOLD, getResources().getDisplayMetrics()); } public void setCustomViewAbove(CustomViewAbove customViewAbove) { mViewAbove = customViewAbove; } public void setCanvasTransformer(CanvasTransformer t) { mTransformer = t; } /** * ���ÿ�ȵ�ƫ���� */ public void setWidthOffset(int i) { mWidthOffset = i; requestLayout(); } /** * ���ñ�Ե�������ٽ�ֵ */ public void setMarginThreshold(int marginThreshold) { mMarginThreshold = marginThreshold; } /** * �õ���Ե�������ٽ�ֵ */ public int getMarginThreshold() { return mMarginThreshold; } /** * �õ���ͼ�Ŀ�� */ public int getBehindWidth() { return mContent.getWidth(); } /** * ������ͼ������ */ public void setContent(View v) { if (mContent != null) removeView(mContent); mContent = v; addView(mContent); } /** * �õ���ͼ������ */ public View getContent() { return mContent; } /** * �����ұ߻����˵������ݣ���ģʽ����ΪLEFT_RIGHTģʽʱ */ public void setSecondaryContent(View v) { if (mSecondaryContent != null) removeView(mSecondaryContent); mSecondaryContent = v; addView(mSecondaryContent); } /** * �õ��ұ߻����˵������� */ public View getSecondaryContent() { return mSecondaryContent; } /** * �����Ƿ��ܹ�ʹ������ͼ */ public void setChildrenEnabled(boolean enabled) { mChildrenEnabled = enabled; } @Override public void scrollTo(int x, int y) { super.scrollTo(x, y); if (mTransformer != null) invalidate(); } @Override public boolean onInterceptTouchEvent(MotionEvent e) { return !mChildrenEnabled; } @Override public boolean onTouchEvent(MotionEvent e) { return !mChildrenEnabled; } @Override protected void dispatchDraw(Canvas canvas) { if (mTransformer != null) { canvas.save(); mTransformer.transformCanvas(canvas, mViewAbove.getPercentOpen()); super.dispatchDraw(canvas); canvas.restore(); } else super.dispatchDraw(canvas); } @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-mWidthOffset, height); if (mSecondaryContent != null) mSecondaryContent.layout(0, 0, width-mWidthOffset, height); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = getDefaultSize(0, widthMeasureSpec); int height = getDefaultSize(0, heightMeasureSpec); setMeasuredDimension(width, height); final int contentWidth = getChildMeasureSpec(widthMeasureSpec, 0, width-mWidthOffset); final int contentHeight = getChildMeasureSpec(heightMeasureSpec, 0, height); mContent.measure(contentWidth, contentHeight); if (mSecondaryContent != null) mSecondaryContent.measure(contentWidth, contentHeight); } //����ģʽ��ֵ private int mMode; //�Ƿ��ܹ�ʹ�ý��뽥��Ч�� private boolean mFadeEnabled; //���彥�뽥����ֵ private float mFadeDegree; //���彥�뽥��Ч������ private final Paint mFadePaint = new Paint(); //���廬�����ŵ�ֵ private float mScrollScale; //���廬���˵�����Ӱ private Drawable mShadowDrawable; //�����ұ߻����˵�����ӰͼƬ private Drawable mSecondaryShadowDrawable; //������Ӱ�Ŀ�� private int mShadowWidth; /** * ����ģʽ��ֵ */ public void setMode(int mode) { if (mode == SlidingMenu.LEFT || mode == SlidingMenu.RIGHT) { if (mContent != null) mContent.setVisibility(View.VISIBLE); if (mSecondaryContent != null) mSecondaryContent.setVisibility(View.INVISIBLE); } mMode = mode; } /** * �õ�ģʽ��ֵ */ public int getMode() { return mMode; } /** * ���û������ŵ�ֵ */ public void setScrollScale(float scrollScale) { mScrollScale = scrollScale; } /** * �õ��������ŵ�ֵ */ public float getScrollScale() { return mScrollScale; } /** * ���û����˵�����Ӱ */ public void setShadowDrawable(Drawable shadow) { mShadowDrawable = shadow; invalidate(); } /** * �����ұ߻����˵�����Ӱ */ public void setSecondaryShadowDrawable(Drawable shadow) { mSecondaryShadowDrawable = shadow; invalidate(); } /** * ������Ӱ�Ŀ�� */ public void setShadowWidth(int width) { mShadowWidth = width; invalidate(); } /** * �����ܷ�ʹ�ý��뽥��Ч�� */ public void setFadeEnabled(boolean b) { mFadeEnabled = b; } /** * ���ý��뽥����ֵ */ public void setFadeDegree(float degree) { if (degree > 1.0f || degree < 0.0f) throw new IllegalStateException("The BehindFadeDegree must be between 0.0f and 1.0f"); mFadeDegree = degree; } /** * �õ��˵�ҳ�� */ public int getMenuPage(int page) { page = (page > 1) ? 2 : ((page < 1) ? 0 : page); if (mMode == SlidingMenu.LEFT && page > 1) { return 0; } else if (mMode == SlidingMenu.RIGHT && page < 1) { return 2; } else { return page; } } /** * �����·���ͼ�����λ�� */ public void scrollBehindTo(View content, int x, int y) { int vis = View.VISIBLE; if (mMode == SlidingMenu.LEFT) { if (x >= content.getLeft()) vis = View.INVISIBLE; scrollTo((int)((x + getBehindWidth())*mScrollScale), y); } else if (mMode == SlidingMenu.RIGHT) { if (x <= content.getLeft()) vis = View.INVISIBLE; scrollTo((int)(getBehindWidth() - getWidth() + (x-getBehindWidth())*mScrollScale), y); } else if (mMode == SlidingMenu.LEFT_RIGHT) { mContent.setVisibility(x >= content.getLeft() ? View.INVISIBLE : View.VISIBLE); mSecondaryContent.setVisibility(x <= content.getLeft() ? View.INVISIBLE : View.VISIBLE); vis = x == 0 ? View.INVISIBLE : View.VISIBLE; if (x <= content.getLeft()) { scrollTo((int)((x + getBehindWidth())*mScrollScale), y); } else { scrollTo((int)(getBehindWidth() - getWidth() + (x-getBehindWidth())*mScrollScale), y); } } if (vis == View.INVISIBLE) Log.v(TAG, "behind INVISIBLE"); setVisibility(vis); } /** * �õ���߲˵�����ͼ */ public int getMenuLeft(View content, int page) { if (mMode == SlidingMenu.LEFT) { switch (page) { case 0: return content.getLeft() - getBehindWidth(); case 2: return content.getLeft(); } } else if (mMode == SlidingMenu.RIGHT) { switch (page) { case 0: return content.getLeft(); case 2: return content.getLeft() + getBehindWidth(); } } else if (mMode == SlidingMenu.LEFT_RIGHT) { switch (page) { case 0: return content.getLeft() - getBehindWidth(); case 2: return content.getLeft() + getBehindWidth(); } } return content.getLeft(); } /** * �õ���߿���ͼ */ public int getAbsLeftBound(View content) { if (mMode == SlidingMenu.LEFT || mMode == SlidingMenu.LEFT_RIGHT) { return content.getLeft() - getBehindWidth(); } else if (mMode == SlidingMenu.RIGHT) { return content.getLeft(); } return 0; } /** * �õ��ұ߿���ͼ */ public int getAbsRightBound(View content) { if (mMode == SlidingMenu.LEFT) { return content.getLeft(); } else if (mMode == SlidingMenu.RIGHT || mMode == SlidingMenu.LEFT_RIGHT) { return content.getLeft() + getBehindWidth(); } return 0; } /** * �Ƿ���������Ļ�ı�Ե */ public boolean marginTouchAllowed(View content, int x) { int left = content.getLeft(); int right = content.getRight(); if (mMode == SlidingMenu.LEFT) { return (x >= left && x <= mMarginThreshold + left); } else if (mMode == SlidingMenu.RIGHT) { return (x <= right && x >= right - mMarginThreshold); } else if (mMode == SlidingMenu.LEFT_RIGHT) { return (x >= left && x <= mMarginThreshold + left) || (x <= right && x >= right - mMarginThreshold); } return false; } /** * ���ô���ģʽ��ֵ */ public void setTouchMode(int i) { mTouchMode = i; } /** * �Ƿ�����ͨ�������򿪻����˵� */ public boolean menuOpenTouchAllowed(View content, int currPage, float x) { switch (mTouchMode) { case SlidingMenu.TOUCHMODE_FULLSCREEN: return true; case SlidingMenu.TOUCHMODE_MARGIN: return menuTouchInQuickReturn(content, currPage, x); } return false; } /** * �����˵����ٷ��� */ public boolean menuTouchInQuickReturn(View content, int currPage, float x) { if (mMode == SlidingMenu.LEFT || (mMode == SlidingMenu.LEFT_RIGHT && currPage == 0)) { return x >= content.getLeft(); } else if (mMode == SlidingMenu.RIGHT || (mMode == SlidingMenu.LEFT_RIGHT && currPage == 2)) { return x <= content.getRight(); } return false; } /** * �Ƿ�����رջ����˵� */ public boolean menuClosedSlideAllowed(float dx) { if (mMode == SlidingMenu.LEFT) { return dx > 0; } else if (mMode == SlidingMenu.RIGHT) { return dx < 0; } else if (mMode == SlidingMenu.LEFT_RIGHT) { return true; } return false; } /** * �Ƿ�����򿪻����˵� */ public boolean menuOpenSlideAllowed(float dx) { if (mMode == SlidingMenu.LEFT) { return dx < 0; } else if (mMode == SlidingMenu.RIGHT) { return dx > 0; } else if (mMode == SlidingMenu.LEFT_RIGHT) { return true; } return false; } /** * �������˵�����Ӱ */ public void drawShadow(View content, Canvas canvas) { if (mShadowDrawable == null || mShadowWidth <= 0) return; int left = 0; if (mMode == SlidingMenu.LEFT) { left = content.getLeft() - mShadowWidth; } else if (mMode == SlidingMenu.RIGHT) { left = content.getRight(); } else if (mMode == SlidingMenu.LEFT_RIGHT) { if (mSecondaryShadowDrawable != null) { left = content.getRight(); mSecondaryShadowDrawable.setBounds(left, 0, left + mShadowWidth, getHeight()); mSecondaryShadowDrawable.draw(canvas); } left = content.getLeft() - mShadowWidth; } mShadowDrawable.setBounds(left, 0, left + mShadowWidth, getHeight()); mShadowDrawable.draw(canvas); } /** * �������뽥��Ч�� */ public void drawFade(View content, Canvas canvas, float openPercent) { if (!mFadeEnabled) return; final int alpha = (int) (mFadeDegree * 255 * Math.abs(1-openPercent)); mFadePaint.setColor(Color.argb(alpha, 0, 0, 0)); int left = 0; int right = 0; if (mMode == SlidingMenu.LEFT) { left = content.getLeft() - getBehindWidth(); right = content.getLeft(); } else if (mMode == SlidingMenu.RIGHT) { left = content.getRight(); right = content.getRight() + getBehindWidth(); } else if (mMode == SlidingMenu.LEFT_RIGHT) { left = content.getLeft() - getBehindWidth(); right = content.getLeft(); canvas.drawRect(left, 0, right, getHeight(), mFadePaint); left = content.getRight(); right = content.getRight() + getBehindWidth(); } canvas.drawRect(left, 0, right, getHeight(), mFadePaint); } private boolean mSelectorEnabled = true; private Bitmap mSelectorDrawable; private View mSelectedView; public void drawSelector(View content, Canvas canvas, float openPercent) { if (!mSelectorEnabled) return; if (mSelectorDrawable != null && mSelectedView != null) { String tag = (String) mSelectedView.getTag(R.id.selected_view); if (tag.equals(TAG+"SelectedView")) { canvas.save(); int left, right, offset; offset = (int) (mSelectorDrawable.getWidth() * openPercent); if (mMode == SlidingMenu.LEFT) { right = content.getLeft(); left = right - offset; canvas.clipRect(left, 0, right, getHeight()); canvas.drawBitmap(mSelectorDrawable, left, getSelectorTop(), null); } else if (mMode == SlidingMenu.RIGHT) { left = content.getRight(); right = left + offset; canvas.clipRect(left, 0, right, getHeight()); canvas.drawBitmap(mSelectorDrawable, right - mSelectorDrawable.getWidth(), getSelectorTop(), null); } canvas.restore(); } } } public void setSelectorEnabled(boolean b) { mSelectorEnabled = b; } public void setSelectedView(View v) { if (mSelectedView != null) { mSelectedView.setTag(R.id.selected_view, null); mSelectedView = null; } if (v != null && v.getParent() != null) { mSelectedView = v; mSelectedView.setTag(R.id.selected_view, TAG+"SelectedView"); invalidate(); } } private int getSelectorTop() { int y = mSelectedView.getTop(); y += (mSelectedView.getHeight() - mSelectorDrawable.getHeight()) / 2; return y; } public void setSelectorBitmap(Bitmap b) { mSelectorDrawable = b; refreshDrawableState(); } }