Google I / O2019アップデート
ViewPager2はこちらです!
Googleはちょうど発表しました「のAndroidの新機能」の話で(別名「Androidの基調講演」)彼らはRecyclerViewに基づく新しいViewPagerに取り組んでいることを!
スライドから:
ViewPagerと似ていますが、より優れています
- ViewPagerからの簡単な移行
- RecyclerViewに基づく
- 右から左へのモードのサポート
- 垂直ページングを許可します
- 改善されたデータセット変更通知
最新バージョンはこちらとリリースノートで確認できますこちらでます。公式サンプルもあります。
個人的な意見:これは本当に必要な追加だと思います。私は最近、多くの問題を抱えていますPagerSnapHelper
左右に無期限に振動ます-私が開いたチケットを参照してください。
新しい答え(2016)
これで、SnapHelperを使用できます。
ViewPagerと同様の中央揃えのスナップ動作が必要な場合は、PagerSnapHelperを使用してください。
SnapHelper snapHelper = new PagerSnapHelper();
snapHelper.attachToRecyclerView(recyclerView);
もあります LinearSnapHelperます。私はそれを試しました、そしてあなたがエネルギーで投げるならば、それは1つの投げで2つのアイテムをスクロールします。個人的には気に入らなかったのですが、自分で決めるだけです。試してみるのはほんの数秒です。
元の回答(2016)
SOで見つかった3つの異なるソリューションを何時間も試した後、私はついに、で見つかった動作を非常によく模倣するソリューションを構築しました。ViewPager
。
このソリューションは、@ eDizzleソリューションに基づいています。これは、ほぼのように機能すると言えるほど改善されたと思いますViewPager
。
重要:RecyclerView
アイテムの幅は画面とまったく同じです。他のサイズは試していません。また、横型で使用していLinearLayoutManager
ます。垂直スクロールが必要な場合は、コードを調整する必要があると思います。
ここにコードがあります:
public class SnappyRecyclerView extends RecyclerView {
public SnappyRecyclerView(Context context) {
super(context);
}
public SnappyRecyclerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public SnappyRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean fling(int velocityX, int velocityY) {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) getLayoutManager();
int screenWidth = Resources.getSystem().getDisplayMetrics().widthPixels;
int lastVisibleItemPosition = linearLayoutManager.findLastVisibleItemPosition();
View lastView = linearLayoutManager.findViewByPosition(lastVisibleItemPosition);
int firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition();
View firstView = linearLayoutManager.findViewByPosition(firstVisibleItemPosition);
int leftMargin = (screenWidth - lastView.getWidth()) / 2;
int rightMargin = (screenWidth - firstView.getWidth()) / 2 + firstView.getWidth();
int leftEdge = lastView.getLeft();
int rightEdge = firstView.getRight();
int scrollDistanceLeft = leftEdge - leftMargin;
int scrollDistanceRight = rightMargin - rightEdge;
if (Math.abs(velocityX) < 1000) {
if (leftEdge > screenWidth / 2) {
smoothScrollBy(-scrollDistanceRight, 0);
} else if (rightEdge < screenWidth / 2) {
smoothScrollBy(scrollDistanceLeft, 0);
} else {
if (velocityX > 0) {
smoothScrollBy(-scrollDistanceRight, 0);
} else {
smoothScrollBy(scrollDistanceLeft, 0);
}
}
return true;
} else {
if (velocityX > 0) {
smoothScrollBy(scrollDistanceLeft, 0);
} else {
smoothScrollBy(-scrollDistanceRight, 0);
}
return true;
}
}
@Override
public void onScrollStateChanged(int state) {
super.onScrollStateChanged(state);
if (state == SCROLL_STATE_IDLE) {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) getLayoutManager();
int screenWidth = Resources.getSystem().getDisplayMetrics().widthPixels;
int lastVisibleItemPosition = linearLayoutManager.findLastVisibleItemPosition();
View lastView = linearLayoutManager.findViewByPosition(lastVisibleItemPosition);
int firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition();
View firstView = linearLayoutManager.findViewByPosition(firstVisibleItemPosition);
int leftMargin = (screenWidth - lastView.getWidth()) / 2;
int rightMargin = (screenWidth - firstView.getWidth()) / 2 + firstView.getWidth();
int leftEdge = lastView.getLeft();
int rightEdge = firstView.getRight();
int scrollDistanceLeft = leftEdge - leftMargin;
int scrollDistanceRight = rightMargin - rightEdge;
if (leftEdge > screenWidth / 2) {
smoothScrollBy(-scrollDistanceRight, 0);
} else if (rightEdge < screenWidth / 2) {
smoothScrollBy(scrollDistanceLeft, 0);
}
}
}
}
楽しい!