webview inside the listview: Touch events conflicts Hence unable to pinch Zoom IN/OUT in android
Asked Answered
S

3

5

I have a custom listview which is filled with webview. I want to use the pinch zoom in/Zoom out for my webview. But i m not getting the pinch zoom in/out flexibly when i m pinching the webview it is triggering the listview's scrolling up and down.

how can I handle the scroll UP/DOWN event for the listview and pinch for webview simultaneously .

here is my listview_layout.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >

ListView
    android:id="@+id/listReader"
    android:layout_width="match_parent"
    android:layout_height="fill_parent"
    android:layout_below="@+id/readerHeader"
    android:divider="@android:color/background_dark"
    android:dividerHeight="5dp" >
</ListView>

here is my webview_layour.xml

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

<WebView
    android:id="@+id/webView1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:clickable="true"
    android:focusable="false"
    android:focusableInTouchMode="false"
    android:scrollbars="none" />
</RelativeLayout>

and here is my java file

public class WebViewBookReader extends Activity {
static final String URL = "http://www.XXXXXXXX.com/requesthandler.ashx";
static final String KEY_ITEM_LOGIN = "Result"; // parent node
static final String KEY_STATUS = "Status";
static final String KEY_CUSTOMERID = "CustomerID";
static final String KEY_FNAME = "FirstName";

ArrayList<String> URLs = null;
Activity act = this;
LayoutInflater inflater = null;
Context context = WebViewBookReader.this;

InputMethodManager imm;
SharedPreferences presForLastLogin;
ImageAdapter adapter;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.book_reader_layout);

    imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    getInfo = getIntent();

    URLs = new ArrayList<String>();
    listView = (ListView) findViewById(R.id.listReader);

    cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);



@Override
protected void onStart() {

    super.onStart();


    if (cm.getActiveNetworkInfo() != null
            && cm.getActiveNetworkInfo().isAvailable()
            && cm.getActiveNetworkInfo().isConnected()) {

        new LoadBookPages().execute("");
    } else {
        Toast.makeText(
                context,
                "Connectivity Error..!\nNo any active Internet Connection Found.",
                Toast.LENGTH_LONG).show();
    }

}

public class ImageAdapter extends BaseAdapter {

    public ImageAdapter(Context c) {
        context = c;
    }

    // ---returns the number of images---
    public int getCount() {
        return URLs.size();

    }

    public ImageAdapter(Context ctx, Activity act) {
        inflater = (LayoutInflater) act
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    // ---returns the ID of an item---
    public Object getItem(int position) {
        return position;
    }

    public long getItemId(int position) {
        return position;
    }

    // ---returns an ImageView view---
    public View getView(final int position, View convertView,
            ViewGroup parent) {

        // ImageView bmImage;

        View vi = convertView;
        if (convertView == null) {
            vi = inflater.inflate(R.layout.book_reader_list_style, parent,
                    false);
            holder = new ViewHolder();

            holder.webView = (WebView) vi.findViewById(R.id.webView1);

            // holder.webView.setInitialScale(scaleWebView);
            WebSettings webSettings = holder.webView.getSettings();
            holder.webView.setVerticalScrollBarEnabled(false);
            holder.webView.setHorizontalScrollBarEnabled(false);
            holder.webView.setVisibility(View.VISIBLE);
            webSettings.setLoadWithOverviewMode(true);
            webSettings.setUseWideViewPort(false);

            webSettings.setBuiltInZoomControls(true);
            webSettings.setSupportZoom(true);
            webSettings.setLoadWithOverviewMode(true);

            holder.webView.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    Log.i("Webview", "Clicked");

                }
            });

            vi.setTag(holder);
        } else {

            holder = (ViewHolder) vi.getTag();
        }

        holder.webView
                .loadDataWithBaseURL(
                        null,
                        "<!DOCTYPE html><html><body style = \"text-align:center\"><img style=\"border-style:dotted;border-width:5px;border-color:black;\" src= "
                                + URLs.get(position)
                                + " alt=\"page Not Found\"></body></html>",
                        "text/html", "UTF-8", null);

        return vi;

    }
}

class ViewHolder {
    WebView webView;
    ImageButton btnZoomIn;
    ImageButton btnZoomOut;

}

class LoadBookPages extends AsyncTask<String, Integer, String> {
    ImageAdapter adapter = new ImageAdapter(context, act);
    ProgressDialog progressDialog;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        progressDialog = ProgressDialog.show(context, "Loading Book...",
                "Please Wait...");
    }

    @Override
    protected String doInBackground(String... params) {

        for (int i = 1; i <= bookPageCount; i++) {
            URLs.add(bookLink + i + ".jpg");
            publishProgress(i);

        }

        return null;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {

        super.onProgressUpdate(values);

        progressDialog.setMessage(values[0]
                + " Page(s) Loaded \nPlease wait...");

    }

    @Override
    protected void onPostExecute(String result) {

        super.onPostExecute(result);
        Toast.makeText(context, "Page No. " + pageNo, Toast.LENGTH_SHORT)
                .show();
        listView.setAdapter(adapter);
        listView.requestFocus();
        progressDialog.dismiss();
        listView.setSelection(pageNo - 1);
    }

}

private class UIThread_BookMark extends AsyncTask<String, Integer, String> {

    ProgressDialog progressDialog;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();

        progressDialog = ProgressDialog.show(context, "BookMarking...",
                "Please Wait...");
    }

    @Override
    protected String doInBackground(String... params) {

        String URL = params[0];

        XMLParser parser = new XMLParser();

        String XMLString = parser.getXmlFromUrl_BookMark(URL,
                Home.CustomerID, Integer.valueOf(bookID), pageNo);
        Document doc = parser.getDomElement(XMLString);
        NodeList nl = doc.getElementsByTagName(KEY_ITEM_LOGIN);
        Element e = (Element) nl.item(0);

        loginStatus = parser.getValue(e, KEY_STATUS);

        if (loginStatus.equals("OK")) {

            publishProgress(1);

        } else {

            publishProgress(0);
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        if (values[0] == 1) {

            Toast.makeText(context, "BookMark Successful",
                    Toast.LENGTH_SHORT).show();

            if (getInfo.getStringExtra("CHECK_FOR_NOWREADING")
                    .equals("YES")) {
                NowReading.pageNoReadingNow.set(
                        getInfo.getIntExtra("BOOK_NO_INLIST", pageNo),
                        pageNo + "");
                Toast.makeText(context, "BookMark Updated",
                        Toast.LENGTH_SHORT).show();
                BookOverView.updatePageFlag = true;
                BookOverView.tempPageNo = pageNo + "";
            } else {
                NowReading.BookTitle = null;
                NowReading.BookRating = null;
                NowReading.BookDescription = null;
                NowReading.BookCoverPhotos = null;
                NowReading.BookAuther = null;
                NowReading.BookPublishDate = null;
                NowReading.BookCode = null;
                NowReading.BookID = null;
                NowReading.BookPageCount = null;
                NowReading.bitmapArray = null;
                NowReading.pageNoReadingNow = null;
                BookOverView.updatePageFlag = false;
            }

        } else if (values[0] == 0) {
            Toast.makeText(context, "Already BookMarked.",
                    Toast.LENGTH_LONG).show();
        }
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        progressDialog.dismiss();
    }
}
}
Shericesheridan answered 21/1, 2013 at 13:30 Comment(1)
This question has an open bounty worth +50 reputation from Qadir Hussain ending in 3 days.Shericesheridan
R
9

you need to implement setOnTouchListener listener on webView and write this statement inside onTouch()

webView.setOnTouchListener(new View.OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent event) {                     

        if(event.getAction()==MotionEvent.ACTION_UP){
            webView.getParent().requestDisallowInterceptTouchEvent(false);

        }else                                   
            webView.getParent().requestDisallowInterceptTouchEvent(true);

        return false;
    }

});

for more detail

http://developer.android.com/reference/android/view/ViewParent.html#requestDisallowInterceptTouchEvent%28boolean%29

Edited

Detecting pinch in Android

How to detect the pinch-zoom event with OnGestureListener in Android?

http://www.krvarma.com/2010/10/multi-touch-in-android/

http://code.almeros.com/android-multitouch-gesture-detectors#.UP4qp4Zu_ox

Railroad answered 21/1, 2013 at 13:53 Comment(4)
i tried this.. this doesn't effect any much. Is there any way to recognize when user pinch with two finger or thumbs?Shericesheridan
yes you need to implement Gesture detector on webview with onTouch listener. Using this call the parent.requestDisallInterceptTouchEvent(true) hope that was work for youRailroad
can you post the code please. I m newbie of gesture detector and touch listener.Shericesheridan
https://mcmap.net/q/813537/-detecting-pinch-in-android, https://mcmap.net/q/637849/-how-to-detect-the-pinch-zoom-event-with-ongesturelistener-in-android, krvarma.com/2010/10/multi-touch-in-android, code.almeros.com/…Railroad
S
0

I have done this thing with 2 scroll views. May be it can help you a bit. here is my code:

ScrollView s_parent= (ScrollView) detailView.findViewById(R.id.parent_scroll);
ScrollView s_child=(ScrollView)detailView.findViewById(R.id.child_scroll);
s_child.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        // TODO Auto-generated method stub
        //Log.v("scrooll_touch","CHILD TOUCH");
        // Disallow the touch request for parent scroll on touch of child view
        v.getParent().requestDisallowInterceptTouchEvent(true);
        return false;
    }
});
s_parent.setOnTouchListener(new View.OnTouchListener() {
    public boolean onTouch(View v, MotionEvent event) {
        // Log.v("scrooll_touch","PARENT TOUCH");
        findViewById(R.id.child_scroll).getParent().requestDisallowInterceptTouchEvent(false);
        return false;
    }
});
Subvene answered 6/2, 2013 at 8:11 Comment(4)
as I have used the custom listview which inflates an webview which resides in another separate XML file. we can not consider them as parent and child of each other. please see my XML files above. may be I m wrongShericesheridan
ok.. can you tell me what are you displaying in your list view?Subvene
I m displaying the webview only in the getVIew method. refer above code plz i have pastedShericesheridan
You cant use Webview inside List View . Because everytime Adapters getView call your view will reload and then it will stuck the application .. I advised you to use Scroll view instead ..Basketry
S
0

I found a solution by creating a custom WebView class

CustomWebView catches touch events that are related with MORE than ONE finger on screen. So user can swipe next item in listview with only one finger.

According the case webView tells its parent view to intercept touch events

@SuppressLint("ClickableViewAccessibility")
class CustomWebView : WebView {
    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)

    init {
        setOnTouchListener { _, event ->
            if (event.action != MotionEvent.INVALID_POINTER_ID &&

                //is for extra fingers that enter the screen beyond the first
                event.action == MotionEvent.ACTION_POINTER_DOWN ||

                //is sent when a finger leaves the screen but at least one finger is still touching it.
                event.action == MotionEvent.ACTION_POINTER_UP ||

                //The number of pointers of data contained in this event.
                event.pointerCount >= 2
            ) {
                //the child does not want the parent to intercept touch events.
                parent.requestDisallowInterceptTouchEvent(true)
            }

            // return always false
            // because the listener has not consumed the event
            false
        }
    }
}
Spill answered 12/7, 2023 at 10:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.