package net.avenwu.support.widget;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import android.widget.ScrollView;
import android.widget.Scroller;
import net.avenwu.support.R;
public class DrawerFrameV2 extends FrameLayout {
View mLeftView;
View mContentView;
Scroller mScroller;
float mSrcX;
int mLeftViewWidth;
boolean isSliding = false;
boolean mSlidable = true;
int mTouchSlop;
public DrawerFrameV2(Context context) {
this(context, null);
}
public DrawerFrameV2(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public DrawerFrameV2(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs, defStyle);
}
private void init(AttributeSet attrs, int defStyle) {
mScroller = new Scroller(getContext(), new Interpolator() {
@Override
public float getInterpolation(float input) {
return (float) (1.0D + Math.pow(input - 1.0D, 5.0D));
}
});
mLeftViewWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 200,
getResources().getDisplayMetrics());
ViewConfiguration configuration = ViewConfiguration.get(getContext());
mTouchSlop = configuration.getScaledTouchSlop();
mShadowLeft = getResources().getDrawable(android.R.drawable.ic_media_play);
}
@Override
protected void onFinishInflate() {
int count = getChildCount();
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
if (child.getId() == R.id.menu) {
mLeftView = child;
} else if (child.getId() == R.id.main) {
mContentView = child;
}
}
if (mLeftView == null) {
mLeftView = new FrameLayout(getContext());
mLeftView.setId(R.id.menu);
mLeftView.setLayoutParams(new LayoutParams(mLeftViewWidth, ViewGroup.LayoutParams.MATCH_PARENT));
mLeftView.setBackgroundColor(0xff669900);
addView(mLeftView);
}
if (mContentView == null) {
mContentView = new FrameLayout(getContext());
mContentView.setId(R.id.main);
mContentView.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
mContentView.setBackgroundColor(0xffff8800);
addView(mContentView);
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (!mSlidable) return false;
final int action = ev.getAction();
if (action != MotionEvent.ACTION_DOWN && isSliding) return true;
switch (action) {
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
return false;
case MotionEvent.ACTION_MOVE:
if (Math.abs(ev.getX() - mSrcX) > mTouchSlop) {
mSrcX = ev.getX();
isSliding = true;
}
break;
case MotionEvent.ACTION_DOWN:
isSliding = false;
mSrcX = ev.getX();
break;
}
return isSliding;
}
public void setSlide(boolean enable) {
mSlidable = enable;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
d("UIView", "event:" + event.toString());
final int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
mSrcX = event.getX();
// TODO after left menu drag outside screen, the menu is somewhat invisible while drag in again?
mLeftView.setVisibility(VISIBLE);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
float dx = event.getX() - mSrcX;
int x = mLeftView.getLeft();
if (dx != 0) {
if (dx + x > 0) {
dx = 0 - x;
}
mLeftView.offsetLeftAndRight((int) dx);
mSrcX = event.getX();
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
int currentX = mLeftView.getLeft();
if (currentX + event.getX() - mSrcX >= -mLeftViewWidth / 2.0) {
int duration = (int) (Math.abs(0 - currentX + 0.5f) / mLeftViewWidth * 1000);
mScroller.startScroll(currentX, 0, 0 - currentX, 0, duration);
} else {
int duration = (int) (Math.abs(-mLeftViewWidth - currentX + 0.5f) / mLeftViewWidth * 1000);
mScroller.startScroll(currentX, 0, -mLeftViewWidth - currentX, 0, duration);
}
invalidate();
break;
}
return true;
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
int count = getChildCount();
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
if (child.getVisibility() == GONE) continue;
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
if (child.getId() == R.id.menu) {
final int childWidth = child.getMeasuredWidth();
final int childHeight = child.getMeasuredHeight();
int childLeft = 0;
child.layout(childLeft, lp.topMargin, childLeft + childWidth, lp.topMargin + childHeight);
child.offsetLeftAndRight(-mLeftViewWidth);
} else if (child.getId() == R.id.main) {
child.layout(0, 0, child.getMeasuredWidth(), child.getMeasuredHeight());
}
}
}
Drawable mShadowLeft;// = new ColorDrawable(Color.RED);
private static final int DEFAULT_SCRIM_COLOR = 0x99000000;
private int mScrimColor = DEFAULT_SCRIM_COLOR;
private float mScrimOpacity;
private Paint mScrimPaint = new Paint();
float alpha;
/* @Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
boolean result = super.drawChild(canvas, child, drawingTime);
if (child.getId() == R.id.main) {
int clipLeft = 0, clipRight = getWidth();
final int baseAlpha = (mScrimColor & 0xff000000) >>> 24;
// final int imag = (int) (baseAlpha * mScrimOpacity);
// final int color = imag << 24 | (mScrimColor & 0xffffff);
mScrimPaint.setColor(Color.argb((int) (255 * alpha * 0xff), 0, 0, 0));
canvas.drawRect(clipLeft, 0, clipRight, getHeight(), mScrimPaint);
} else if (child.getId() == R.id.menu) {
final int shadowWidth = mShadowLeft.getIntrinsicWidth();
final int childRight = child.getRight();
final int drawerPeekDistance = mLeftViewWidth;
alpha =
Math.max(0, Math.min((float) childRight / drawerPeekDistance, 1.f));
mShadowLeft.setBounds(childRight, child.getTop(),
childRight + shadowWidth, child.getBottom());
mShadowLeft.setAlpha((int) (0xff * alpha));
mShadowLeft.draw(canvas);
}
return result;
}*/
boolean isContentView(View child) {
return ((LayoutParams) child.getLayoutParams()).gravity == Gravity.NO_GRAVITY;
}
boolean isDrawerView(View child) {
final int gravity = ((LayoutParams) child.getLayoutParams()).gravity;
// final int absGravity = GravityCompat.getAbsoluteGravity(gravity,
// ViewCompat.getLayoutDirection(child));
// return (absGravity & (Gravity.LEFT | Gravity.RIGHT)) != 0;
return gravity == Gravity.LEFT || gravity == Gravity.RIGHT;
}
public void showMenuSmoothly() {
mScroller.startScroll(mLeftViewWidth, 0, -mLeftViewWidth, 0, 1000);
invalidate();
}
public void dismissSmoothly() {
int start = mScroller.getCurrX();
mScroller.startScroll(start, 0, mLeftViewWidth - start, 0, 1000);
invalidate();
}
public void setMenuView(View view) {
if (mLeftView instanceof ViewGroup) {
((ViewGroup) mLeftView).removeAllViews();
((ViewGroup) mLeftView).addView(view);
requestLayout();
}
}
public void setContentView(View view) {
if (mContentView instanceof ViewGroup) {
((ViewGroup) mContentView).removeAllViews();
((ViewGroup) mContentView).addView(view);
requestLayout();
}
}
@Override
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
int oldLeft = mLeftView.getLeft();
int left = mScroller.getCurrX();
if (oldLeft != mScroller.getFinalX()) {
int xOffset = left - oldLeft;
int dx = xOffset + oldLeft;
if (dx > 0) {
xOffset = 0 - oldLeft;
} else if (dx < -mLeftViewWidth) {
xOffset = -mLeftViewWidth - oldLeft;
}
mLeftView.offsetLeftAndRight(xOffset);
onScrollChanged(left, 0, oldLeft, 0);
}
invalidate();
} else {
mScroller.abortAnimation();
}
}
private void d(String tag, String text) {
// if (BuildConfig.DEBUG) {
Log.d(tag, text);
// }
}
/**
* This is called in response to an internal scroll in this view (i.e., the
* view scrolled its own contents). This is typically as a result of
* {@link #scrollBy(int, int)} or {@link #scrollTo(int, int)} having been
* called.
*
* @param l Current horizontal scroll origin.
* @param t Current vertical scroll origin.
* @param oldl Previous horizontal scroll origin.
* @param oldt Previous vertical scroll origin.
*/
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
}
}