先贴图

85bf072bfeed

要实现上面的画廊效果,传统通过ViewPager clipChildren置为false实现。网上很多教程这个不多说,现在说说用RecyclerView实现上面的效果。这个效果分两步:

ViewPager滑动最终居中停止

滑动过程中缩放

ViewPager滑动最终居中停止

Support RecyclerView 24.2.0中增加一个非常重要的类SnapHelper,他的作用是让RecyclerView滑动视图后使停止位置正好停在某页的正中间。使用方式很简单

重点在于new LinearSnapHelper().attachToRecyclerView(recyclerView);

LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false);

recyclerView.setLayoutManager(linearLayoutManager);

new LinearSnapHelper().attachToRecyclerView(recyclerView);

滑动过程中缩放

毫无疑问,RecyclerView的滑动缩放必须要监听RecyclerView的滑动

mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {

@Override

public void onScrolled(RecyclerView recyclerView, int dx, int dy) {

super.onScrolled(recyclerView, dx, dy);

// dx>0则表示右滑, dx<0表示左滑, dy<0表示上滑, dy>0表示下滑

mCurrentItemOffset += dx;

computeCurrentItemPos();

onScrolledChangedCallback();

}

});

mCurrentItemOffset为滑动总距离,Card每页滑动的距离是固定的,根据这个可以计算出当前显示的位置。缩放看onScrolledChangedCallback这个函数,有了滑动位置就能实时计算滑动某页的百分比

float percent = (float) Math.max(Math.abs(offset) * 1.0 / mOnePageWidth, 0.0001);

得到百分比, 再获取当前位置相邻的视图调用setScaleY函数实现缩放

/**

* RecyclerView位移事件监听, view大小随位移事件变化

*/

private void onScrolledChangedCallback() {

int offset = mCurrentItemOffset - mCurrentItemPos * mOnePageWidth;

float percent = (float) Math.max(Math.abs(offset) * 1.0 / mOnePageWidth, 0.0001);

View leftView = null;

View currentView;

View rightView = null;

if (mCurrentItemPos > 0) {

leftView = mRecyclerView.getLayoutManager().findViewByPosition(mCurrentItemPos - 1);

}

currentView = mRecyclerView.getLayoutManager().findViewByPosition(mCurrentItemPos);

if (mCurrentItemPos < mRecyclerView.getAdapter().getItemCount() - 1) {

rightView = mRecyclerView.getLayoutManager().findViewByPosition(mCurrentItemPos + 1);

}

if (leftView != null) {

// y = (1 - mScale)x + mScale

leftView.setScaleY((1 - mScale) * percent + mScale);

}

if (currentView != null) {

// y = (mScale - 1)x + 1

currentView.setScaleY((mScale - 1) * percent + 1);

}

if (rightView != null) {

// y = (1 - mScale)x + mScale

rightView.setScaleY((1 - mScale) * percent + mScale);

}

}

完整代码下载

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐