July 22nd, 2021

eBook sample with Jetpack Window Manager

Raymond Liu
Firmware Engineer Intern

Hello Android developers!

Reading books on Microsoft Surface Duo can be a great take on the classic reading experience. In this blog, we will walk through an eBook reader sample I created as an internship project. This eBook sample demonstrates how the Two Page layout for foldable devices can naturally spread content across multiple screens.

Base functionality

This project is designed to load plain text files and present them in book form. The text is parsed into chapters according to some basic rules, and chapters are cached as arrays of strings (one string per paragraph). To build pages, the code uses the app’s current layout information and the chapter cache to organize the strings into pages.

Surface Duo ebook showing two pages of text and the section menu
Figure 1: Paging through a book

To display sliding pages, this app uses ViewPager2. ViewPager2 is an upgraded RecyclerView developed by Android to slide efficiently between Views. To support dual-screen devices, the app uses different ViewHolders based on the current app layout.

Dual-screen enhancements

Enhancing the book reading activity for two-page design required only a few extra lines of code. Jetpack Window Manager collects a list of display features. If folding features are detected, the ViewPager2 ViewHolders inflate “split” page layouts instead of “normal” page layouts. The position and width of the fold are used to calculate new Rects for the book to adhere to.

return when(layoutStateContainer.layoutMode) {
    BookActivity.LayoutMode.NORMAL -> {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.book_page_layout_normal, parent, false)
        view.findViewById(R.id.caption_view).text = book.chapterTitle
        PageViewHolder(view, book.fontSize)
    }
    // Setting view holder to two-page layout
    BookActivity.LayoutMode.SPLIT_HORIZONTAL -> {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.book_page_layout_split_horizontal, parent, false)
        view.findViewWithTag("page_container_0").layoutParams = LinearLayout.LayoutParams(book.pageRects[0].width(),
            LinearLayout.LayoutParams.MATCH_PARENT)
        view.findViewWithTag("page_container_1").layoutParams = LinearLayout.LayoutParams(book.pageRects[1].width(),
            LinearLayout.LayoutParams.MATCH_PARENT)

        view.findViewById(R.id.caption_view).text = book.chapterTitle
        view.findViewById(R.id.caption_view2).text = book.chapterTitle
        SplitPageViewHolder(view, book.fontSize)
    }

For the main menu activity, where users choose a book to read, Android Jetpack’s SlidingPaneLayout keeps the book selection UI on one side of a fold or hinge. An empty 0-width view on the right pane of the SlidingPaneLayout ensures that the left pane fills non-folded screens.

Surface Duo ebook index view
Figure 2: Book list view adapted to being spanned

The sample comes with a copy of some of our developer documentation as the default book content. You can add additional “books” as plain text files in the project’s assets/books folder. As long as each chapter has four preceding linefeeds and paragraphs are separated by two linefeeds, the content should be rendered in a readable way and populate the chapter menu.

Feedback and resources

The sample code is available on GitHub along with other Jetpack Window Manager dual-screen apps.

Check out the Surface Duo developer documentation and past blog posts for links and details on all our samples. You can find our samples on GitHub.

If you have any questions, or would like to tell us about your apps, use the feedback forum or message us on Twitter @surfaceduodev.

Author

Raymond Liu
Firmware Engineer Intern

Raymond is a computer engineering student at the University of Michigan. Along with robotics projects, he enjoys audiobooks, video games, watching F1, and badminton.

1 comment

Discussion is closed. Login to edit/delete existing comments.

  • Ehsan Mirsaeedi

    Great job.