Android ScrollView嵌套WebView

Android中WebView用來加載html頁面,自帶滑動效果。ScrollView同樣也是自帶滑動效果,在項目中如果需要WebView和一些其他view比如TextView一起滑動的話就必須外面嵌套一層ScrollView,這時問題就來了,嵌套之後ScrollView的滑動和WebView的滑動就會有衝突,WebView的滑動不流暢。下面就是解決方案:

第一種方法:我們都知道ScrollView和WebView都有滾動的效果,所以我們需要先屏蔽WebView的滾動事件。
<ScrollView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:descendantFocusability="blocksDescendants" >

這時候如果後端如果傳過來的不是完整的Html,而是隻有body部分的內容,那麼我們就需要補充並添加一些css樣式來達到自適應的效果。

private String getHtmlData(String bodyHTML) {
    String head = "<head>" +
                "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\"> " +
                "<style>img{max-width: 100%; width:auto; height:auto;}</style>" +
                "</head>";
    return "<html>" + head + "<body>" + bodyHTML + "</body></html>";
}

4.0以後引用:

Webview.loadDataWithBaseURL("example-app://example.co.uk/", getHtmlData(String bodyHTML), null, "UTF-8",null);

第二種方法:自定義一個ScrollView



import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ScrollView;

/**
 * Created by Administrator on 2015/12/29 0029.
 */
public class MyScrollView extends ScrollView {
//    private GestureDetector mGestureDetector;
//    View.OnTouchListener mGestureListener;
//
//    public MyScrollView(Context context, AttributeSet attrs) {
//        super(context, attrs);
//        mGestureDetector = new GestureDetector(context, new YScrollDetector());
//        setFadingEdgeLength(0);
//    }
//
//    @Override
//    public boolean onInterceptTouchEvent(MotionEvent ev) {
//        return super.onInterceptTouchEvent(ev) && mGestureDetector.onTouchEvent(ev);
//    }
//
//    // Return false if we're scrolling in the x direction
//    class YScrollDetector extends GestureDetector.SimpleOnGestureListener {
//        @Override
//        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
//            if (Math.abs(distanceY) > Math.abs(distanceX)) {
//                return true;
//            }
//            return false;
//        }
//    }
    /**
     */
    public ScrollView parentScrollView;
    public MyScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    private int lastScrollDelta = 0;
    public void resume() {
        overScrollBy(0, -lastScrollDelta, 0, getScrollY(), 0, getScrollRange(), 0, 0, true);
        lastScrollDelta = 0;
    }
    int mTop = 10;
    /**
     * 將targetView滾到最頂端
     */
    public void scrollTo(View targetView) {
        int oldScrollY = getScrollY();
        int top = targetView.getTop() - mTop;
        int delatY = top - oldScrollY;
        lastScrollDelta = delatY;
        overScrollBy(0, delatY, 0, getScrollY(), 0, getScrollRange(), 0, 0, true);
    }
    private int getScrollRange() {
        int scrollRange = 0;
        if (getChildCount() > 0) {
            View child = getChildAt(0);
            scrollRange = Math.max(0, child.getHeight() - (getHeight()));
        }
        return scrollRange;
    }
    int currentY;
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (parentScrollView == null) {
            return super.onInterceptTouchEvent(ev);
        } else {
            if (ev.getAction() == MotionEvent.ACTION_DOWN) {
// 將父scrollview的滾動事件攔截
                currentY = (int)ev.getY();
                setParentScrollAble(false);
                return super.onInterceptTouchEvent(ev);
            } else if (ev.getAction() == MotionEvent.ACTION_UP) {
// 把滾動事件恢復給父Scrollview
                setParentScrollAble(true);
            } else if (ev.getAction() == MotionEvent.ACTION_MOVE) {
            }
        }
        return super.onInterceptTouchEvent(ev);
    }
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        View child = getChildAt(0);
        if (parentScrollView != null) {
            if (ev.getAction() == MotionEvent.ACTION_MOVE) {
                int height = child.getMeasuredHeight();
                height = height - getMeasuredHeight();
// System.out.println("height=" + height);
                int scrollY = getScrollY();
// System.out.println("scrollY" + scrollY);
                int y = (int)ev.getY();
// 手指向下滑動
                if (currentY < y) {
                    if (scrollY <= 0) {
// 如果向下滑動到頭,就把滾動交給父Scrollview
                        setParentScrollAble(true);
                        return false;
                    } else {
                        setParentScrollAble(false);
                    }
                } else if (currentY > y) {
                    if (scrollY >= height) {
// 如果向上滑動到頭,就把滾動交給父Scrollview
                        setParentScrollAble(true);
                        return false;
                    } else {
                        setParentScrollAble(false);
                    }
                }
                currentY = y;
            }
        }
        return super.onTouchEvent(ev);
    }
    /**
     * 是否把滾動事件交給父scrollview
     *
     * @param flag
     */
    private void setParentScrollAble(boolean flag) {
        parentScrollView.requestDisallowInterceptTouchEvent(!flag);
    }
}



之後就在自己的xml佈局文件裏用MyScrollView代替ScrollView來佈局就ok了。如:
<com.boohee.widgets.MyScrollView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/main_bg"
    android:layout_marginTop="@dimen/default_shadow_margin" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="180dp" >

            <android.support.v4.view.ViewPager
                android:id="@+id/vp_top_show"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent" />

            <LinearLayout
                android:id="@+id/dot_layout"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:gravity="center_horizontal"
                android:orientation="horizontal"
                android:padding="10dp" >
            </LinearLayout>
        </RelativeLayout>

        <WebView
            android:id="@+id/wv_show"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layerType="software"
            android:scrollbars="none" />
    </LinearLayout>
</com.boohee.widgets.MyScrollView>

注意:使用後發現webView加上
android:layerType="software"
之後,有時候加載不出來數據,而且加載數據很慢。所以可以去掉。感謝點擊打開鏈接

webview常見問題彙總http://blog.csdn.net/t12x3456/article/details/13769731




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章