运行效果如下,这里展示的是条形指示器的效果,你可以改成圆点形式的也:
不好意思视频转gif图的时候翻转角度出问题了
自定义banner控件BannerView:
/**
* Created by wjj on 18/12/20 20:40
* [email protected]
* 自定义无限轮播banner控件
*/
public class BannerView extends RelativeLayout implements BannerAdapter.ViewPagerOnItemClickListener {
ViewPager viewPager;
LinearLayout points;
//默认轮播时间,3s
private int delayTime = 3000;
private List imageViewList;
private List bannerList;
//选中显示Indicator 小圆点样式
// private int selectRes = R.drawable.shape_dots_select;
//条形指示器样式
private int selectRes = R.drawable.shape_line_select;
//非选中显示Indicator
// private int unSelcetRes = R.drawable.shape_dots_default;
private int unSelcetRes = R.drawable.shape_line_default;
//当前页的下标
private int currentPos;
private Handler handler ;
public ViewPager getViewPager() {
return viewPager;
}
public BannerView(Context context) {
this(context, null);
initView();
}
public BannerView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
initView();
}
public BannerView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
LayoutInflater.from(getContext()).inflate(R.layout.layout_custom_banner, this, true);
imageViewList = new ArrayList<>();
initView();
}
private void initView() {
viewPager = findViewById(R.id.layout_banner_viewpager);
points = findViewById(R.id.layout_banner_points_group);
}
/**
* 设置轮播间隔时间
*
* @param time 轮播间隔时间,单位秒
*/
public BannerView delayTime(int time) {
this.delayTime = time;
return this;
}
/**
* 设置Points资源 Res
*
* @param selectRes 选中状态
* @param unselcetRes 非选中状态
*/
public void setPointsRes(int selectRes, int unselcetRes) {
this.selectRes = selectRes;
this.unSelcetRes = unselcetRes;
}
/**
* 图片轮播需要传入参数
*/
public void build(List list) {
destroy();
if (list.size() == 0) {
this.setVisibility(GONE);
return;
}
bannerList = new ArrayList<>();
bannerList.addAll(list);
final int pointSize;
pointSize = bannerList.size();
if (pointSize == 2) {
bannerList.addAll(list);
}
//判断是否清空 指示器点
if (points.getChildCount() != 0) {
points.removeAllViewsInLayout();
}
//初始化与个数相同的指示器点
for (int i = 0; i < pointSize; i++) {
View dot = new View(getContext());
dot.setBackgroundResource(unSelcetRes);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
// DipDpUtil.dip2px(getContext(), 5),
// DipDpUtil.dip2px(getContext(), 5));
DipDpUtil.dip2px(getContext(), 13),
DipDpUtil.dip2px(getContext(), 2));
params.leftMargin = DipDpUtil.dip2px(getContext(), 4);
dot.setLayoutParams(params);
dot.setEnabled(false);
points.addView(dot);
}
points.getChildAt(0).setBackgroundResource(selectRes);
for (int i = 0; i < bannerList.size(); i++) {
ImageView mImageView = new ImageView(getContext());
mImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT
);
mImageView.setLayoutParams(p);
if(!StringUtils.StringIsNull(bannerList.get(i).getWurl_preview())){
mImageView.setImageResource(R.drawable.home_top_loadpic);
}else {
Glide.with(getContext())
.load(bannerList.get(i).getWurl_middle())
.apply(RequestOptions
.bitmapTransform(new GlideRoundTransform2(getContext(),8))
.placeholder(R.drawable.home_top_loadpic)
.error(R.drawable.home_top_loadpic)
.diskCacheStrategy(DiskCacheStrategy.ALL))
.into(mImageView);
Log.d("bannerview","--url"+bannerList.get(i).getWurl_preview());
}
imageViewList.add(mImageView);
}
//监听图片轮播,改变指示器状态
viewPager.clearOnPageChangeListeners();
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
@Override
public void onPageSelected(int pos) {
pos = pos % pointSize;
currentPos = pos;
for (int i = 0; i < points.getChildCount(); i++) {
points.getChildAt(i).setBackgroundResource(unSelcetRes);
}
points.getChildAt(pos).setBackgroundResource(selectRes);
}
@Override
public void onPageScrollStateChanged(int state) {
switch (state) {
// 闲置中
case ViewPager.SCROLL_STATE_IDLE:
isAutoPlay = true;
break;
// 拖动中
case ViewPager.SCROLL_STATE_DRAGGING:
isAutoPlay = false;
break;
// 设置中
case ViewPager.SCROLL_STATE_SETTLING:
isAutoPlay = true;
break;
}
}
});
BannerAdapter bannerAdapter = new BannerAdapter(imageViewList);
viewPager.setAdapter(bannerAdapter);
bannerAdapter.notifyDataSetChanged();
bannerAdapter.setmViewPagerOnItemClickListener(this);
//图片开始轮播
startScroll();
}
private boolean isAutoPlay = false;
/**
* 图片开始轮播
*/
private void startScroll() {
// 如果少于2张就不用自动播放了
if (bannerList.size() < 2) {
isAutoPlay = false;
} else {
isAutoPlay = true;
handler = new Handler();
handler.postDelayed(task, delayTime);
}
}
private Runnable task = new Runnable() {
@Override
public void run() {
if (isAutoPlay) {
// 正常每隔3秒播放一张图片
viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);
// vpImageTitle.setCurrentItem(currentItem);
handler.postDelayed(task, 3000);
} else {
// 如果处于拖拽状态停止自动播放,会每隔5秒检查一次是否可以正常自动播放。
handler.postDelayed(task, 5000);
}
}
};
public void destroy() {
}
/**
* 设置ViewPager的Item点击回调事件
*/
// @Override
// public void onItemClick(int positon) {
// BrowserActivity.launch((Activity) getContext(),
// bannerList.get(currentPos).link,
// bannerList.get(currentPos).title);
// }
/**
* 设置ViewPager的Item点击回调事件
*/
@Override
public void onBannerItemClick(int possition) {
Intent intent = new Intent(getContext(), WallpaperListActivity.class);
intent.putExtra("isVideo", false);
intent.putExtra("category", "new");
getContext().startActivity(intent);
//如果有特殊需求可以从外面回调点击事件接口
// MainActivity.banneritemlistener.onBannerItemClick(possition);
}
}
bannerview的布局代码:
轮播指示器是圆点的drawable文件,放在res的drawable目录下:
没有选中的时候:shape_dots_default.xml
选中的时候:shape_dots_select.xml
轮播指示器是条形的drawable文件,放在res的drawable目录下:
没有选中的时候:shape_line_default.xml
选中的时候:shape_line_select.xml
轮播控件的适配器:
/**
* Created by wjj on 18/12/20 20:40
* [email protected]
* Banner适配器
*/
public class BannerAdapter extends PagerAdapter {
private List mList;
private int pos;
private ViewPagerOnItemClickListener mViewPagerOnItemClickListener;
void setmViewPagerOnItemClickListener(ViewPagerOnItemClickListener mViewPagerOnItemClickListener) {
this.mViewPagerOnItemClickListener = mViewPagerOnItemClickListener;
}
BannerAdapter(List list) {
this.mList = list;
}
@Override
public int getCount() {
return Integer.MAX_VALUE;
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
int position1 = position;
//对ViewPager页号求模取出View列表中要显示的项
position %= mList.size();
if (position < 0) {
position = mList.size() + position;
}
ImageView v = mList.get(position);
pos = position;
v.setScaleType(ImageView.ScaleType.CENTER_CROP);
LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT
);
v.setLayoutParams(p);
//如果View已经在之前添加到了一个父组件,则必须先remove,否则会抛出IllegalStateException。
ViewParent vp = v.getParent();
if (vp != null) {
ViewGroup parent = (ViewGroup) vp;
parent.removeView(v);
}
v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mViewPagerOnItemClickListener != null) {
// mViewPagerOnItemClickListener.onBannerItemClick(pos);
//发生点击banner的item后position错误异常
if (pos ==0){
pos =mList.size()-1;
}else {
pos =pos-1;
}
mViewPagerOnItemClickListener.onBannerItemClick(pos);
}
}
});
container.addView(v);
return v;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
}
public interface ViewPagerOnItemClickListener {
void onBannerItemClick(int possition);
}
}
使用的时候效果如下:
banner.delayTime(3000).build(bean!!.data.new_wallpaper.new_wallpaper_list)
以上是我做完项目后稍微整理出来的注释和源码,如果你在使用中遇到了什么问题或者是我忘记少贴了哪些东西,可以留言给我,我看到后会尽快回复,解决,带来不便之处还望理解!谢谢!