android开发之仿商城首页Banner图的实现

该博客介绍了如何在Android应用中实现仿商城首页Banner图的动态缩放效果,包括图片的自动滚动和手动拖动时的缩放动画。通过使用ObjectAnimator进行视图缩放,结合ViewPager的滚动事件,实现了平滑的动画联动。同时,博客提供了详细的代码示例,展示了数据绑定和Glide库的使用方法。

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

  实现效果:当banner滚动的时候 首先会缩放当前以及上一个或下一个banner图,当banner滚动时会,背景会随滚动系数变化缩放(自动滚动),下面相关技术人员来分享一下源码:

//0无状态,1缩放,2放大,3不能再播放动画

private int status = 0;

private void fada() {

if (status == 0 || status == 1) {

AnimatorSet animatorSetsuofang = new AnimatorSet();//组合动画

ObjectAnimator scaleX = ObjectAnimator.ofFloat(viewPager, "scaleX", 0.9f, 1f);

ObjectAnimator scaleY = ObjectAnimator.ofFloat(viewPager, "scaleY", 0.9f, 1f);

animatorSetsuofang.setDuration(500);

animatorSetsuofang.setInterpolator(new LinearInterpolator());

animatorSetsuofang.play(scaleX).with(scaleY);//两个动画同时开始

animatorSetsuofang.addListener(new AnimatorListenerAdapter() {

@Override

public void onAnimationStart(Animator animation) {

super.onAnimationStart(animation);

setViewPagerIsScroll(false);

stopAutoPlay();

status = 3;

}

@Override

public void onAnimationEnd(Animator animation) {

super.onAnimationEnd(animation);

setViewPagerIsScroll(true);

Log.e("as", "sa");

startAutoPlay();

status = 2;

}

});

animatorSetsuofang.start();

}

}

private void suoxia() {

if (status == 0 || status == 2) {

AnimatorSet animatorSetsuofang = new AnimatorSet();//组合动画

ObjectAnimator scaleX = ObjectAnimator.ofFloat(viewPager, "scaleX", 1f, 0.9f);

ObjectAnimator scaleY = ObjectAnimator.ofFloat(viewPager, "scaleY", 1f, 0.9f);

animatorSetsuofang.setDuration(200);

animatorSetsuofang.setInterpolator(new LinearInterpolator());

animatorSetsuofang.play(scaleX).with(scaleY);//两个动画同时开始

animatorSetsuofang.addListener(new AnimatorListenerAdapter() {

@Override

public void onAnimationStart(Animator animation) {

super.onAnimationStart(animation);

setViewPagerIsScroll(false);

stopAutoPlay();

status = 3;

}

@Override

public void onAnimationEnd(Animator animation) {

super.onAnimationEnd(animation);

setViewPagerIsScroll(true);

// startAutoPlay();

status = 1;

}

});

animatorSetsuofang.start();

}

}

 

动画联动效果实现:

 

private final Runnable task = new Runnable() {

@Override

public void run() {

if (status == 0 || status == 2) {

AnimatorSet animatorSetsuofang = new AnimatorSet();//组合动画

ObjectAnimator scaleX = ObjectAnimator.ofFloat(viewPager, "scaleX", 1f, 0.9f);

ObjectAnimator scaleY = ObjectAnimator.ofFloat(viewPager, "scaleY", 1f, 0.9f);

animatorSetsuofang.setDuration(300);

animatorSetsuofang.setInterpolator(new LinearInterpolator());

animatorSetsuofang.play(scaleX).with(scaleY);//两个动画同时开始

animatorSetsuofang.addListener(new AnimatorListenerAdapter() {

@Override

public void onAnimationStart(Animator animation) {

super.onAnimationStart(animation);

setViewPagerIsScroll(false);

status = 3;

}

@Override

public void onAnimationEnd(Animator animation) {

super.onAnimationEnd(animation);

setViewPagerIsScroll(true);

if (count > 1 && isAutoPlay) {

currentItem = currentItem % (count + 1) + 1;

// Log.i(tag, "curr:" + currentItem + " count:" + count);

if (currentItem == 1) {

viewPager.setCurrentItem(currentItem, false);

handler.post(task);

} else {

viewPager.setCurrentItem(currentItem);

handler.postDelayed(task, delayTime);

}

}

status = 1;

}

});

animatorSetsuofang.start();

}

}

};

 

缩放(拖动)效果实现:

 

@Override

public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

int num = 0;

if (mOnPageChangeListener != null) {

// Log.e("as", "position" + position + " ----positionOffset " + positionOffset + " positionOffsetPixels" + positionOffsetPixels);

// Log.e(scale);

Log.e("as", imageUrls.size() + "" + " currentItem" + currentItem);

if (positionOffset > 0) {

Log.e("as", "position" + position + " currentItem" + currentItem + "mViewPagerIndex" + mViewPagerIndex);

// Log.e("as", mViewPagerIndex + "");

if (touch) {

if (currentItem == imageUrls.size() + 1) {

Glide.with(context).load(imageUrls.get(0)).into(roundImageView);

Glide.with(context).load(imageUrls.get(0)).into(roundImagetwo);

} else {

if (currentItem == 0) {

Glide.with(context).load(imageUrls.get(imageUrls.size() - 1)).into(roundImageView);

Glide.with(context).load(imageUrls.get(imageUrls.size() - 1)).into(roundImagetwo);

} else {

Glide.with(context).load(imageUrls.get(currentItem - 1)).into(roundImageView);

Glide.with(context).load(imageUrls.get(currentItem - 1)).into(roundImagetwo);

}

}

if (position == mViewPagerIndex) {

Log.e("tt", "左");

if (position == imageUrls.size()) {

num = 0;

} else {

num = position;

}

Glide.with(context).load(imageUrls.get(num)).diskCacheStrategy(DiskCacheStrategy.ALL).into(mImagebg);

roundImageView.setVisibility(VISIBLE);

roundImagetwo.setVisibility(INVISIBLE);

} else {

Log.e("tt", "右");

if (position == 0) {

num = imageUrls.size();

} else {

num = position;

}

Glide.with(context).load(imageUrls.get(num - 1)).diskCacheStrategy(DiskCacheStrategy.ALL).into(mImagebg);

roundImagetwo.setVisibility(VISIBLE);

roundImageView.setVisibility(INVISIBLE);

}

} else {

if (!touchover) {

if (position < currentItem) {

roundImageView.setVisibility(VISIBLE);

roundImagetwo.setVisibility(INVISIBLE);

}

}

if (position == imageUrls.size()) {

Glide.with(context).load(imageUrls.get(0)).diskCacheStrategy(DiskCacheStrategy.ALL).into(mImagebg);

} else if (position == 0) {

num = imageUrls.size();

Glide.with(context).load(imageUrls.get(num - 1)).diskCacheStrategy(DiskCacheStrategy.ALL).into(mImagebg);

} else {

if (position == mViewPagerIndex) {

Glide.with(context).load(imageUrls.get(position)).diskCacheStrategy(DiskCacheStrategy.ALL).into(mImagebg);

} else {

if (!touchover) {

Glide.with(context).load(imageUrls.get(position)).diskCacheStrategy(DiskCacheStrategy.ALL).into(mImagebg);

} else {

Glide.with(context).load(imageUrls.get(position - 1)).diskCacheStrategy(DiskCacheStrategy.ALL).into(mImagebg);

roundImageView.setVisibility(INVISIBLE);

roundImagetwo.setVisibility(VISIBLE);

}

//

}

}

}

//

} else {

roundImagetwo.setVisibility(VISIBLE);

roundImageView.setVisibility(VISIBLE);

if (currentItem == imageUrls.size() + 1) {

Glide.with(context).load(imageUrls.get(0)).into(roundImageView);

Glide.with(context).load(imageUrls.get(0)).into(roundImagetwo);

} else {

if (currentItem == 0) {

Glide.with(context).load(imageUrls.get(imageUrls.size() - 1)).into(roundImageView);

Glide.with(context).load(imageUrls.get(imageUrls.size() - 1)).into(roundImagetwo);

} else {

Glide.with(context).load(imageUrls.get(currentItem - 1)).into(roundImageView);

Glide.with(context).load(imageUrls.get(currentItem - 1)).into(roundImagetwo);

}

}

}

roundImagetwo.setRound(1f - positionOffset);

roundImageView.setRound(positionOffset);

if ((positionOffset == 0) && touch == false) {

fada();

}

mOnPageChangeListener.onPageScrolled(toRealPosition(position), positionOffset, positionOffsetPixels);

}

}

 

轮播图数据绑定

 

banner.setImages(imagebgUrls)

.setImageLoader(new GlideImageLoader())

.setImageList(images)

.start();

  好了,到这里就算是完后才能了,如果大家需要改banner依赖包的setImageList()方法,不然无法在主线程中添加数据,还存在不理解的地方也是可以留言咨询。

  本文由专业的郑州app开发公司燚轩科技整理发布,原创不易,如需转载请注明出处!

现在的APP Banner大多数千篇一律,前几天看到魅族手机上所有魅族自家APP上的Banner效果不错,于是就想着来仿着做一个类似的效果。因此就有了这个库。但是为了使用方便,这个库不仅仅只有仿魅族效果的BannerView 来使用,还可以当作普通的BannerView 来使用,还可以当作一个ViewPager 来使用。使用很方便,具体使用方法和API 请看后面的示例。 ---  左为魅族APP上的Banner效果,右是高仿效果。MZBannerView 有以下功能:1 . 仿魅族BannerView 效果。2 . 当普通Banner 使用3 . 当普通ViewPager 使用。4 . 当普通ViewPager使用(有魅族Banner效果)5 . 仿某视频网站Banner效果。Demo APKgif片有点模糊,可以扫描下方二维码下载APK体验相关博客ViewPager系列之 仿魅族应用的广告BannerView更新日志v1.1.1 : 增加按住Banner 停止轮播,松开开始自动轮播的功能v1.1.0 : fix 在从网上获取数据后,banner 显示 造成 ANR 的bug(如果在onCreate()中设置资源显示则没问题)v1.1.2 : fix 更改数据之后,调用setPages重新刷新数据会crush的bugv2.0.0 :1,add: 添加仿魅族Banner效果,中间Page覆盖两边。 -- 2,fix 部分bug: 添加OnPageChangeListener 回调 pisition 不对的bug.DependencyAdd it in your root build.gradle at the end of repositories:allprojects {      repositories {           ...           maven { url 'https://jitpack.io' }      } }Step 2. Add the dependencydependencies {          compile 'com.github.pinguo-zhouwei:MZBannerView:v2.0.0' }自定义属性属性名属性意义取值open_mz_mode是否开启魅族模式true 为魅族Banner效果,false 则普通Banner效果canLoop是否轮播true 轮播,false 则为普通ViewPagerindicatorPaddingLeft设置指示器距离左侧的距离单位为 dp 的值indicatorPaddingRight设置指示器距离右侧的距离单位为 dp 的值indicatorAlign设置指示器的位置有三个取值:left 左边,center 剧中显示,right 右侧显示middle_page_cover设置中间Page是否覆盖(真正的魅族Banner效果)true 覆盖,false 无覆盖效果使用方法1 . xml 布局文件2 . activity中代码:mMZBanner = (MZBannerView) view.findViewById(R.id.banner);              // 设置数据         mMZBanner.setPages(list, new MZHolderCreator() {             @Override             public BannerViewHolder createViewHolder() {                 return new BannerViewHolder();             }         });  public static class BannerViewHolder implements MZViewHolder {         private ImageView mImageView;         @Override         public View createView(Context cont
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值