How to scroll webview horizontally inside ViewPage

2019-01-23 09:11发布

I have a viewpager, where each page has to show a different WebView. This WebView should allow horizontall scrool, and I want to swipe to next page when the scroll finishes.

I've searched, and find some solutions, but nothing I did resolve this issue. I have a CustomViewPager and a CustomWebView for trying to handle scroll events.

This is my code:

Custom ViewPager

public class WebViewPager extends ViewPager {

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

    @Override
    protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
        if (v instanceof ExtendedWebView) {
            return ((ExtendedWebView) v).canScrollHor(-dx);
        } else {
            return super.canScroll(v, checkV, dx, x, y);
        }
    }
}

Custom WebView

public class ExtendedWebView extends WebView {

    public ExtendedWebView(Context context) {
        super(context);
    }

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

    public boolean canScrollHor(int direction) {
        final int offset = computeHorizontalScrollOffset();
        final int range = computeHorizontalScrollRange() - computeHorizontalScrollExtent();
        if (range == 0)
            return false;
        if (direction < 0) {
            return offset > 0;
        } else {
            return offset < range - 1;
        }
    }   
}

ScreenSlidePagerActivity

public class ScreenSlidePagerActivity extends FragmentActivity {

    class MyPageAdapter extends FragmentPagerAdapter {
        private List<Fragment> fragments;
        private List<String> titles;

        public MyPageAdapter(FragmentManager fm) {
            super(fm);
            this.fragments = new ArrayList<Fragment>();
            this.titles = new ArrayList<String>();
        }

        public void addItem(String url, String title) {
            Fragment myFragment = new WebViewFragment();
            Bundle args = new Bundle();
            args.putString("url", url);
            myFragment.setArguments(args);
            this.fragments.add(myFragment);
            this.titles.add(title);
        }

        @Override
        public Fragment getItem(int position) {
            return this.fragments.get(position);
        }

        public CharSequence getPageTitle(int position) {
            return this.titles.get(position);
        }

        @Override
        public int getCount() {
            return this.fragments.size();
        }
    }

    private MyPageAdapter pageAdapter = null;
    private WebViewPager pager = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        pageAdapter = new MyPageAdapter(getSupportFragmentManager());
        pageAdapter.addItem("url1", "WebView 1");
        pageAdapter.addItem("url2", "WebView 2");
        pageAdapter.addItem("url3", "WebView 3");

        pager = (WebViewPager) findViewById(R.id.pager);

        pager.setOffscreenPageLimit(pageAdapter.getCount() - 1);
        pager.setAdapter(pageAdapter);
    }
}

Layout of the activity

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    android:paddingBottom="0dp"
    android:paddingLeft="0dp"
    android:paddingRight="0dp"
    android:paddingTop="0dp"
    tools:context=".MainActivity" >

    <com.example.viewpagerexample.WebViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="6dp"
        android:paddingTop="0dp" >

        <android.support.v4.view.PagerTabStrip
            android:id="@+id/pager_header"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="top"
            android:background="#fff"
            android:paddingBottom="0dp"
            android:paddingLeft="0dp"
            android:paddingRight="0dp"
            android:paddingTop="0dp"
            android:textColor="#000" />
    </com.example.viewpagerexample.WebViewPager>

</LinearLayout>

UPDATE The accepted answer only worked if I put this parameter in the CSS of my web page:

display: table;

Apparently, without this parameter the WebView is not able to calculate the width of its content.

1条回答
对你真心纯属浪费
2楼-- · 2019-01-23 10:14

Set following properties to your WebView

<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

Alternatively you can also extend your WebView but not both altogether

@Override
public boolean onInterceptTouchEvent(MotionEvent p_event)
{
    return true;
}

@Override
public boolean onTouchEvent(MotionEvent p_event)
{
    if (p_event.getAction() == MotionEvent.ACTION_MOVE && getParent() != null)
    {
        getParent().requestDisallowInterceptTouchEvent(true);
    }

    return super.onTouchEvent(p_event);
}
查看更多
登录 后发表回答