package com.mapsaurus.paneslayout;
import java.util.List;
import android.content.Context;
import android.graphics.Rect;
import android.view.FocusFinder;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
import android.widget.FrameLayout;
import android.widget.ScrollView;
import android.widget.Scroller;
@SuppressWarnings("unused")
public class SimpleScrollView extends FrameLayout {
private Scroller mScroller;
/**
* True when the layout has changed but the traversal has not come through yet.
* Ideally the view hierarchy would keep track of this for us.
*/
private boolean mIsLayoutDirty = true;
public SimpleScrollView(Context context) {
super(context);
mScroller = new Scroller(context);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
if (widthMode == MeasureSpec.UNSPECIFIED) {
return;
}
if (getChildCount() > 0) {
final View child = getChildAt(0);
int width = getMeasuredWidth();
if (child.getMeasuredWidth() < width) {
final FrameLayout.LayoutParams lp = (LayoutParams) child.getLayoutParams();
int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec,
getPaddingTop() + getPaddingBottom(), lp.height);
width -= getPaddingLeft();
width -= getPaddingRight();
int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}
}
}
@Override
protected void measureChild(View child, int parentWidthMeasureSpec, int parentHeightMeasureSpec) {
ViewGroup.LayoutParams lp = child.getLayoutParams();
int childWidthMeasureSpec;
int childHeightMeasureSpec;
childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec,
getPaddingTop() + getPaddingBottom(), lp.height);
childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}
@Override
protected void measureChildWithMargins(View child, int parentWidthMeasureSpec, int widthUsed,
int parentHeightMeasureSpec, int heightUsed) {
final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec,
getPaddingTop() + getPaddingBottom() + lp.topMargin + lp.bottomMargin
+ heightUsed, lp.height);
final int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
lp.leftMargin + lp.rightMargin, MeasureSpec.UNSPECIFIED);
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}
@Override
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
int oldX = getScrollX();
int oldY = getScrollY();
int x = mScroller.getCurrX();
int y = mScroller.getCurrY();
if (getChildCount() > 0) {
View child = getChildAt(0);
x = clamp(x, getWidth() - getPaddingRight() - getPaddingLeft(), child.getWidth());
y = clamp(y, getHeight() - getPaddingBottom() - getPaddingTop(), child.getHeight());
}
scrollTo(x, y);
if (oldX != getScrollX() || oldY != getScrollY()) {
onScrollChanged(getScrollX(), getScrollY(), oldX, oldY);
}
// Keep on drawing until the animation has finished.
postInvalidate();
}
}
private int clamp(int n, int my, int child) {
if (my >= child || n < 0) {
return 0;
}
if ((my + n) > child) {
return child - my;
}
return n;
}
@Override
public void requestLayout() {
mIsLayoutDirty = true;
super.requestLayout();
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
mIsLayoutDirty = false;
// Calling this with the present values causes it to re-clam them
scrollTo(getScrollX(), getScrollY());
}
public boolean isLayoutDirty() {
return mIsLayoutDirty;
}
/* ************************************************************************
* Edited by Kenrick. Simple smooth scroll!
*/
/**
* Like {@link View#scrollBy}, but scroll smoothly instead of immediately.
*
* @param dx the number of pixels to scroll by on the X axis
* @param dy the number of pixels to scroll by on the Y axis
*/
public final void smoothScrollBy(int dx, int dy) {
mScroller.startScroll(getScrollX(), getScrollY(), dx, dy);
invalidate();
}
/**
* Like {@link #scrollTo}, but scroll smoothly instead of immediately.
*
* @param x the position where to scroll on the X axis
* @param y the position where to scroll on the Y axis
*/
public final void smoothScrollTo(int x, int y) {
smoothScrollBy(x - getScrollX(), y - getScrollY());
}
}