- 不能无限循环
- 不能控制自动播放
[Java] 查看源文件 复制代码
Listdata = new ArrayList<>(); data.add(R.mipmap.a1); data.add(R.mipmap.a2); data.add(R.mipmap.a3); data.add(R.mipmap.a4); AdapterDemo ad = new AdapterDemo(this, data); Banner banner = (Banner) findViewById(R.id.banner); /** * 关于这里的设置参数问题,是需要这样使用的 * 在设置了小圆点之后才能设置适配器 * 因为只有在适配器里才会根据一共多少条数据来适配 * 最后需要调用开始轮播 * 个人建议在onPause()/onDestroy()方法中来停止 -- stopAutoPlay() */ banner.setDot(R.drawable.no_selected_dot, R.drawable.selected_dot). setDotGravity(Banner.CENTER). setAdapter(ad). setOnItemClickListener(new BannerPagerAdapter.onItemClickListener() { @Override public void onClick(int position) { Toast.makeText(MainActivity.this, "" + position, Toast.LENGTH_SHORT).show(); } }). startAutoPlay();
[Java] 查看源文件 复制代码
public class AdapterDemo extends BannerPagerAdapter { private Context mContext; private Listdata; public AdapterDemo(Context context, List data) { super(context, data); mContext = context; this.data = data; } /** * 只需要重写构造和这个方法即可 * 在这里可以设置自己的View,使用自己的图片加载库 */ @Override public View setView(int position) { View v = LayoutInflater.from(mContext).inflate(R.layout.test, null); ImageView iv = (ImageView) v.findViewById(R.id.iv); iv.setImageResource(data.get(position)); return v; } }
下面开始说如何写
首先我们要确定一下这个banner有几个需要注意的点:
- 无限轮播
- 点击事件
- 指示器
- 指示器的滑动效果
指示器、滑动效果
其实我写的时候有好多坑,但是写这篇文章的时候感觉都不是特别难的点(技术太菜)
关于指示器,其实现在大部分都是小圆点,这里我实现的思路是创建一个FrameLayout来添加ViewPager和指示器
但是可以看到,这里的指示器会有一个随着页面滑动而滑动的效果,这里就需要两层了,一个是包含未选中的,一个是包含了选中和未选中的(Group)
代码如下:
[Java] 查看源文件 复制代码
private void init() { mPager = new BannerViewPager(mContext); addView(mPager); /** * 实例化两个Group */ mFrameLayout = new FrameLayout(mContext); mDotGroup = new LinearLayout(mContext); /** * 设置小圆点Group的方向为水平 */ mDotGroup.setOrientation(LinearLayout.HORIZONTAL); /** * 如果不设置则小圆点在中间 */ mDotGroup.setGravity(CENTER | Gravity.BOTTOM); /** * 两个Group的大小都为match_parent */ LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); /** * 首先添加小圆点的Group */ mFrameLayout.addView(mDotGroup, params); /** * 然后添加包含的Group(f**k,表达能力有限) */ addView(mFrameLayout, params); /** * 添加到任务栈,当前所有任务完事之后添加已经选中的那个小圆点 */ post(new Runnable() { @Override public void run() { ImageView iv = new ImageView(mContext); iv.setImageDrawable(mContext.getResources().getDrawable(mDot[1])); FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); /** * 设置选中小圆点的左边距 */ params.leftMargin = (int) mDotGroup.getChildAt(0).getX(); params.gravity = Gravity.BOTTOM; mFrameLayout.addView(iv, params); mSelectedDot = mFrameLayout.getChildAt(1); } }); mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { /** * 获取到当前position */ position %= mAdapter.size; /** * 判断如果当前的position不是最后一个,那么就设置偏移量来实现被选中小圆点的滑动效果 */ if (mSelectedDot != null && position != mAdapter.size -1) { float dx = mDotGroup.getChildAt(1).getX() - mDotGroup.getChildAt(0).getX(); mSelectedDot.setTranslationX((position * dx) + positionOffset * dx); } } @Override public void onPageSelected(int position) { position %= mAdapter.size; /** * 如果已经是最后一个,那么则直接把小圆点定位到那,不然滑动效果会出错 */ if (mSelectedDot != null && position == mAdapter.size - 1) { float dx = mDotGroup.getChildAt(1).getX() - mDotGroup.getChildAt(0).getX(); mSelectedDot.setTranslationX(position * dx); } } @Override public void onPageScrollStateChanged(int state) { } }); }
关于滑动指示器,其实就是用了一个setTranslationX()方法,这个方法可以虽然移动View的位置,但是没有真正的移动该View,所以我们在移动的时候根据position来计算,但是当移动到最后一个的时候就不应该用这个方法了,如果还用的话就会造成一种『出界』了的感觉,所以这里在最后一个的时候不进入方法。
有人应该会想到『在第一页的时候』,这里我们大家可以自己测试一下,当手指向右滑的时候,就已经是size-1页了,所以我们直接就用一个判断就够了
相关源码推荐:
- DragGridView拖拽排序(15026次查看,111次下载)
- bihu逼乎(20072次查看,190次下载)
- Yhb-2.0有惠报(7865次查看,54次下载)
- 简单易用的星级控件(10817次查看,97次下载)
- IOS_Style-DragDeleteListView(3651次查看,9次下载)