A ViewPager
is a fairly slick way to present a digital book. You can have
individual portions of the book be accessed by horizontal swiping, with the prose within a
portion accessed by scrolling vertically. While not offering “page-at-a-time”
models used by some book reader software, it is much simpler to set up.
So, that’s the approach we will use with EmPubLite. Which means, among other
things, that we need to add a ViewPager
to the app.
This is a continuation of the work we did in the previous tutorial.
You can find the results of the previous tutorial and the results of this tutorial in the book’s GitHub repository.
Right now, the main
layout used by EmPubLiteActivity
just has a TextView
. We need
to change that to have our ViewPager
.
Since ViewPager
is not available for drag-and-drop through the IDE
graphical layout editors, even IDE users are going to have to dive into the layout XML this time.
Open up res/layout/main.xml
and switch to the Text sub-tab to see the raw XML.
Replace its contents with:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<io.karim.MaterialTabs
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="48dp"
app:mtIndicatorColor="@color/colorAccent"
app:mtSameWeightTabs="true"/>
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
</LinearLayout>
This adds our ViewPager
, underneath a MaterialTabs
, inside a vertical
LinearLayout
. MaterialTabs
is an implementation of tabs for a
ViewPager
, one that we will explore in greater detail
later in the book.
A ViewPager
needs a PagerAdapter
to populate its content, much like a
ListView
needs a ListAdapter
. We cannot completely construct a PagerAdapter
yet, as we still need to learn how to load up our book content from files.
But, we can get part-way towards having a useful PagerAdapter
now.
Right-click over the com.commonsware.empublite
package in your java/
directory
and choose New > Java Class from the context menu. Fill in ContentsAdapter
as the name and click OK to create the empty class.
Then, replace the generated ContentsAdapter.java
file
with the following content:
package com.commonsware.empublite;
import android.app.Activity;
import android.app.Fragment;
import android.support.v13.app.FragmentStatePagerAdapter;
public class ContentsAdapter extends FragmentStatePagerAdapter {
public ContentsAdapter(Activity ctxt) {
super(ctxt.getFragmentManager());
}
@Override
public Fragment getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return 0;
}
}
If you prefer, you can view this file’s contents in your Web browser via this GitHub link.
Now, we need to add some code to retrieve the ViewPager
, populate it
with the ContentsAdapter
, and do something useful with those tabs.
First, add two fields to EmPubLiteActivity
:
private ViewPager pager;
private ContentsAdapter adapter;
This will require adding an import
for android.support.v4.view.ViewPager
.
Then, add a few more lines to the bottom of onCreate()
of EmPubLiteActivity
:
pager=(ViewPager)findViewById(R.id.pager);
adapter=new ContentsAdapter(this);
pager.setAdapter(adapter);
MaterialTabs tabs=(MaterialTabs)findViewById(R.id.tabs);
tabs.setViewPager(pager);
This will require an import
statement for io.karim.MaterialTabs
.
What we are doing is:
ViewPager
, holding onto it in its field,ContentsAdapter
,ContentsAdapter
with the ViewPager
,MaterialTabs
, andViewPager
At this point, your EmPubLiteActivity
should look something like:
package com.commonsware.empublite;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.view.Menu;
import android.view.MenuItem;
import io.karim.MaterialTabs;
public class EmPubLiteActivity extends Activity {
private ViewPager pager;
private ContentsAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
pager=(ViewPager)findViewById(R.id.pager);
adapter=new ContentsAdapter(this);
pager.setAdapter(adapter);
MaterialTabs tabs=(MaterialTabs)findViewById(R.id.tabs);
tabs.setViewPager(pager);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.options, menu);
return(super.onCreateOptionsMenu(menu));
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.about:
Intent i=new Intent(this, SimpleContentActivity.class);
startActivity(i);
return(true);
case R.id.help:
i=new Intent(this, SimpleContentActivity.class);
startActivity(i);
return(true);
}
return(super.onOptionsItemSelected(item));
}
}
The net effect, if you run this modified version of the app, is that
we have a big blank area, taken up by our empty ViewPager
:
Figure 257: EmPubLite, With Empty ViewPager
The ViewPager
is empty simply because our ContentsAdapter
returned 0
from getCount()
, indicating that there are no pages to be displayed.
… we will finish our “help” and “about” screens in our tutorial project.