HTML book-like pagination

后端 未结 10 1384
清歌不尽
清歌不尽 2020-11-27 09:29

How can I split the content of a HTML file in screen-sized chunks to \"paginate\" it in a WebKit browser?

Each \"page\" should show a complete amount of text. This

10条回答
  •  隐瞒了意图╮
    2020-11-27 09:54

    I was able to improve Nacho's solution to get horizontal swipe paging effect with WebView. You can find solution here and example code.

    Edit:

    Solution code.

    MainActivity.java

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            WebView.setWebContentsDebuggingEnabled(true);
        }
        wv = (HorizontalWebView) findViewById(R.id.web_view);
        wv.getSettings().setJavaScriptEnabled(true);
        wv.setWebViewClient(new WebViewClient() {
    
            public void onPageFinished(WebView view, String url) {
                injectJavascript();
            }
        });
    
        wv.setWebChromeClient(new WebChromeClient() {
            @Override
            public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
                int pageCount = Integer.parseInt(message);
                wv.setPageCount(pageCount);
                result.confirm();
                return true;
            }
        });
        wv.loadUrl("file:///android_asset/ch03.html");   // now it will not fail here
    }
    
    private void injectJavascript() {
        String js = "function initialize(){\n" +
                "    var d = document.getElementsByTagName('body')[0];\n" +
                "    var ourH = window.innerHeight;\n" +
                "    var ourW = window.innerWidth;\n" +
                "    var fullH = d.offsetHeight;\n" +
                "    var pageCount = Math.floor(fullH/ourH)+1;\n" +
                "    var currentPage = 0;\n" +
                "    var newW = pageCount*ourW;\n" +
                "    d.style.height = ourH+'px';\n" +
                "    d.style.width = newW+'px';\n" +
                "    d.style.margin = 0;\n" +
                "    d.style.webkitColumnCount = pageCount;\n" +
                "    return pageCount;\n" +
                "}";
        wv.loadUrl("javascript:" + js);
        wv.loadUrl("javascript:alert(initialize())");
    }
    

    In my WebChromeClient's onJsAlert get the number of horizontal pages which i pass to the custom HorizontalWebView to implement paging effect

    HorizontalWebView.java

    public class HorizontalWebView extends WebView {
        private float x1 = -1;
        private int pageCount = 0;
    
        public HorizontalWebView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    x1 = event.getX();
                    break;
                case MotionEvent.ACTION_UP:
                    float x2 = event.getX();
                    float deltaX = x2 - x1;
                    if (Math.abs(deltaX) > 100) {
                        // Left to Right swipe action
                        if (x2 > x1) {
                            turnPageLeft();
                            return true;
                        }
    
                        // Right to left swipe action
                        else {
                            turnPageRight();
                            return true;
                        }
    
                    }
                    break;
            }
            return true;
        }
    
        private int current_x = 0;
    
        private void turnPageLeft() {
            if (getCurrentPage() > 0) {
                int scrollX = getPrevPagePosition();
                loadAnimation(scrollX);
                current_x = scrollX;
                scrollTo(scrollX, 0);
            }
        }
    
        private int getPrevPagePosition() {
            int prevPage = getCurrentPage() - 1;
            return (int) Math.ceil(prevPage * this.getMeasuredWidth());
        }
    
        private void turnPageRight() {
            if (getCurrentPage() < pageCount - 1) {
                int scrollX = getNextPagePosition();
                loadAnimation(scrollX);
                current_x = scrollX;
                scrollTo(scrollX, 0);
            }
        }
    
        private void loadAnimation(int scrollX) {
            ObjectAnimator anim = ObjectAnimator.ofInt(this, "scrollX",
                    current_x, scrollX);
            anim.setDuration(500);
            anim.setInterpolator(new LinearInterpolator());
            anim.start();
        }
    
        private int getNextPagePosition() {
            int nextPage = getCurrentPage() + 1;
            return (int) Math.ceil(nextPage * this.getMeasuredWidth());
        }
    
        public int getCurrentPage() {
            return (int) (Math.ceil((double) getScrollX() / this.getMeasuredWidth()));
        }
    
        public void setPageCount(int pageCount) {
            this.pageCount = pageCount;
        }
    }
    

提交回复
热议问题