1. 程式人生 > >Android 中使用 RecyclerView + SnapHelper 實現類似 ViewPager 效果

Android 中使用 RecyclerView + SnapHelper 實現類似 ViewPager 效果

寫在前面:強大的Recyclerview,官方提供的幫助類.

1 前言

在 一些特定的場景下,如照片的瀏覽,卡片列表滑動瀏覽,我們希望當滑動停止時可以將當前的照片或者卡片停留在螢幕中央,以吸引使用者的焦點。在 Android 中,我們可以使用RecyclerView + Snaphelper 來實現,SnapHelper 旨在支援 RecyclerView 的對齊方式,也就是通過計算對齊 RecyclerView 中 TargetView 的指定點或者容器中的任何畫素點(包括前面說的顯示在螢幕中央)。本篇文章將詳細介紹 SnapHelper 的相關知識點。本文目錄如下:

2 SnapHelper 介紹

Google 在 Android 24.2.0 的 support 包中添加了 SnapHelper,SnapHelper 是對RecyclerView 的拓展,結合 RecyclerView 使用,能很方便的做出一些炫酷的效果。SnapHelper 到底有什麼功能呢? SnapHelper 旨在支援 RecyclerView 的對齊方式,也就是通過計算對齊 RecyclerView 中 TargetView 的指定點或者容器中的任何畫素點。 ,可能有點不好理解,看了後文的效果和原理分析就好理解了。看一下文件介紹:

SnapHelper 繼承自 RecyclerView.OnFlingListener ,並實現了它的抽象方法 onFling , 支援 SnapHelper 的 RecyclerView.LayoutManager 必須實現 RecyclerView.SmoothScroller.ScrollVectorProvider 介面,或者你自己實現 onFling(int,int) 方法手動處理。SnapHeper 有以下幾個重要方法:

  • attachToRecyclerView:將 SnapHelper attach 到指定的 RecyclerView 上。

  • calculateDistanceToFinalSnap:複寫這個方法計算對齊到 TargetView 或容器指定點的距離,這是一個抽象方法,由子類自己實現,返回的是一個長度為 2 的 int 陣列 out,out[0] 是 x 方向對齊要移動的距離,out[1] 是 y 方向對齊要移動的距離。

  • calculateScrollDistance:根據每個方向給定的速度估算滑動的距離,用於 Fling 操作。

  • findSnapView:提供一個指定的目標 View 來對齊,抽象方法,需要子類實現

  • findTargetSnapPosition:提供一個用於對齊的 Adapter 目標 position,抽象方法,需要子類自己實現。

  • onFling:根據給定的 x 和 y 軸上的速度處理 Fling。

3 LinearSnapHelper & PagerSnapHelper

上面講了 SnapHelper 的幾個重要的方法和作用,SnapHelper 是一個抽象類,要使用SnapHelper,需要實現它的幾個方法。而 Google 內建了兩個預設實現類, LinearSnapHelper 和 PagerSnapHelper  ,LinearSnapHelper 可以使 RecyclerView 的當前 Item 居中顯示(橫向和豎向都支援),PagerSnapHelper  看名字可能就能猜到,使RecyclerView 像ViewPager 一樣的效果,每次只能滑動一頁(LinearSnapHelper 支援快速滑動), PagerSnapHelper 也是 Item 居中對齊。接下來看一下使用方法和效果。

(1) LinearSnapHelper

LinearSnapHelper  使當前 Item 居中顯示,常用場景是橫向的 RecyclerView, 類似ViewPager 效果,但是又可以快速滑動(滑動多頁)。程式碼如下:

LinearLayoutManager manager = new LinearLayoutManager(getContext());
 manager.setOrientation(LinearLayoutManager.VERTICAL);
 mRecyclerView.setLayoutManager(manager);// 將SnapHelper attach 到RecyclrView
 LinearSnapHelper snapHelper = new LinearSnapHelper();
 snapHelper.attachToRecyclerView(mRecyclerView);

程式碼很簡單,new 一個 SnapHelper 物件,然後 Attach 到 RecyclerView 即可。

效果如下:

如上圖所示,簡單幾行程式碼就可以用 RecyclerView 實現一個類似 ViewPager 的效果,並且效果更贊。可以快速滑動多頁,當前頁劇中顯示,並且顯示前一頁和後一頁的部分。如果使用 ViewPager 來做還是有點麻煩的。除了上面的效果外,如果你想要和 ViewPager 一樣,限制一次只讓它滑動一頁,那麼你就可以使用 PagerSnapHelper 了,接下來看一下PagerSnapHelper 的使用效果。

(2) PagerSnapHelper (在Android 25.1.0 support 包加入的)
PagerSnapHelper 的展示效果和 LineSnapHelper 是一樣的,只是 PagerSnapHelper 限制一次只能滑動一頁,不能快速滑動。程式碼如下:

PagerSnapHelper snapHelper = new PagerSnapHelper();

snapHelper.attachToRecyclerView(mRecyclerView);

PagerSnapHelper效果如下:

上面展示的是 PagerSnapHelper 水平方向的效果,豎直方向的效果和 LineSnapHelper 豎直的方向的效果差不多,只是不能快速滑動,就不在介紹了,感興趣的可以把它們的效果都試一下。

上面就是 LineSnapHelper 和  PagerSnapHelper 的使用和效果展示,瞭解了它的使用方法和效果,接下來我們看一下它的實現原理。

4 SnapHelper原碼分析

上面介紹了 SnapHelper 的使用,那麼接下來我們來看一下 SnapHelper 到底是怎麼實現的,走讀一下原始碼:

(1) 入口方法,attachToRecyclerView

通過

attachToRecyclerView 方法將 SnapHelper attach 到 RecyclerView,看一下這個方法做了哪些事情:

/**
    *
    * 1,首先判斷attach的RecyclerView 和原來的是否是一樣的,一樣則返回,不一樣則替換
    * 
    * 2,如果不是同一個RecyclerView,將原來設定的回撥全部remove或者設定為null
    * 
    * 3,Attach的RecyclerView不為null,先2設定回撥 滑動的回撥和Fling操作的回撥,
    * 初始化一個Scroller 用於後面做滑動處理,然後呼叫snapToTargetExistingView
    *
    * */
    public void attachToRecyclerView(@Nullable RecyclerView recyclerView)
            throws IllegalStateException {
        if (mRecyclerView == recyclerView) {
            return; // nothing to do
        }
        if (mRecyclerView != null) {
            destroyCallbacks();
        }
        mRecyclerView = recyclerView;
        if (mRecyclerView != null) {
            setupCallbacks();
            mGravityScroller = new Scroller(mRecyclerView.getContext(),
                    new DecelerateInterpolator());
            snapToTargetExistingView();
        }
    }

(2) snapToTargetExistingView :

這個方法用於第一次Attach到 RecyclerView 時對齊 TargetView,或者當 Scroll 被觸發的時候和 fling 操作的時候對齊 TargetView 。在 attachToRecyclerView 和 onScrollStateChanged 中都呼叫了這個方法。

/**
    *
    * 1,判斷RecyclerView 和LayoutManager是否為null
    *
    * 2,呼叫findSnapView  方法來獲取需要對齊的目標View(這是個抽象方法,需要子類實現)
    *
    * 3,通過calculateDistanceToFinalSnap 獲取x方向和y方向對齊需要移動的距離
    *
    * 4,最後通過RecyclerView 的smoothScrollBy 來移動對齊
    **/
    void snapToTargetExistingView() {
        if (mRecyclerView == null) {
            return;
        }
        LayoutManager layoutManager = mRecyclerView.getLayoutManager();
        if (layoutManager == null) {
            return;
        }
        View snapView = findSnapView(layoutManager);
        if (snapView == null) {
            return;
        }
        int[] snapDistance = calculateDistanceToFinalSnap(layoutManager, snapView);
        if (snapDistance[0] != 0 || snapDistance[1] != 0) {
            mRecyclerView.smoothScrollBy(snapDistance[0], snapDistance[1]);
        }
    }

(3) Filing 操作時對齊:

SnapHelper 繼承了 RecyclerView.OnFlingListener,實現了 onFling 方法。

/**
* fling 回撥方法,方法中呼叫了snapFromFling,真正的對齊邏輯在snapFromFling裡
*/

    @Override
    public boolean onFling(int velocityX, int velocityY) {
        LayoutManager layoutManager = mRecyclerView.getLayoutManager();
        if (layoutManager == null) {
            return false;
        }
        RecyclerView.Adapter adapter = mRecyclerView.getAdapter();
        if (adapter == null) {
            return false;
        }
        int minFlingVelocity = mRecyclerView.getMinFlingVelocity();
        return (Math.abs(velocityY) > minFlingVelocity || Math.abs(velocityX) > minFlingVelocity)
                && snapFromFling(layoutManager, velocityX, velocityY);
    }
 /**
  *snapFromFling 方法被fling 觸發,用來幫助實現fling 時View對齊
  *
  */
 private boolean snapFromFling(@NonNull LayoutManager layoutManager, int velocityX,
            int velocityY) {
       // 首先需要判斷LayoutManager 實現了ScrollVectorProvider 介面沒有,
      //如果沒有實現 ,則直接返回。
        if (!(layoutManager instanceof ScrollVectorProvider)) {
            return false;
        }
      // 建立一個SmoothScroller 用來做滑動到指定位置
        RecyclerView.SmoothScroller smoothScroller = createSnapScroller(layoutManager);
        if (smoothScroller == null) {
            return false;
        }
        // 根據x 和 y 方向的速度來獲取需要對齊的View的位置,需要子類實現。
        int targetPosition = findTargetSnapPosition(layoutManager, velocityX, velocityY);
        if (targetPosition == RecyclerView.NO_POSITION) {
            return false;
        }
       // 最終通過 SmoothScroller 來滑動到指定位置
        smoothScroller.setTargetPosition(targetPosition);
        layoutManager.startSmoothScroll(smoothScroller);
        return true;
    }

其實通過上面的 3 個方法就實現了 SnapHelper 的對齊,只是有幾個抽象方法是沒有實現的,具體的對齊規則交給子類去實現。

接下來看一下 LinearSnapHelper 是怎麼實現劇中對齊的: 主要是實現了上面提到的三個抽象方法, findTargetSnapPosition 、 calculateDistanceToFinalSnap 和 findSnapView 。

(1) calculateDistanceToFinalSnap :計算最終對齊要移動的距離,返回一個長度為 2 的int 陣列 out,out[0] 為 x 方向移動的距離,out[1] 為 y 方向移動的距離。

@Override
    public int[] calculateDistanceToFinalSnap(
            @NonNull RecyclerView.LayoutManager layoutManager, @NonNull View targetView) {
        int[] out = new int[2];
       // 如果是水平方向滾動的,則計算水平方向需要移動的距離,否則水平方向的移動距離為0
        if (layoutManager.canScrollHorizontally()) {
            out[0] = distanceToCenter(layoutManager, targetView,
                    getHorizontalHelper(layoutManager));
        } else {
            out[0] = 0;
        }
 // 如果是豎直方向滾動的,則計算豎直方向需要移動的距離,否則豎直方向的移動距離為0
        if (layoutManager.canScrollVertically()) {
            out[1] = distanceToCenter(layoutManager, targetView,
                    getVerticalHelper(layoutManager));
        } else {
            out[1] = 0;
        }
        return out;
    }

   // 計算水平或者豎直方向需要移動的距離
    private int distanceToCenter(@NonNull RecyclerView.LayoutManager layoutManager,
            @NonNull View targetView, OrientationHelper helper) {
        final int childCenter = helper.getDecoratedStart(targetView) +
                (helper.getDecoratedMeasurement(targetView) / 2);
        final int containerCenter;
        if (layoutManager.getClipToPadding()) {
            containerCenter = helper.getStartAfterPadding() + helper.getTotalSpace() / 2;
        } else {
            containerCenter = helper.getEnd() / 2;
        }
        return childCenter - containerCenter;
    }

(2) findSnapView:   找到要對齊的 View

// 找到要對齊的目標View, 最終的邏輯在findCenterView 方法裡// 規則是:迴圈LayoutManager的所有子元素,計算每個 childView的//中點距離Parent 的中點,找到距離最近的一個,就是需要居中對齊的目標View
 @Override
    public View findSnapView(RecyclerView.LayoutManager layoutManager) {
        if (layoutManager.canScrollVertically()) {
            return findCenterView(layoutManager, getVerticalHelper(layoutManager));
        } else if (layoutManager.canScrollHorizontally()) {
            return findCenterView(layoutManager, getHorizontalHelper(layoutManager));
        }
        return null;
    }

(3) findTargetSnapPosition :   找到需要對齊的目標 View 的的 Position

@Override
    public int findTargetSnapPosition(RecyclerView.LayoutManager layoutManager, int velocityX,
            int velocityY) {...// 前面程式碼省略
        int vDeltaJump, hDeltaJump;
       // 如果是水平方向滾動的列表,估算出水平方向SnapHelper響應fling 
       //對齊要滑動的position和當前position的差,否則,水平方向滾動的差值為0.
        if (layoutManager.canScrollHorizontally()) {
            hDeltaJump = estimateNextPositionDiffForFling(layoutManager,
                    getHorizontalHelper(layoutManager), velocityX, 0);
            if (vectorForEnd.x < 0) {
                hDeltaJump = -hDeltaJump;
            }
        } else {
            hDeltaJump = 0;
        }
      // 如果是豎直方向滾動的列表,估算出豎直方向SnapHelper響應fling 
       //對齊要滑動的position和當前position的差,否則,豎直方向滾動的差值為0.
        if (layoutManager.canScrollVertically()) {
            vDeltaJump = estimateNextPositionDiffForFling(layoutManager,
                    getVerticalHelper(layoutManager), 0, velocityY);
            if (vectorForEnd.y < 0) {
                vDeltaJump = -vDeltaJump;
            }
        } else {
            vDeltaJump = 0;
        }

 // 最終要滑動的position 就是當前的Position 加上上面算出來的差值。//後面程式碼省略...}

以上就分析了 LinearSnapHelper 實現滑動的時候居中對齊和 fling 時居中對齊的原始碼。整個流程還是比較簡單清晰的,就是涉及到比較多的位置計算比較麻煩。熟悉了它的實現原理,從上面我們知道,SnapHelper 裡面實現了對齊的流程,但是怎麼對齊的規則就交給子類去處理了,比如 LinearSnapHelper 實現了居中對齊,PagerSnapHelper 實現了居中對齊,並且限制只能一次滑動一頁。那麼我們也可以繼承它來實現我們自己的 SnapHelper,接下來看一下自己實現一個 SnapHelper。

5 自定義 SnapHelper

上面分析了 SnapHelper 的流程,那麼這節我們來自定義一個 SnapHelper , LinearSnapHelper 實現了居中對齊,那麼我們來試著實現 Target View 開始對齊。  當然了,我們不用去繼承 SnapHelper,既然 LinearSnapHelper 實現了居中對齊,那麼我們只要更改一下對齊的規則就行,更改為開始對齊(計算目標 View到 Parent start 要滑動的距離),其他的邏輯和 LinearSnapHelper 是一樣的。因此我們選擇繼承 LinearSnapHelper ,具體程式碼如下:

/**
* Created by zhouwei on 17/3/30.
*/

public class StartSnapHelper extends LinearSnapHelper {

    private OrientationHelper mHorizontalHelper, mVerticalHelper;

    @Nullable
    @Override
    public int[] calculateDistanceToFinalSnap(RecyclerView.LayoutManager layoutManager, View targetView) {
        int[] out = new int[2];
        if (layoutManager.canScrollHorizontally()) {
            out[0] = distanceToStart(targetView, getHorizontalHelper(layoutManager));
        } else {
            out[0] = 0;
        }
        if (layoutManager.canScrollVertically()) {
            out[1] = distanceToStart(targetView, getVerticalHelper(layoutManager));
        } else {
            out[1] = 0;
        }
        return out;
    }

    private int distanceToStart(View targetView, OrientationHelper helper) {
        return helper.getDecoratedStart(targetView) - helper.getStartAfterPadding();
    }

    @Nullable
    @Override
    public View findSnapView(RecyclerView.LayoutManager layoutManager) {
        if (layoutManager instanceof LinearLayoutManager) {

            if (layoutManager.canScrollHorizontally()) {
                return findStartView(layoutManager, getHorizontalHelper(layoutManager));
            } else {
                return findStartView(layoutManager, getVerticalHelper(layoutManager));
            }
        }

        return super.findSnapView(layoutManager);
    }



    private View findStartView(RecyclerView.LayoutManager layoutManager,
                              OrientationHelper helper) {
        if (layoutManager instanceof LinearLayoutManager) {
            int firstChild = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition();
            //需要判斷是否是最後一個Item,如果是最後一個則不讓對齊,以免出現最後一個顯示不完全。
            boolean isLastItem = ((LinearLayoutManager) layoutManager)
                    .findLastCompletelyVisibleItemPosition()
                    == layoutManager.getItemCount() - 1;

            if (firstChild == RecyclerView.NO_POSITION || isLastItem) {
                return null;
            }

            View child = layoutManager.findViewByPosition(firstChild);

            if (helper.getDecoratedEnd(child) >= helper.getDecoratedMeasurement(child) / 2
                    && helper.getDecoratedEnd(child) > 0) {
                return child;
            } else {
                if (((LinearLayoutManager) layoutManager).findLastCompletelyVisibleItemPosition()
                        == layoutManager.getItemCount() - 1) {
                    return null;
                } else {
                    return layoutManager.findViewByPosition(firstChild + 1);
                }
            }
        }

        return super.findSnapView(layoutManager);
    }


    private OrientationHelper getHorizontalHelper(
            @NonNull RecyclerView.LayoutManager layoutManager) {
        if (mHorizontalHelper == null) {
            mHorizontalHelper = OrientationHelper.createHorizontalHelper(layoutManager);
        }
        return mHorizontalHelper;
    }

    private OrientationHelper getVerticalHelper(RecyclerView.LayoutManager layoutManager) {
        if (mVerticalHelper == null) {
            mVerticalHelper = OrientationHelper.createVerticalHelper(layoutManager);
        }
        return mVerticalHelper;

    }

}

使用的時候,更改為使用 StartSnapHelper,程式碼如下:

StartSnapHelper snapHelper = new StartSnapHelper();

snapHelper.attachToRecyclerView(mRecyclerView);

效果如下:

以上就實現了一個 Start 對齊的效果,此外,在 Github 上發現一個實現了好幾種 Snap 效果的庫,比如,start 對齊、end 對齊,top 對齊等等。有興趣的可以去弄來玩一下,地址:[Snap 效果庫]。( https://github.com/rubensousa/RecyclerViewSnap )

6 總結

SnapHelper 是對 RecyclerView 的一個擴充套件,可以很方便的實現類似 ViewPager 的效果,比ViewPager 效果更好,當我們要實現卡片式的瀏覽或者相簿照片瀏覽時,使用RecyclerView + SnapHelper 的效果要比 ViewPager 的效果好很多。因此掌握 SnapHelper 的使用技巧,能幫助我們方便的實現一些滑動互動效果,以上就是對 Snapuhelper 的總結,如有問題,歡迎留言交流。本文 Demo 已上傳 Github AndroidTrainingSimples https://github.com/pinguo-zhouwei/AndroidTrainingSimples

參考:

Using SnapHelper in RecyclerView

來自:http://mp.weixin.qq.com/s/DMksgHOuGWhztESGfDgucA


相關推薦

Android 使用 RecyclerView + SnapHelper 實現類似 ViewPager 效果

寫在前面:強大的Recyclerview,官方提供的幫助類. 1 前言 在 一些特定的場景下,如照片的瀏覽,卡片列表滑動瀏覽,我們希望當滑動停止時可以將當前的照片或者卡片停留在螢幕中央,以吸引使用者的焦點。在 Android 中,我們可以使用RecyclerView

Androidrecyclerview+pullToRefresh實現上拉重新整理和下拉載入

一. 依賴 implementation 'com.jwenfeng.pulltorefresh:library:1.0.3' 要把minSdkVersion 改為16以上 二.佈局 <LinearLayout xmlns:android="http:/

Android對文字實現跑馬燈效果

關於在Android中文字實現跑馬燈效果 方法一:(只能實現單個TextView的跑馬燈效果) android:singleLine=”true”只能單行,超出的文字顯示為”…” android:

Android 的用HorizontalScrollView佈局實現類似Gallery效果

setAdjustViewBounds 是否保持寬高比。需要與maxWidth、MaxHeight一起使用,否則單獨使用沒有效果。 以前也使用過Gallery,最初自己的想法也是使用這個,再讓使用

Android自定義View——實現水波紋效果類似剩余流量球

string 三個點 pre ber block span 初始化 move 理解 最近突然手癢就想搞個貝塞爾曲線做個水波紋效果玩玩,終於功夫不負有心人最後實現了想要的效果,一起來看下吧: 效果圖鎮樓 一:先一步一步來分解一下實現的過程 需要繪制一個正弦曲線(sin

RecyclerView實現類似ViewPager翻頁OnPageChangeListener監聽功能

轉載請註明:https://blog.csdn.net/u012854870/article/details/84984066 我們在使用ViewPager的時候多多少少都會遇到一些坑,這裡今天就不細說了。   首先我們先介紹一下SnapHelper Google 在 An

Android應用TabLayout實現頂部Tab小選單加滑動效果

TabLayout控制元件是2015年google大會上,google釋出了新的Android Support Design庫,裡面包含了幾個新的控制元件,其中就有一個TabLayout,它就可以完成TabPageIndicator的效果,而且還是官方的,最好的是它可以相容

AndroidRecyclerView的item控制元件的點選事件新增刪除一行、上移下移一行的程式碼實現

Demo展示圖片 佈局程式碼 // (layout)activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/an

AndroidRecyclerView實現瀑布流圖片顯示

效果圖: 具體程式碼如下:(註釋很詳細,基本每句都要註釋) MainActivity.java package com.zhiyuan3g.recyclerviewwaterfall; import android.content.Intent; import an

Android自定義View實現類似水波擴散效果

自定義View一共分為6步第一步public SpreadView(Context context) { this(context,null,0); } public SpreadView(Context context, @Nullable AttributeSe

AndroidRecyclerview使用13----實現瀑布流遇到的各種問題(item移動,載入更多圖片閃爍,以及定製各種型別Header和Footer)

功能:圖片瀑布流 問題1:如何保持已顯示過的imageview的尺寸 解決方法:定義一個HashMap<Integer, Float> indexMap = new HashMap<Integer, Float>();用來儲存已顯示過的Ima

Android自定義View——實現水波紋效果類似剩餘流量球

最近突然手癢就想搞個貝塞爾曲線做個水波紋效果玩玩,終於功夫不負有心人最後實現了想要的效果,一起來看下吧: 效果圖鎮樓 一:先一步一步來分解一下實現的過程 需要繪製一個正弦曲線(sin)或者餘弦曲線(cos) 通過水平平移曲線來的到像水

Android 兩種方式實現類似水波擴散效果

amp round ini 視覺差 arr arraylist inf nim you 兩種方式實現類似水波擴散效果,先上圖為敬 自定義view實現 動畫實現 ### 自定義view實現 思路分析:通過canvas畫圓,每次改變圓半徑和透明度,當半徑達到一定程度,再次

Android RecyclerView +SnapHelper 實現橫向滾動自動滾動到中心控制元件並選中

效果圖 此效果已被產品砍掉,所以有些適配bug就不修改了 此部落格只為記錄下程式碼 默哀3秒 1秒 2秒 3秒 程式碼 佈局檔案 <?xml version="1.0" encoding="utf-8"?> <

Android使用SVG實現炫酷動畫效果

前言 SVG,即Scalable Vector Graphics 可伸縮向量圖形。這種影象格式在前端中已經使用的非常廣泛,而在移動端的開發中,遇到一些複雜的自定義控制元件或者動畫效果,我們就可以考慮使用SVG。 一.Vector Drawable

androidRecyclerView控件實現長按彈出PopupMenu菜單功能

mage 有一個 手工 sim pat 創建 .get mco span 之前寫過一篇文章:android中實現簡單的聊天功能 現在是在之前功能的基礎上,添加一個長按聊天記錄,刪除對應聊天記錄的功能 RecyclerView控件,沒有對應的長按事件,我們需要自己手工添加

Android使用NavigationView實現抽屜側滑效果Menu選單欄設定

a、在value/styles.xml中定義樣式<!--設定Menu中item的字型大小-->     <style name="WindowTitle" parent="@android:style/TextAppearance">         <item name="a

android利用tablelayout實現表格效果

利用tablelayout佈局,給textview新增邊框的方法實現表格效果 在drawable中新增textview邊框樣式 四周邊框都有 <?xml version="1.0" encoding="utf-8"?> <layer-

AndroidRecyclerView學習(二)----高仿網易新聞欄目動畫效果

之前用TabLayout+RecyclerView實現了CSDN客戶端首頁搭建與Tabs的排序。今天準備用RecyclerView來實現網易新聞Tabs的動態效果。先看效果圖:  點選下面的RecyclerView的item,會有一個view的移動的動畫;動畫完成以後,

Android輪播所用到viewPager.PageTransformer 頁面滑動時候處理圖片縮放效果程式碼

class ScalePagerTransformer implements ViewPager.PageTransformer {         //最小縮放率         private static final float MIN_SCALE = 0.85f;