如何实现MakeMyTrip‘Hot Deals’板块视图及卡片滑动换图效果?
实现MakeMyTrip风格Hot Deals卡片滑动时的图片切换效果
既然你已经基于卡片式ViewPager完成了基础布局,要实现滑动卡片时同步切换图片(和MakeMyTrip的Hot Deals效果一致),可以通过监听ViewPager的页面切换事件,配合平滑过渡动画来实现,以下是具体步骤和代码示例:
核心思路
MakeMyTrip的Hot Deals板块在卡片滑动时,通常会同步切换顶部主图(或卡片关联的图片),并伴随流畅的过渡动画。我们需要:
- 绑定卡片位置与对应图片资源
- 监听ViewPager的页面切换状态
- 在页面选中/滑动过程中切换图片并添加动画
具体实现步骤
1. 准备图片资源与布局引用
首先,定义每个卡片对应的图片资源数组,并获取布局中的ViewPager和目标ImageView(比如顶部主图):
// 示例:存储每个卡片对应的图片资源ID(如果是网络图则用URL数组) private int[] hotDealImages = {R.drawable.deal_hotel, R.drawable.deal_flight, R.drawable.deal_bus, R.drawable.deal_train}; private ViewPager cardViewPager; // 你的卡片ViewPager private ImageView mainDealImageView; // 需要切换的目标图片View
2. 监听ViewPager页面切换事件
通过OnPageChangeListener(ViewPager)或OnPageChangeCallback(ViewPager2)监听页面状态,实现图片切换:
针对ViewPager的实现:
cardViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { // 可选:添加视差效果,让图片滑动速度慢于卡片,增强层次感 mainDealImageView.setTranslationX(-positionOffsetPixels * 0.3f); } @Override public void onPageSelected(int position) { // 切换图片并添加淡入淡出过渡动画,匹配MakeMyTrip的流畅度 TransitionDrawable transition = new TransitionDrawable(new Drawable[]{ mainDealImageView.getDrawable(), getResources().getDrawable(hotDealImages[position]) }); mainDealImageView.setImageDrawable(transition); transition.startTransition(300); // 300ms过渡时间,可根据需求调整 } @Override public void onPageScrollStateChanged(int state) { // 可选:处理滑动状态(比如开始滑动时暂停动画,结束时恢复) } });
针对ViewPager2的实现(推荐,因为ViewPager已被弃用):
cardViewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { @Override public void onPageSelected(int position) { super.onPageSelected(position); // 使用Glide加载图片并添加过渡动画,更适合网络图片场景 Glide.with(MainActivity.this) .load(hotDealImages[position]) .transition(DrawableTransitionOptions.withCrossFade(300)) .into(mainDealImageView); } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { super.onPageScrolled(position, positionOffset, positionOffsetPixels); // 同样可以添加视差效果 mainDealImageView.setTranslationX(-positionOffsetPixels * 0.3f); } });
3. 优化体验:预加载图片
为了避免滑动时图片加载卡顿,提前预加载所有图片资源(以Glide为例):
for (int imageRes : hotDealImages) { Glide.with(this).load(imageRes).preload(); }
4. 可选:卡片缩放联动效果
如果要和MakeMyTrip的卡片缩放效果匹配,可以在onPageScrolled中添加卡片缩放逻辑:
@Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { // 遍历ViewPager的子View,调整卡片缩放比例 for (int i = 0; i < cardViewPager.getChildCount(); i++) { View card = cardViewPager.getChildAt(i); float offset = Math.abs((position - i) + positionOffset); // 缩放系数:当前卡片最大,相邻卡片缩小 float scaleFactor = 1 - 0.1f * offset; card.setScaleX(scaleFactor); card.setScaleY(scaleFactor); } // 图片视差 mainDealImageView.setTranslationX(-positionOffsetPixels * 0.3f); }
关键注意点
- 过渡动画时长建议设置在250-350ms之间,和主流APP的流畅度保持一致
- 如果是网络图片,务必使用图片加载库(如Glide、Picasso)处理缓存和加载状态
- 视差效果的系数(比如0.3)可以根据实际UI调整,达到自然的联动效果
内容的提问来源于stack exchange,提问作者taru khan
相关产品推荐
相关产品推荐

