1. 程式人生 > >Android ViewPager實現圖片瀏覽器

Android ViewPager實現圖片瀏覽器

Android ViewPager實現圖片瀏覽器

一、目標

左右滑動瀏覽筆記中的所有圖片。
在這裡插入圖片描述

二、體驗地址

神馬筆記最新版本:【神馬筆記Version1.1.0_beta.apk

三、方案選擇

Android中可以作為左右滑動,並將子控制元件停留在居中位置的容器有2個。

  1. RecyclerView with PagerSnapHelper
  2. ViewPager

將RecyclerView作為可選方案的原因是RecyclerView在神馬筆記中應用非常廣泛,基本上每個介面都用到了RecyclerView。繼續使用RecyclerView可以降低了專案程式碼的管理難度。

最終選擇ViewPager作為實現方案。

選擇ViewPager作為容器的關鍵原因,是ViewPager中有一段程式碼。

protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
    if (v instanceof ViewGroup) {
final ViewGroup group = (ViewGroup) v; final int scrollX = v.getScrollX(); final int scrollY = v.getScrollY(); final int count = group.getChildCount(); // Count backwards - let topmost views consume scroll distance first. for (int i = count - 1; i >=
0; i--) { // TODO: Add versioned support here for transformed views. // This will not work for transformed views in Honeycomb+ final View child = group.getChildAt(i); if (x + scrollX >= child.getLeft() && x + scrollX < child.getRight() && y + scrollY >= child.getTop() && y + scrollY < child.getBottom() && canScroll(child, true, dx, x + scrollX - child.getLeft(), y + scrollY - child.getTop())) { return true; } } } return checkV && v.canScrollHorizontally(-dx); }

這段程式碼用於讓ViewPager的子控制元件處理水平滑動。非常符合圖片瀏覽的使用場景。

當圖片放大超過控制元件寬度時,應該優先移動圖片。當圖片到達邊界時,才可以移動控制元件顯示下一張圖片。

四、PageTransformer

使用ViewPager的額外好處是可以通過設定PageTransformer來實現頁面的切換效果。

GitHub上有一個非常棒的專案實現了一系列效果——Viewpager-Transformation。

GitHub專案地址:https://github.com/dipanshukr/Viewpager-Transformation

Wiki幫助手冊:https://github.com/dipanshukr/Viewpager-Transformation/wiki

五、剪裁控制元件

Android提供了2中方式裁剪控制元件

  • setClipBounds(Rect clipBounds)
  • setOutlineProvider(ViewOutlineProvider provider)

setClipBounds接受一個Rect引數,以矩形方式進行裁剪。

setOutlineProvider接受一個ViewOutlineProvider引數,支援矩形、圓形、圓角矩形3中裁剪方式。

六、ClipPageTransformer

在左右滑動圖片時,變換子控制元件的裁剪區域實現圖片逐漸進入視野的效果。

private static class ClipPageTransformer implements ViewPager.PageTransformer {

    Rect clipRect;
    int gutterWidth;

    ClipPageTransformer(int gutterWidth) {
        this.clipRect = new Rect();
        this.gutterWidth = gutterWidth;
    }

    @Override
    public void transformPage(@NonNull View page, float position) {
        if (position >= 1 || position <= -1) {
            page.setClipBounds(null);
        } else if (position < 0) {

            int width = (int)(position * gutterWidth);
            clipRect.set(0, 0, page.getWidth() + width, page.getHeight());
            page.setClipBounds(clipRect);

        } else if (position < 1) {

            int width = (int)(position * gutterWidth);
            clipRect.set(width, 0, page.getWidth(), page.getHeight());
            page.setClipBounds(clipRect);

        }
    }
}

七、Final

ViewPager的使用方式比較容易,網上有很多不錯的介紹文章。也可以參考官方的示例程式碼瞭解ViewPager的使用方式。

FragmentPagerAdapterFragmentStatePagerAdapter是2個非常不錯的參考示例。