mars3142
mars3142

Reputation: 2561

Android WebView inside ListView

I have a WebView inside a ListView. Everything works fine, except that I can't block the ListView from scrolling up/down, if the WebView handles the scroll gesture.

I know, that I can completely block scrolling of the ListView with following code in the OnTouchListener

@Override
public boolean onTouch(View v, MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_UP) {
        webView.getParent().requestDisallowInterceptTouchEvent(false);
    } else {
        webView.getParent().requestDisallowInterceptTouchEvent(true);
    }
}

but I only want to block it, while the WebViewdidn't handle the scroll/touch gesture.

Eg. I have two HTML-pages. One shows a 360 View of a location. This WebView should block scrolling of the parent completely, while the second WebView is just text. The page would not handle the touch events and therefore, the parent ListView can scroll.

PS: The HTML is not written by myself and can't be modified.

Upvotes: 1

Views: 4550

Answers (4)

Youngjae
Youngjae

Reputation: 25050

Followed by @mars3142, below code shows and allows to scroll more like a webpage shown in the browser.

public class InnerScrollWebView extends WebView {

    private Boolean enableScroll = true;

    public InnerScrollWebView(Context context, AttributeSet attrs){
        super(context, attrs);
        getSettings().setDomStorageEnabled(true);
        getSettings().setJavaScriptEnabled(true);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE) {
            enableScroll = true;
        }
        if (getParent() != null) {
            getParent().requestDisallowInterceptTouchEvent(enableScroll);
        }
        return super.onTouchEvent(event);
    }

    @Override
    protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
        if (getParent() != null) {
            enableScroll = false;
        }
        super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
    }
}

Upvotes: 2

mars3142
mars3142

Reputation: 2561

I resolved it by creating a custom WebView and it seems to work really good.

public class CustomWebView extends WebView {

    private Boolean enableScroll = true;

    public CustomWebView(Context context, AttributeSet attrs){
        super(context, attrs);
    }

    public CustomWebView(Context context, AttributeSet attrs, int defStyleAttr){
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            enableScroll = true;
        }
        if (getParent() != null) {
            getParent().requestDisallowInterceptTouchEvent(enableScroll);
        }
        return super.onTouchEvent(event);
    }

    @Override
    protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
        if (getParent() != null) {
            enableScroll = false;
        }
        super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
    }
}

Upvotes: 0

Parminder ghuman
Parminder ghuman

Reputation: 1

I have just override the on touch event

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.android.gms.internal.ev;
import com.google.android.gms.internal.ol;
import com.notifyme.R;
import com.notifyme.test.InteractiveScrollView;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.AbsListView;
import android.widget.Adapter;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.ScrollView;

public class TestActivity extends Activity {

    ListView listView;
    Map<Integer, List<Float>>  map = new HashMap<Integer, List<Float>>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.test_activity);
        listView = (ListView) findViewById(R.id.lv_test);

        MyAdapter adapter = new MyAdapter(this, R.layout.test_activity);
        List<String> strings = new ArrayList<String>();
        strings.add("http://youtube.com");
        strings.add("https://google.com");
        strings.add("http://www.tutorialspoint.com/");
        strings.add("http://stackoverflow.com/");
        adapter.addAll(strings);
        listView.setAdapter(adapter);
    }

    private class MyAdapter extends ArrayAdapter<String> {

        public MyAdapter(Context context, int textViewResourceId) {
            super(context, textViewResourceId);
            // TODO Auto-generated constructor stub
        }

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {

            /*
             * RelativeLayout relativeLayout = new RelativeLayout(getContext());
             * RelativeLayout.LayoutParams params1 = new
             * RelativeLayout.LayoutParams(
             * RelativeLayout.LayoutParams.MATCH_PARENT,
             * RelativeLayout.LayoutParams.WRAP_CONTENT); params1.height = 600;
             * ScrollView scrollView = new ScrollView(getContext());
             */
            /*
             * scrollView.setLayoutParams(params1);
             * relativeLayout.setOnTouchListener(new OnTouchListener() {
             * 
             * @Override public boolean onTouch(View v, MotionEvent event) {
             * Log.e("error","here");
             * v.getParent().getParent().requestDisallowInterceptTouchEvent
             * (true); return true; } });
             */
            WebView w = new WebView(getContext());
            AbsListView.LayoutParams params = new AbsListView.LayoutParams(
                    RelativeLayout.LayoutParams.MATCH_PARENT,
                    RelativeLayout.LayoutParams.WRAP_CONTENT);
            params.height = 600;
            w.setLayoutParams(params);
            w.setScrollContainer(false);
            w.getSettings().setLoadsImagesAutomatically(true);
            w.getSettings().setJavaScriptEnabled(true);
            w.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
            w.setWebViewClient(new WebViewClient());

            w.setOnTouchListener(new OnTouchListener() {

                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    // TODO Auto-generated method stub
                    return false;
                }
            });
            w.loadUrl(getItem(position));
            w.setOnTouchListener(new OnTouchListener() {

                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    Log.e("error",event.getEventTime()+"");
                    v.getParent()
                            .requestDisallowInterceptTouchEvent(true);

                    WebView scrollView =(WebView) v;

                    switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:

                            map.put(position, new ArrayList<Float>());

                        map.get(position).add(0,event.getX());
                        map.get(position).add(1,event.getY());
                        break;
                    case MotionEvent.ACTION_MOVE:

                        float diff = (scrollView.getContentHeight()*scrollView.getScale()) - (scrollView.getScrollY()+600);
                       // Log.e("scrollView",scrollView.getContentHeight()*scrollView.getScale()+"   ");

                       // Log.e("diff",diff+"v.getBottom()"+ v.getBottom()+"v.getHeight()"+v.getHeight()+"v.getScrollY() "+v.getScrollY());
                       if (diff <= 0 ) {
                           scrollView.scrollTo((int)event.getX(), (int)(scrollView.getContentHeight()*scrollView.getScale()-600));
                            v.getParent()
                            .requestDisallowInterceptTouchEvent(false);

                          //Log.e("TestActivity", "bottom");
                          return false;
                        }if(v.getScrollY() < 0 ||  v.getHeight() > scrollView.getContentHeight()){
                            scrollView.scrollTo((int)event.getX(), (int)0);
                            v.getParent()
                            .requestDisallowInterceptTouchEvent(false);
                            // Log.e("TestActivity", "top");
                              return false;
                        }
                        float oldX =0;
                        float oldY = 0;
                        if(map.containsKey(position)){
                             oldX = map.get(position).get(0);
                             oldY = map.get(position).get(1);
                        }

                        float diffX = oldX -event.getX();
                        float diffY = oldY - event.getY();
                        //Log.e("Scroll To", "oldX "+ oldX+"oldY "+oldY+"diffX "+diffX+"diffY "+diffY+"event.getX() "+event.getX()+"event.getY() "+event.getY());
                        scrollView.scrollBy((int)diffX, (int)diffY);
                        Log.e("error",event.getEventTime()+"  =  "+diffY);
                        map.get(position).clear();
                        map.get(position).add(0,event.getX());
                        map.get(position).add(1,event.getY());
                        break;
                    default:
                        break;
                    }





                    return true;
                }
            });
            /*
             * scrollView.addView(w); relativeLayout.addView(scrollView);
             */
            return w;
            // return super.getView(position, convertView, parent);
        }

    }
}

and test_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ListView
        android:id="@+id/lv_test"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </ListView>

</LinearLayout>

Upvotes: -1

Chris
Chris

Reputation: 3338

You should place this on the parent layout of each webview and it should do the trick.

android:descendantFocusability="blocksDescendants" 
android:layout_width="match_parent"
android:layout_height="wrap_content"

Upvotes: 0

Related Questions