先给大家上效果图
项目运行
项目结构
项目思路
问题1: 左右无限滑
在PagerAdapt的getCount方法里给上一个很大的数
public int getCount() {
return Integer.MAX_VALUE;
}
然后把设置item项设置到一个中间的位置
int diff = Integer.MAX_VALUE /2 % mData.size();
mPager.setCurrentItem(Integer.MAX_VALUE /2 - diff);
问题二: 防止position过大 引起下标越界
在所有需要处理position值得地方加上
position = position % mData.size();
问题三:自动轮播
使用Thread或者使用Handler都可以,原理就是隔一段时间把pager的item项+1
我这用的一个自定的Runnable,写了一个停止方法和开始方法
class AutoScrollTask implements Runnable{
@Override
public void run() {
int item = mPager.getCurrentItem();
mPager.setCurrentItem(item + 1);
startTask();
}
public void startTask(){
mPager.postDelayed(this, 2000);
}
public void stopTask(){
mPager.removeCallbacks(this);
}
}
问题四:停止轮播和重新开始轮播
去监听pager,当发生DOWN事件的时候去停止轮播,UP事件的时候就去重新轮播
final AutoScrollTask task = new AutoScrollTask();
task.startTask();
mPager.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
task.stopTask();
break;
case MotionEvent.ACTION_UP:
task.startTask();
break;
}
return false;
}
});
项目代码
代码 AutoCarousel 类
public class AutoCarousel extends RelativeLayout {
private List<Bitmap> mData; // 数据源
private int mIndicatorHeight; // 滑动指示器高度
private ViewPager mPager; // 轮播的ViewPager
private LinearLayout mIndicator; // 指示器容器控件
public AutoCarousel(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public AutoCarousel(Context context, AttributeSet attrs) {
super(context, attrs);
}
public AutoCarousel(Context context) {
super(context);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mIndicatorHeight = mIndicator.getHeight();
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
}
/** 初始化数据 只用当外界调用这个方法一切才会开始 */
public void initView(List<Bitmap> T) {
mData = T;
if (mData != null && mData.size() != 0) {
View.inflate(getContext(), R.layout.auto_carousel, this);
mPager = (ViewPager) findViewById(R.id.lv_auto_carousel);
mIndicator = (LinearLayout) findViewById(R.id.ll_auto_carousel_indicator);
mIndicator.setGravity(Gravity.CENTER);
// 轮播
mPager.setAdapter(new AutoAdapter());
// 添加指示器
for (int i = 0; i < mData.size(); i++) {
IndicatorView indicatorView = new IndicatorView(getContext());
mIndicator.addView(indicatorView );
}
// 监听滑动,目的是为了同步指示器的改变
mPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
position = position % mData.size();
for (int i = 0; i < mData.size(); i++) {
IndicatorView view= (IndicatorView) mIndicator.getChildAt(i);
view.changeColor(Color.GRAY);
if (position == i) {
view.changeColor(Color.RED);
}
}
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
});
// 设置偏移,目的是为了使item 刚好处于第0项的位置
int diff = Integer.MAX_VALUE /2 % mData.size();
mPager.setCurrentItem(Integer.MAX_VALUE /2 - diff);
// 开始轮播
final AutoScrollTask task = new AutoScrollTask();
task.startTask();
// 停止轮播和重新开始轮播的处理
mPager.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
task.stopTask();
break;
case MotionEvent.ACTION_UP:
task.startTask();
break;
}
return false;
}
});
}
}
/** 适配器 */
class AutoAdapter extends PagerAdapter{
@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) {
position = position % mData.size();
ImageView image = new ImageView(getContext()); //fitXY
image.setImageBitmap(mData.get(position));
image.setScaleType(ScaleType.FIT_XY);
container.addView(image);
return image;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
}
/** 自动轮播 */
class AutoScrollTask implements Runnable{
@Override
public void run() {
int item = mPager.getCurrentItem();
mPager.setCurrentItem(item + 1);
startTask();
}
public void startTask(){
mPager.postDelayed(this, 2000);
}
public void stopTask(){
mPager.removeCallbacks(this);
}
}
/** 指示器 */
class IndicatorView extends View{
Paint paint;
public IndicatorView(Context context) {
super(context);
paint = new Paint();
paint.setColor(Color.GRAY);
}
public void changeColor(int color){
paint.setColor(color);
invalidate();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(16, mIndicatorHeight);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawCircle(8, mIndicatorHeight/2, 4, paint);
}
}
}
代码 MainActivity 类
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AutoCarousel auto = (AutoCarousel) findViewById(R.id.re);
List<Bitmap> T = new ArrayList<Bitmap>();
Bitmap bitmap1 = BitmapFactory.decodeResource(getResources(), R.drawable.img1);
Bitmap bitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.img2);
Bitmap bitmap3 = BitmapFactory.decodeResource(getResources(), R.drawable.img3);
Bitmap bitmap4 = BitmapFactory.decodeResource(getResources(), R.drawable.img4);
T.add(bitmap1);
T.add(bitmap2);
T.add(bitmap3);
T.add(bitmap4);
auto.initView(T);
}
}
代码 activity_main.xml 文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.xuan.autocarousel.AutoCarousel
android:id="@+id/re"
android:layout_width="match_parent"
android:layout_height="200dp"/>
</RelativeLayout>
代码 auto_carousel.xml 文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="150dp">
<android.support.v4.view.ViewPager
android:id="@+id/lv_auto_carousel"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<LinearLayout
android:id="@+id/ll_auto_carousel_indicator"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:orientation="horizontal"
android:background="#6000"
android:layout_height="40dp"/>
</RelativeLayout>