/**
* galaxy inc.
* meetup client for android
*/
package com.galaxy.meetup.client.android.ui.view;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
import android.widget.Scroller;
import com.galaxy.meetup.client.android.R;
/**
*
* @author sihai
*
*/
public abstract class ScrollableViewGroup extends ViewGroup {
private static final Interpolator sInterpolator = new Interpolator() {
public final float getInterpolation(float f) {
float f1 = f - 1.0F;
return 1.0F + f1 * (f1 * (f1 * (f1 * f1)));
}
};
private float mFlingVelocity;
private boolean mFlingable;
private boolean mIsBeingDragged;
private float mLastPosition[] = {
0.0F, 0.0F
};
private final int mLimits[] = {
0x80000001, 0x7fffffff
};
private int mMaximumVelocity;
private int mMinimumVelocity;
private boolean mReceivedDown;
private int mScrollDirection;
private boolean mScrollEnabled;
protected Scroller mScroller;
private int mTouchSlop;
private VelocityTracker mVelocityTracker;
private boolean mVertical;
//===========================================================================
// Constructor
//===========================================================================
public ScrollableViewGroup(Context context) {
super(context);
mFlingVelocity = 0.0F;
mScrollDirection = 0;
mVertical = true;
mFlingable = true;
mIsBeingDragged = false;
mScrollEnabled = true;
mReceivedDown = false;
Context context1 = getContext();
setFocusable(false);
ViewConfiguration viewconfiguration = ViewConfiguration.get(context1);
mTouchSlop = viewconfiguration.getScaledTouchSlop();
mMinimumVelocity = viewconfiguration.getScaledMinimumFlingVelocity();
mMaximumVelocity = viewconfiguration.getScaledMaximumFlingVelocity();
mScroller = new Scroller(context1, sInterpolator);
}
public ScrollableViewGroup(Context context, AttributeSet attributeset) {
super(context, attributeset);
mFlingVelocity = 0.0F;
mScrollDirection = 0;
mVertical = true;
mFlingable = true;
mIsBeingDragged = false;
mScrollEnabled = true;
mReceivedDown = false;
Context context1 = getContext();
setFocusable(false);
ViewConfiguration viewconfiguration = ViewConfiguration.get(context1);
mTouchSlop = viewconfiguration.getScaledTouchSlop();
mMinimumVelocity = viewconfiguration.getScaledMinimumFlingVelocity();
mMaximumVelocity = viewconfiguration.getScaledMaximumFlingVelocity();
mScroller = new Scroller(context1, sInterpolator);
}
public ScrollableViewGroup(Context context, AttributeSet attributeset, int i) {
super(context, attributeset, i);
mFlingVelocity = 0.0F;
mScrollDirection = 0;
mVertical = true;
mFlingable = true;
mIsBeingDragged = false;
mScrollEnabled = true;
mReceivedDown = false;
Context context1 = getContext();
setFocusable(false);
ViewConfiguration viewconfiguration = ViewConfiguration.get(context1);
mTouchSlop = viewconfiguration.getScaledTouchSlop();
mMinimumVelocity = viewconfiguration.getScaledMinimumFlingVelocity();
mMaximumVelocity = viewconfiguration.getScaledMaximumFlingVelocity();
mScroller = new Scroller(context1, sInterpolator);
}
//===========================================================================
// Private function
//===========================================================================
private int clampToScrollLimits(int i) {
if(i >= mLimits[0]) {
if(i > mLimits[1])
i = mLimits[1];
} else {
i = mLimits[0];
}
return i;
}
private boolean shouldStartDrag(MotionEvent motionevent) {
if (!mScrollEnabled) {
return false;
} else {
if (mIsBeingDragged) {
mIsBeingDragged = false;
return false;
} else {
boolean flag1 = false;
switch (motionevent.getAction()) {
case 1: // '\001'
default:
flag1 = false;
break;
case 0: // '\0'
updatePosition(motionevent);
if (!mScroller.isFinished()) {
startDrag();
flag1 = true;
} else {
mReceivedDown = true;
flag1 = false;
}
break;
case 2: // '\002'
float f = motionevent.getX() - mLastPosition[0];
float f1 = motionevent.getY() - mLastPosition[1];
boolean flag2;
boolean flag3;
boolean flag4;
if (f > (float) mTouchSlop || f < (float) (-mTouchSlop))
flag2 = true;
else
flag2 = false;
if (f1 > (float) mTouchSlop || f1 < (float) (-mTouchSlop))
flag3 = true;
else
flag3 = false;
if (mVertical) {
if (flag3 && !flag2)
flag4 = true;
else
flag4 = false;
} else {
if (flag2 && !flag3)
flag4 = true;
else
flag4 = false;
}
flag1 = false;
if (flag4) {
updatePosition(motionevent);
startDrag();
flag1 = true;
}
break;
}
return flag1;
}
}
}
private void startDrag() {
mIsBeingDragged = true;
mFlingVelocity = 0.0F;
mScrollDirection = 0;
mScroller.abortAnimation();
}
//===========================================================================
// Protected function
//===========================================================================
protected final void updatePosition(MotionEvent motionevent) {
mLastPosition[0] = motionevent.getX();
mLastPosition[1] = motionevent.getY();
}
protected final void scrollTo(int i) {
if(mVertical)
scrollTo(0, clampToScrollLimits(i));
else
scrollTo(clampToScrollLimits(i), 0);
}
//===========================================================================
// Public function
//===========================================================================
public void addView(View view)
{
View view1 = view.findViewById(R.id.list_layout_parent);
if(null != view1) {
int i = ((Integer)view1.getTag()).intValue();
int j = getChildCount();
int k = 0;
boolean flag = false;
while(k < j) {
if(((Integer)getChildAt(k).findViewById(R.id.list_layout_parent).getTag()).intValue() <= i) {
k++;
} else {
addView(view, k);
flag = true;
if(!flag)
super.addView(view);
return;
}
}
if(!flag)
super.addView(view);
}
}
public void computeScroll() {
if(mScroller.computeScrollOffset()) {
int i;
int j;
if(mVertical)
i = mScroller.getCurrY();
else
i = mScroller.getCurrX();
scrollTo(i);
invalidate();
if(mVertical)
j = mScroller.getFinalY();
else
j = mScroller.getFinalX();
if(i == j)
mScroller.abortAnimation();
if(mFlingVelocity != 0.0F) {
int k;
if(mFlingVelocity > 0.0F)
k = 1;
else
k = -1;
mFlingVelocity = 0.0F;
onScrollFinished(k);
}
}
}
public final int getScroll() {
if(mVertical)
return getScrollY();
else
return getScrollX();
}
public boolean onInterceptTouchEvent(MotionEvent motionevent) {
return shouldStartDrag(motionevent);
}
protected void onScrollFinished(int i) {
}
public boolean onTouchEvent(MotionEvent motionevent) {
int i = motionevent.getAction();
if(mFlingable) {
if(mVelocityTracker == null)
mVelocityTracker = VelocityTracker.obtain();
mVelocityTracker.addMovement(motionevent);
}
if(!mIsBeingDragged) {
boolean flag1;
if(shouldStartDrag(motionevent)) {
flag1 = true;
} else {
if(i == 1 && mReceivedDown) {
mReceivedDown = false;
flag1 = performClick();
} else {
flag1 = true;
}
}
return flag1;
} else {
switch(i) {
default:
return true;
case 1:
case 3:
boolean flag;
if(i == 3)
flag = true;
else
flag = false;
mIsBeingDragged = false;
if(!flag && mFlingable && getChildCount() > 0) {
mVelocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
float f;
if(mVertical)
f = mVelocityTracker.getYVelocity();
else
f = mVelocityTracker.getXVelocity();
if(f > (float)mMinimumVelocity || f < (float)(-mMinimumVelocity)) {
float f1 = -f;
mFlingVelocity = f1;
int j = getScrollX();
int k = getScrollY();
if(mVertical)
mScroller.fling(j, k, 0, (int)f1, 0, 0, mLimits[0], mLimits[1]);
else
mScroller.fling(j, k, (int)f1, 0, mLimits[0], mLimits[1], 0, 0);
invalidate();
} else {
onScrollFinished(mScrollDirection);
}
} else {
onScrollFinished(mScrollDirection);
}
if(mFlingable && mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
mReceivedDown = false;
return true;
case 2:
int l;
float f2;
float f3;
if(mVertical)
l = 1;
else
l = 0;
f2 = mLastPosition[l];
updatePosition(motionevent);
f3 = f2 - mLastPosition[l];
if(f3 < -1F)
mScrollDirection = -1;
else
if(f3 > 1.0F)
mScrollDirection = 1;
scrollTo(getScroll() + (int)f3);
mReceivedDown = false;
return true;
}
}
}
public void setFlingable(boolean flag) {
mFlingable = flag;
}
public void setScrollEnabled(boolean flag) {
mScrollEnabled = flag;
}
public void setScrollLimits(int i, int j) {
mLimits[0] = i;
mLimits[1] = j;
}
public void setVertical(boolean flag) {
mVertical = flag;
}
public boolean showContextMenuForChild(View view) {
requestDisallowInterceptTouchEvent(true);
return super.showContextMenuForChild(view);
}
public final void smoothScrollTo(int i) {
int j = clampToScrollLimits(i) - getScroll();
if(mVertical)
mScroller.startScroll(0, getScrollY(), 0, j, 500);
else
mScroller.startScroll(getScrollX(), 0, j, 0, 500);
invalidate();
}
}