android首页新颖,Android仿转转首页banner

这篇博客分享了一种在Android中实现高大上轮播图效果的方法,包括底部背景的reveal动画和上层图片的缩放效果。通过ViewPager和属性动画,创建了一个可循环播放并带有联动背景的轮播组件。虽然最终效果与目标略有出入,但代码已上传至GitHub供参考和进一步优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2475a15ee5d2?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

banner_g--.gif

效果由来

我司设计一向比较喜欢高大上的东西(我也喜欢...),无意中看到转转首页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();

}

}

}

}

使用方法

在 app的build.gradle 里面引用

implementation 'com.tokiii:reveal-banner:1.0.0'

布局文件

android:layout_width="match_parent"

android:layout_height="240dp">

android:id="@+id/banner_bg_container"

android:layout_width="match_parent"

android:layout_height="240dp" />

android:id="@+id/loop_layout"

android:layout_width="match_parent"

android:layout_height="168dp"

android:layout_gravity="bottom" />

代码设置属性

// 设置轮播图属性

loopLayout.setLoop_ms(3000);//轮播的速度(毫秒)

loopLayout.setLoop_duration(400);//滑动的速率(毫秒)

loopLayout.setScaleAnimation(true);// 设置是否需要动画

loopLayout.setLoop_style(LoopStyle.Empty);//轮播的样式-默认empty

loopLayout.setIndicatorLocation(IndicatorLocation.Center);//指示器位置-中Center

loopLayout.initializeData(this);

// 设置轮播图属性end

// 准备数据

ArrayList bannerInfos = new ArrayList<>();

List bgList = new ArrayList<>();

bannerInfos.add(new BannerInfo(R.mipmap.banner_1, "first"));

bannerInfos.add(new BannerInfo(R.mipmap.banner_2, "second"));

bgList.add(R.mipmap.banner_bg1);

bgList.add(R.mipmap.banner_bg2);

// 设置监听

loopLayout.setOnLoadImageViewListener(new OnDefaultImageViewLoader() {

@Override

public void onLoadImageView(ImageView view, Object object) {

Glide.with(view.getContext())

.load(object)

.into(view);

}

});

loopLayout.setOnBannerItemClickListener(this);

if (bannerInfos.size() == 0) {

return;

}

loopLayout.setLoopData(bannerInfos);// 设置轮播数据

bannerBgContainer.setBannerBackBg(this, bgList);// 背景容器设置轮播图片

loopLayout.setBannerBgContainer(bannerBgContainer);// 联动

loopLayout.startLoop();// 开始循环

后记

详细请看具体代码已经上传到Github ,由于时间仓促,实际效果与转转还是多少有些不同,代码注释较少,等后续优化接近完美会补上关键代码逻辑和原理(也没有多复杂),敬请期待.....

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值