Android ViewPager實現圖片瀏覽器
Android ViewPager實現圖片瀏覽器
一、目標
左右滑動瀏覽筆記中的所有圖片。
二、體驗地址
神馬筆記最新版本:【神馬筆記Version1.1.0_beta.apk】
三、方案選擇
Android中可以作為左右滑動,並將子控制元件停留在居中位置的容器有2個。
- RecyclerView with PagerSnapHelper
- 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的使用方式。
FragmentPagerAdapter
和FragmentStatePagerAdapter
是2個非常不錯的參考示例。