Friday, March 10, 2017

ViewPager with WebView allowing swiping and disallowing scrolling of WebView

Leave a Comment

I am using ViewPager and WebViewto present HTML contents as an eBook. On some pages of the ViewPager I am allowing the TouchEvent to be handled by the WebView and on some pages I am letting the ViewPager handle the TouchEvent by itself by overriding the onInterceptTouchEvent method in the ViewPager(some pages are having TextViews and Buttons without WebView 1st and last page here). Here is code for the same-

@Override     public boolean onInterceptTouchEvent(MotionEvent ev) {         if (getCurrentItem() == 0 || getCurrentItem() == getAdapter().getCount() - 1)             return false;         else {             if (ev.getAction() == MotionEvent.ACTION_DOWN) {                 return false;             }             return true;         }     } 

I am again disallowing the scrolling by setting OnTouchListener on the WebView using the following code-

contentView.setOnTouchListener((v, event) -> {             if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_MOVE) {                 ((BigBeeViewPager) v.getParent().getParent()).onInterceptTouchEvent(event);             }             return true;         }); 

Problem I am facing is - When I am trying to swipe the ViewPager from the middle of the pages it doesn't work. I have to start swiping from the end of the pages. However it works fine for the pages which are not having WebView How to allow it to start swiping from the anywhere in the pages.

This behaviour is similar to Gmail Android App where ViewPager is containing the WebView and Swiping is available from any where. I am not able to figure out how they have done it.

Note - When I am intercepting all TouchEvent to the WebView it disables the long click and text selection too, which is not desirable.

Thanks in advance for the help.

3 Answers

Answers 1

Here you go man - an old problem with a nice solution.

Take a look here Scroll webview horizontally inside a ViewPager

Answers 2

You have create a GestureDetector and implement that on a Webviewlike this:

GestureDetector gestureDetector=new GestureDetector(new GestureDetector.OnGestureListener() {         @Override         public boolean onDown(MotionEvent motionEvent) {             return false;         }          @Override         public void onShowPress(MotionEvent motionEvent) {         }          @Override         public boolean onSingleTapUp(MotionEvent motionEvent) {             return false;         }          @Override         public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {             return false;         }          @Override         public void onLongPress(MotionEvent motionEvent) {         }          @Override         public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {             return false;         }     });            webView.setOnTouchListener(new View.OnTouchListener() {                 @Override                 public boolean onTouch(View v, MotionEvent event) {                     switch (event.getAction()) {                         case MotionEvent.ACTION_DOWN:                         case MotionEvent.ACTION_UP:                             if (!v.hasFocus()) {                                 v.requestFocus();                             }                             break;                     }                     gestureDetector.onTouchEvent(event);                     return false;                 }             }); 

And remove the Interceptor from Viewpager and use the default one without any changes

Answers 3

<your.package.name.MyWebView   android:id="@+id/webview"   android:layout_width="fill_parent"   android:layout_height="fill_parent"   />   mWebView.setInitialScale(120);     mWebView.setScrollContainer(true);     mWebView.bringToFront();     mWebView.setScrollbarFadingEnabled(true);     mWebView.setVerticalScrollBarEnabled(true);     mWebView.setHorizontalScrollBarEnabled(true);     mWebView.getSettings().setBuiltInZoomControls(true);     mWebView.getSettings().setJavaScriptEnabled(false);     mWebView.getSettings().setUseWideViewPort(true);     mWebView.getSettings().setUserAgentString("Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3"); 

1. implement a custom ViewPager Instance like this:

import android.content.Context; import android.support.v4.view.ViewPager; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent;  public class CustomViewPager extends ViewPager {      private MagazineWebView_WithoutFlipWebView mCurrentPageWebView_; //custom webview      public CustomViewPager(Context context, AttributeSet attrs) {         super(context, attrs);     }      @Override     public boolean onInterceptTouchEvent(MotionEvent event) {          if (Constants.LOGGING) {             Log.v(Constants.LOG_OEAMTC_APP, "CustomViewPager - onInterceptTouchEvent");         }          // if view zoomed out (view starts at 33.12... scale level) ... allow         // zoom within webview, otherwise disallow (allow viewpager to change         // view)         if (mCurrentPageWebView_ != null && (mCurrentPageWebView_.getScale() * 100) > 34) {             Log.v(Constants.LOG_OEAMTC_APP, "CustomViewPager - intrcepted: " + String.valueOf((mCurrentPageWebView_.getScale() * > 100)));             this.requestDisallowInterceptTouchEvent(true);         }         else {             if (mCurrentPageWebView_ != null) {                 Log.v(Constants.LOG_OEAMTC_APP,                         "CustomViewPager - not intrcepted: " + String.valueOf(mCurrentPageWebView_.getScale() * 100));             }             this.requestDisallowInterceptTouchEvent(false);         }          return super.onInterceptTouchEvent(event);     }      public MagazineWebView_WithoutFlipWebView getCurrentPageWebView() {         return mCurrentPageWebView_;     }      public void setCurrentPageWebView(MagazineWebView_WithoutFlipWebView currentPageWebView) {         mCurrentPageWebView_ = currentPageWebView;     } } 

2. in your main (ViewPager) Activity add the following lines to the view pager

mViewPager_ = new AwesomePagerAdapter();         viewpapgerInLayout = (CustomViewPager) findViewById(R.id.awesomepager);         viewpapgerInLayout.setAdapter(mViewPager_);         viewpapgerInLayout.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {             @Override             public void onPageSelected(int position) {                   viewpapgerInLayout.setCurrentPageWebView(mLstPagesWebviews_.get(position));             }              @Override             public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {              }              @Override             public void onPageScrollStateChanged(int state) {              }         }); 

3. finally, run it :=) if the zoom level is at initial zoom, changes pages is allowed, all the other time you can navigate your web view

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment