package czd.lib.view.scrollview.observable;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ScrollView;
import java.lang.ref.WeakReference;
public class ObservableScrollView extends ScrollView {
private static final int DEFAULT_ADVANCE_GAP = 150;
private int height = 0;
private int lastY = 0;
private boolean onTop = true, onBottom = true, onStop = true;
private int advance_gap = DEFAULT_ADVANCE_GAP;
private int tall = 0;
private ObservableScrollListener listener = null;
private ScrollHandler handler = new ScrollHandler(this);
public ObservableScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public ObservableScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ObservableScrollView(Context context) {
super(context);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_MOVE)
{
onStop = false;
}
return super.onTouchEvent(ev);
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (listener != null)
{
listener.onScroll(this, l, t, oldl, oldt);
}
handler.sendMessageDelayed(handler.obtainMessage(0, t, oldt), 100);
whereami(t);
}
private void whereami(int t) {
if (t <= advance_gap)
{
if (!onTop && listener != null)
{
onTop = true;
listener.onTop(t);
}
}
else
{
if (onTop && listener != null)
{
onTop = false;
listener.outTop(t);
}
}
if (tall - t - height <= advance_gap)
{
if (!onBottom && listener != null)
{
onBottom = true;
listener.onBottom(t);
}
}
else
{
if (onBottom && listener != null)
{
onBottom = false;
listener.outBottom(t);
}
}
}
public void setAdvanceGap(int gap) {
this.advance_gap = gap;
}
public int getAdvanceGap() {
return this.advance_gap;
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
if (height == 0)
{
height = getHeight();
advance_gap = Math.min(advance_gap, height / 5);
}
else
{
tall = getChildAt(0).getHeight();
whereami(lastY);
}
}
public void setScrollListener(ObservableScrollListener listener) {
this.listener = listener;
}
private static class ScrollHandler extends Handler {
WeakReference<ObservableScrollView> scroll_weak;
public ScrollHandler(ObservableScrollView scroll) {
this.scroll_weak = new WeakReference<ObservableScrollView>(scroll);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
ObservableScrollView scroll = scroll_weak.get();
if (scroll != null)
{
if (!scroll.onStop && msg.arg1 == scroll.lastY)
{
scroll.onStop = true;
if (scroll.listener != null)
{
scroll.listener.onStop(msg.arg1);
}
}
scroll.lastY = scroll.getScrollY();
}
}
}
}