ViewPage2 的使用相信各位大佬都信手拈来了 这里就跳过设置Adapter的步骤直接来研究他的这个PageTransformer
1 先看API
ViewPage2.setPageTransformer(@Nullable PageTransformer transformer)
less
public void setPageTransformer(@Nullable PageTransformer transformer)
public interface PageTransformer
less
void transformPage(@NonNull View page, float position);
PageTransformer 接口只有一个方法 transformPage(View page, float position) 。 page就是被移动的视图,position如上解释,代表偏移量。
其中Page 在滑动过程中会被多次回调,并且每次回调的都不一定是同一个Page。因为当你在滑动中时候 你的 page0 (当前current Position)往左,而右边的page1 也会跟着一起移动,而后面的page2 也会同步移动 。其实右边的page1 和page2 的数量是 ,下面的这api的缓存数量来决定的
less
public void setOffscreenPageLimit(@OffscreenPageLimit int limit)
当你的 OffscreenPageLimit = 1 ,那么默认 page1会加载。如果你的 OffscreenPageLimit 是2 。那么page2 会被加载,所以得看你的滑动动画ui表现。所以一般情况是不需要使用到page2的视图。所以设置 OffscreenPageLimit = 1 即可
"所以一般情况是不需要使用到page2的视图" 这里意思是,你的滑动中根本看不到page2的ui。所以不需要提前加载page2
分析OffscreenPageLimit = 1
代表缓存中会预加载加载左右两页,其实Viewpage2 内部使用RecycleView来维护的
分析transformPage
接口 PageTransformer 在滑动中回调
less
void transformPage(@NonNull View page, float position);
而这里会被多次回调,其中如果默认冲position = 0 第一位开始的话 View page 将会是 page0 与 page1 。意思是transformPage每次回调有可能是page0 ,也有可能是page1 ,在滑动的时候。那么如何知道滑动的距离和情况呢。现在就得观察Postion的变化。
观察Postion
问题一 pageX任意一个 , postion = 0.5是什么意思
ini
答:说明有一个页面右滑滑到了当前Viewpage 右边的一半距离了,如图,就说明page1滑到了一半。这里前提是当前的current == 1 ,反之如果是current == 0 就是左滑
问题二 Position [0,1],[-1,0] 含义
sql
答:其实Postion是针对可视区域(current)来说的,就是代表当前可视在屏幕中偏移量
0就是完全处于正常居中展示,1就是代表在当前的右边,-1就是在左边
设置属于自己的PageTransformer
less
public class ViewpageActivity extends AppCompatActivity {
@NonNull
ActivityViewpageBinding activityViewpageBinding;
int[] colors = {Color.BLACK, Color.DKGRAY, Color.GRAY, Color.LTGRAY, Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW, Color.CYAN, Color.MAGENTA};
private int indexColor = 0;
int getColorByIndex() {
int c = colors[indexColor++];
if (indexColor == colors.length) {
indexColor = 0;
}
return c;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_viewpage);
activityViewpageBinding = DataBindingUtil.setContentView(this, R.layout.activity_viewpage);
activityViewpageBinding.idViewpage.setOffscreenPageLimit(1);
activityViewpageBinding.idViewpage.setAdapter(new RecyclerView.Adapter<SimpleHodler>() {
@NonNull
@Override
public SimpleHodler onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new SimpleHodler(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_bg, parent, false));
}
@Override
public void onBindViewHolder(@NonNull SimpleHodler holder, int position) {
holder.contentView.setBackgroundColor(getColorByIndex());
}
@Override
public int getItemCount() {
return Integer.MAX_VALUE;
}
});
activityViewpageBinding.idViewpage.setCurrentItem(Integer.MAX_VALUE / 2);
activityViewpageBinding.idViewpage.addItemDecoration(new RecyclerView.ItemDecoration() {
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
outRect.right = 100;
outRect.left = 100;
}
});
activityViewpageBinding.idViewpage.setPageTransformer(new ViewPager2.PageTransformer() {
@Override
public void transformPage(@NonNull View page, float position) {
page.setTranslationX(-150 * position);
}
});
}
static class SimpleHodler extends RecyclerView.ViewHolder {
View contentView;
public SimpleHodler(@NonNull View itemView) {
super(itemView);
contentView = itemView.findViewById(R.id.id_view);
}
}
}
page.setTranslationX(-150 * position); 核心代码,就是让左右两边挤过来。
可以这样尝试理解;
当你左边不滑动时候,这个左page TranslationX = -150 * -1 = 150 ;向右迁移150个像素
当你右边不滑动时候,这个右page TranslationX = -150 * 1 = -150 ;向左迁移150个像素
再配合 ItemDecoration outRect.right = 100; outRect.left = 100; 给每个page增加左右100像素间距
这是就是简单的卡片效果
如果你想加其他效果比如放大/缩小
less
activityViewpageBinding.idViewpage.setPageTransformer(new ViewPager2.PageTransformer() {
@Override
public void transformPage(@NonNull View page, float position) {
page.setTranslationX(-350 * position);
page.setScaleX(1 - Math.abs(position) * 0.4f);
page.setScaleY(1 - Math.abs(position) * 0.4f);
}
});
其他效果比如透明度和旋转
less
activityViewpageBinding.idViewpage.setPageTransformer(new ViewPager2.PageTransformer() {
@Override
public void transformPage(@NonNull View page, float position) {
page.setTranslationX(-350 * position);
page.setScaleX(1 - Math.abs(position) * 0.4f);
page.setScaleY(1 - Math.abs(position) * 0.4f);
page.setAlpha(1 - Math.abs(position) * 0.7f);
page.setRotation(10 * position);
}
});
总结
只要使用中把握住 -1,0,1的变量即可。比如 你需要一个透明渐变 在左右两边是 0.5f alpha,那么你可以先写好,最基本的3个固定值用来观测
左边, position = -1 写成 setAlpha(--1 * 0.5)
中间, position = 0 任意 setAlpha(0 * 0.5)
右边边,position = 1 写成 setAlpha(1 * 0.5)
所以但你要综合情况的时候得出 page.setAlpha(1 - Math.abs(position) * 0.7f); 这公式既满足了 position = -1 也满足 position = 1 也满足 position = 0 。这个代码就是最终的表现方式
其他的也一样道理,如果情况很复杂还可以分别判断
scss
if(position >= 0 ){
****
}else if(postion <0){
****
}
好了希望能帮到有需要的人