Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making ViewPager + WebView swipe vertical in continuous way

I'm writing a html page reader, cant load all .html because its huge and performance is bad, so I decided to split it into 3(or more) html and load that inside Web View nested with View Pager (swipe vertically)

My problem is that I should swipe slowly to scroll the web view and swipe fast to change view pager

Slow swiping

enter image description here

fast swipe change the Page on ViewPager

enter image description here

1) Can i expand webview to all its content heigh inside viewpager ? 2) Can change viewpager item only when topScroll or endScroll?

what i've tried so far:

CustomWebView

 @Override
    public boolean onTouchEvent(MotionEvent event) {
        requestDisallowInterceptTouchEvent(true);

        return super.onTouchEvent(event);
    }

worked but was unable to change viewpager item

so i though about enable/disable it when i get to the top or to the end

removed webview onTouchEvent and added:

   @Override
    protected void onScrollChanged(final int l, final int t, final int oldl, final int oldt) {
        requestDisallowInterceptTouchEvent(true);



        int height = (int) Math.floor(this.getContentHeight() * this.getScale());
        int webViewHeight = this.getMeasuredHeight();

        boolean scrollTop = this.getTop() == t;
        boolean scrollEnd = this.getScrollY() + webViewHeight >= height;

        if(scrollTop || scrollEnd) {
            requestDisallowInterceptTouchEvent(false);
        } 

worked randomly, the most common thing is that when i change page, i must scroll down and scroll up to trigger the requestDisallow to false so i can change page =[

Vertical CustomViewPage is this one ->

public class VerticalViewPager extends ViewPager {

    public VerticalViewPager(Context context) {
        super(context);
        init();
    }

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

    private void init() {
        // The majority of the magic happens here
        setPageTransformer(true, new VerticalPageTransformer());
        // The easiest way to get rid of the overscroll drawing that happens on the left and right
        setOverScrollMode(OVER_SCROLL_NEVER);
    }

    private class VerticalPageTransformer implements ViewPager.PageTransformer {

        @Override
        public void transformPage(View view, float position) {

            if (position < -1) { // [-Infinity,-1)
                // This page is way off-screen to the left.
                view.setAlpha(0);

            } else if (position <= 1) { // [-1,1]
                view.setAlpha(1);

                // Counteract the default slide transition
                view.setTranslationX(view.getWidth() * -position);

                //set Y position to swipe in from top
                float yPosition = position * view.getHeight();
                view.setTranslationY(yPosition);

            } else { // (1,+Infinity]
                // This page is way off-screen to the right.
                view.setAlpha(0);
            }
        }
    }

    /**
     * Swaps the X and Y coordinates of your touch event.
     */
    private MotionEvent swapXY(MotionEvent ev) {
        float width = getWidth();
        float height = getHeight();

        float newX = (ev.getY() / height) * width;
        float newY = (ev.getX() / width) * height;

        ev.setLocation(newX, newY);

        return ev;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev){
        boolean intercepted = super.onInterceptTouchEvent(swapXY(ev));
        swapXY(ev); // return touch coordinates to original reference frame for any child views
        return intercepted;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return super.onTouchEvent(swapXY(ev));
    }

}
like image 382
user2582318 Avatar asked Apr 26 '18 06:04

user2582318


Video Answer


1 Answers

  • 1st i think it's a bad idea to split your content into 3 different HTML files and putting them on 3 different WebViews.
  • 3 fils can be a good idea but 3 WebView in 3 Views of ViewPager is a bad idea.
  • Instead, you should detect top and bottom of the webpage using ".js" / "jQuery" and route page/HTML within same WebView.

    window.onscroll = function(ev) { if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) { // you're at the bottom of the page }};

There are many ways to detect TOP and BOTTOM of your HTML content.

Still, if you want to increase the height of your review to content height use Getting WebView Content height once its loaded Android it worked for me.

like image 91
Abhinav Aggarwal Avatar answered Nov 14 '22 23:11

Abhinav Aggarwal