Android仿转转首页banner
2018-08-01 本文已影响474人
卷卷更健康
banner_g--.gif
代码地址:Github
效果由来
我司设计一向比较喜欢高大上的东西(我也喜欢...),无意中看到转转首页banner动画不错,想得之,由于项目工期和人手限制,遭到IOS开发和我的强烈反对,设计也即将妥协,我抱着猎奇心态(手欠)搜了下网上看看有没有类似效果,结果让我搜到了iOS版本 ,iOS开发欢心集成,我则愁眉苦展,辗转两天之久,出此代码.
具体效果
- 底部背景图片随着banner滚动实现reveal效果
- banner上层图片缩放效果
实现原理
- 上层banner用viewPager实现,通过handler定时发送消息实现可循环自动播放的banner
- 下层背景图片通过多张图片折叠,然后通过viewPager滚动监听来操作底部图片的显示和隐藏
- 缩放动画用属性动画实现,根据viewPager滑动停止和移动判断是否放大或缩小
特性
- 可独立拆分使用,设置属性可变为普通banner,修改如需特殊要求可修改源码item_banner.xml布局即可
部分关键代码
private class ViewPageChangeListener implements ViewPager.OnPageChangeListener {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// 判断viewPager左右滑动相关
if (mViewPagerIndex == position) {
if (bannerBgContainer.getBannerBgViews().size() > position % bannerBgContainer.getBannerBgViews().size() + 1) {
bannerBgContainer.getBannerBgViews().get(position % bannerBgContainer.getBannerBgViews().size() + 1).bringToFront();
bannerBgContainer.getBannerBgViews().get(position % bannerBgContainer.getBannerBgViews().size() + 1)
.hideClipAnimation((positionOffset - reduceValue) * upValue > 1 ? 1 : (positionOffset - reduceValue) * upValue);
} else if (bannerBgContainer.getBannerBgViews().size() == position % bannerBgContainer.getBannerBgViews().size() + 1) {
bannerBgContainer.getBannerBgViews().get(0).bringToFront();
bannerBgContainer.getBannerBgViews().get(0)
.hideClipAnimation((positionOffset - reduceValue) * upValue > 1 ? 1 : (positionOffset - reduceValue) * upValue);
}
} else {
if (position / bannerBgContainer.getBannerBgViews().size() >= 0) {
bannerBgContainer.getBannerBgViews().get(position % bannerBgContainer.getBannerBgViews().size()).bringToFront();
bannerBgContainer.getBannerBgViews().get(position % bannerBgContainer.getBannerBgViews().size())
.showClipAnimation(0, bannerBgContainer.getHeight() / 2,
(1 - (positionOffset + reduceValue)) * upValue > 1 ? 1 : (1 - (positionOffset + reduceValue)) * upValue);
}
}
}
@Override
public void onPageSelected(int position) {
int i = position % bannerInfos.size();
if (i == 0) {
animIndicator.setTranslationX(totalDistance * 0.0f);
} else if (i == bannerInfos.size() - 1) {
animIndicator.setTranslationX(totalDistance * 1.0f);
}
// 不是手动拖拽时, 当前position 减1 因为setCurrentItem方法会在滑动之前把position设置成当前位置(此处是坑)
mViewPagerIndex = position - 1;
}
@Override
public void onPageScrollStateChanged(int state) {
// 如果是手动拖拽,则取当前位置
if (state == 1) {
if (loopViewPager != null) {
mViewPagerIndex = loopViewPager.getCurrentItem();
}
}
}
}
后记
详细请看具体代码已经上传到Github ,由于时间仓促,实际效果与转转还是多少有些不同,代码注释较少,等后续优化接近完美会补上关键代码逻辑和原理(也没有多复杂),敬请期待.....