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
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;
}
}