在项目开发过程中,我们经常会收到广告轮播图的需求。之前都是用Viewpager来实现,也用到了些许第三方的的广告轮播库。今天介绍下基于RecyclerView实现广告轮播效果。
主要实现了:
主要方法如下:
方法名 | 作用 |
---|---|
setIndicatorWH(int widht,int height) | 设置单个指示器的高度和宽度 |
setIndicatorMargin(int margin) | 指示器间距 |
setIndicatorDrawableId(int indicatorDrawableId) | 设置指示器样式 |
setDelayTime(int time) | 设置Banner停留时间 |
setSpeend(int speed) | 设置广告滑动速度 |
setIsAutoPlay(boolean isAutoPlay) | 是否开启自动轮播 |
setBannerLayout(int bannerLayout) | 设置自定义布局(Banner图布局) |
setListData(List list) | 设置数据源 |
setCallBack(BannerAdapterCallBack callBack) | 设置回掉 |
start() | 开始轮播(所有属性设置完后,需要调用此方法) |
pauseAutoPlay() | 暂停轮播 |
continueAutoPlay() | 继续轮播 |
stopAutoPlay() | 停止轮播 |
setIndicatorGravity(int gravity) | 设置指示器的位置(左、右、居中) |
releaseBanner() | 释放BannerView(可在页面销毁时调用) |
主要attrs属性:
属性 | 作用 |
---|---|
app:indicatorheight | 单个指示器高度 |
app:indicatorwidth | 单个指示器宽度 |
app:delaytime | 延迟时间 |
app:isautoplay | 是否开启自动轮播 |
app:indicatorgravity | 指示器位置 |
app:indicatordrawable | 指示器样式 |
app:speed | 轮播速度 |
一. BannerView 无限滚动
在RecyclerView的Adapter设置数据源无限大,这样的RecyclerView,就可以无限滚动呢。
@Override
public int getItemCount() {
return mList == null || mList.size() == 0 ? 0 : Integer.MAX_VALUE;
}
onBindViewHolder 中设置数据源的需要注意:
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
T t = mList.get(position%mList.size());
if (mCallBack == null)
{
Toast.makeText(context,"请接入回掉监听",Toast.LENGTH_LONG).show();
return;
}
mCallBack.onCallBack(holder.itemView,t);
}
二. 自动轮播
这里采用Handler发送延迟消息的形式实现。因为Handler可能导致内存泄漏,这里特意引用了一个第三方的WeakHandler了。
protected WeakHandler handler = new WeakHandler();
handler.removeCallbacks(task);
handler.postDelayed(task,mDelayTime);
protected final Runnable task = new Runnable() {
@Override
public void run() {
if (isAutoPlay)
{
if (maxBannerCount < 1)
{
// 当前没有广告
return;
}
// 处理自动轮询
mCurrentBannerPosition ++;
Log.d(TAG,"当前位置:"+mCurrentBannerPosition+"总大小:"+maxBannerCount);
mRecyclerView.smoothScrollToPosition(mCurrentBannerPosition);
moveIndicator(mCurrentBannerPosition);
}
// 继续轮询
handler.postDelayed(this,mDelayTime);
}
};
三. ReyclerView+PagerSnapHelper 实现ViewPager效果(这个具体的可以参照我上一片文章)
// 设置一次翻一项
PagerSnapHelper pagerSnapHelper = new PagerSnapHelper()
{
@Override
public int findTargetSnapPosition(RecyclerView.LayoutManager layoutManager, int velocityX, int velocityY) {
// 当前滑动的项
int target = super.findTargetSnapPosition(layoutManager, velocityX, velocityY);
// 联动指示器
moveIndicator(target);
return target;
}
};
pagerSnapHelper.attachToRecyclerView(mRecyclerView);
四. 自定义样式
调用setBannerLayout(int bannerLayout)方法设置自定义的布局;
mBannerView3.setBannerLayout(R.layout.item_banner_1);
然后通过BannerAdapterCallBack回掉自己处理:
mBannerView3.setCallBack(new BannerAdapterCallBack() {
@Override
public void onCallBack(View view, BannerBean1 bannerBean1) {
SimpleDraweeView simpleDraweeView = view.findViewById(R.id.item_simleDraweeview);
TextView textView = view.findViewById(R.id.item_title);
simpleDraweeView.setImageURI(bannerBean1.getCover());
textView.setText(bannerBean1.getTitle());
}
});
五. 设置滑动时间
这里设置滑动时间,其实就是设置smoothScrollToPosition的滑动时间。可通过LinearLayoutManager中smoothScrollToPosition进行设置,通过设置滑动1像素需要多长时间来实现。
LinearLayoutManager layoutManager = new LinearLayoutManager(context)
{
@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
// super.smoothScrollToPosition(recyclerView, state, position);
// 此处用户设置滑动速度
LinearSmoothScroller smoothScroller =
new LinearSmoothScroller(recyclerView.getContext()) {
// 返回:滑过1px时经历的时间(ms)。
@Override
protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
return mSmoothSpeed / displayMetrics.densityDpi;
}
};
smoothScroller.setTargetPosition(position);
startSmoothScroll(smoothScroller);
}
};
五. 自定义数据源
可以传入任意类型的数据源,通过调用:
mBannerView3.setListData(mListForB3);
需要完整的代码,请转到我的github主页,里面有详细的使用步骤:https://github.com/zlwmzh/BannerView