/* * Copyright (c) 2014. Marshal Chen. */ package com.marshalchen.common.uimodule.fadingactionbar.view; import android.content.Context; import android.graphics.Canvas; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.webkit.WebView; /** * Adapted from: http://stackoverflow.com/a/14753235/244576 and http://stackoverflow.com/a/11442374/244576 */ public class ObservableWebViewWithHeader extends WebView implements ObservableScrollable { private OnScrollChangedCallback mOnScrollChangedCallback; public ObservableWebViewWithHeader(Context context) { super(context); } public ObservableWebViewWithHeader(Context context, AttributeSet attrs) { super(context, attrs); } public ObservableWebViewWithHeader(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } /* * Header */ private int headerHeight; @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){ super.onMeasure(widthMeasureSpec, heightMeasureSpec); // determine height of title bar View title = getChildAt(0); headerHeight = title==null ? 0 : title.getMeasuredHeight(); } @Override public boolean onInterceptTouchEvent(MotionEvent ev){ return true; // don't pass our touch events to children (title bar), we send these in dispatchTouchEvent } private boolean touchInHeader; @Override public boolean dispatchTouchEvent(MotionEvent me){ boolean wasInTitle = false; switch(me.getActionMasked()){ case MotionEvent.ACTION_DOWN: touchInHeader = (me.getY() <= visibleHeaderHeight()); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: wasInTitle = touchInHeader; touchInHeader = false; break; } if (touchInHeader || wasInTitle) { View title = getChildAt(0); if(title!=null) { // this touch belongs to title bar, dispatch it here me.offsetLocation(0, getScrollY()); return title.dispatchTouchEvent(me); } } // this is our touch, offset and process me.offsetLocation(0, -headerHeight); return super.dispatchTouchEvent(me); } /** * @return visible height of title (may return negative values) */ private int visibleHeaderHeight(){ return headerHeight-getScrollY(); } @Override protected void onDraw(Canvas c){ c.save(); int tH = visibleHeaderHeight(); if(tH > 0) { // clip so that it doesn't clear background under title bar int sx = getScrollX(), sy = getScrollY(); c.clipRect(sx, sy+tH, sx+getWidth(), sy+getHeight()); } c.translate(0, headerHeight); super.onDraw(c); c.restore(); } /* * Scroll */ @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); View title = getChildAt(0); if (title != null) // undo horizontal scroll, so that title scrolls only vertically title.offsetLeftAndRight(l - title.getLeft()); if (mOnScrollChangedCallback != null) mOnScrollChangedCallback.onScroll(l, t); } public OnScrollChangedCallback getOnScrollChangedCallback() { return mOnScrollChangedCallback; } @Override public void setOnScrollChangedCallback(OnScrollChangedCallback callback) { mOnScrollChangedCallback = callback; } }