android中使用ViewPager实现无限轮播图

时间:2022-08-04 10:11:42

android中使用ViewPager实现无限轮播图

一、实现方式:

   1.通过ViewPager适配器中的getCount()方法添加一个整型最大的值来实现

   2.通过继承ViewPager重写ViewPager中的部分方法来实现

二、实现原理:

   上述的的方式一,其实可以理解成一种假的无限轮播,同时它太过野蛮也比较耗费资源,所以在这里我主要介绍第二种实现无线轮播图的方法。

原理展示图如下图所示:

android中使用ViewPager实现无限轮播图

三、代码实现

布局文件


<LinearLayout 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"
tools:context=".MainActivity" >


<com.example.cycleviewpage.CycleViewPager
android:id="@+id/vp"
android:layout_width="match_parent"
android:layout_height="200dp"
/>


</LinearLayout>

java代码实现


package com.example.cycleviewpage;<br/>

import android.app.Activity;<br/>
import android.content.Context;<br/>
import android.os.Bundle;<br/>
import android.support.v4.view.PagerAdapter;<br/>
import android.support.v4.view.ViewPager;<br/>
import android.view.View;<br/>
import android.view.ViewGroup;<br/>
import android.widget.ImageView;<br/>

public class MainActivity extends Activity {

private ViewPager vp;
//四张图片资源id的整型数组
private int[] ids = { R.drawable.a, R.drawable.b, R.drawable.c,
R.drawable.d };
private Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
vp = (ViewPager) findViewById(R.id.vp);
//给vp设置适配器
vp.setAdapter(new Adapter());
}

private class Adapter extends PagerAdapter {

@Override
public int getCount() {
return ids.length ;
}
//初始化ViewPager中添加的内容
@Override
public Object instantiateItem(ViewGroup container, int position) {
ImageView image = new ImageView(context);
image.setBackgroundResource(ids[position]);
container.addView(image);
return image;
}

@Override
public boolean isViewFromObject(View view, Object object) {
return view==object;
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
}
}

自定义的无限轮播的CycleViewPager


package com.example.cycleviewpage;<br/>

import android.content.Context;<br/>
import android.os.Handler;<br/>
import android.support.v4.view.PagerAdapter;<br/>
import android.support.v4.view.ViewPager;<br/>
import android.util.AttributeSet;<br/>
import android.view.MotionEvent;<br/>
import android.view.View;<br/>
import android.view.ViewGroup;<br/>

public class CycleViewPager extends ViewPager {

//创建一个Handler对象来实现图片的自动轮播
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
if (msg.what == 0) {
//获取当前CycleViewPager展示的位置
int currentItem = getCurrentItem();
currentItem += 1;
setCurrentItem(currentItem);
//通过再次发送handler消息实现无线轮播图
handler.sendEmptyMessageDelayed(0, 2000);
}
};
};

public CycleViewPager(Context context) {
super(context);
}

public CycleViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}

//重写ViewPager的监听方法,来实现在自定义控件内部的监听
@Override
public void setOnPageChangeListener(OnPageChangeListener listener) {
InnerPageChangeListener innerListener = new InnerPageChangeListener(
listener);
super.setOnPageChangeListener(innerListener);
}

//重写ViewPager的setAdapter,来实现在自定义控件内部的自己添加适配器
@Override
public void setAdapter(PagerAdapter adapter) {
//接收从外部来的Adapter,然后再对其进行再次的封装
InnerPagerAdapter innerAdapter = new InnerPagerAdapter(adapter);
super.setAdapter(innerAdapter);
setOnPageChangeListener(null);
setCurrentItem(1);
startScroll();
}

private void startScroll() {
handler.sendEmptyMessageDelayed(0, 2000);
}

private void stopScroll() {
handler.removeMessages(0);
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
//在手指按下的时候让图片停止自动轮播
case MotionEvent.ACTION_DOWN:
stopScroll();
break;
case MotionEvent.ACTION_MOVE:
break;
//防止从ViewPager中滑动移除到其他控件的时候不执行ACTION_UP事件,从而无法实现图片的自动轮播
case MotionEvent.ACTION_CANCEL:
//手指抬起的时候再次发送handler消息,启动图片自动轮播的功能
case MotionEvent.ACTION_UP:
startScroll();
break;
}
return super.onTouchEvent(ev);
}

private class InnerPageChangeListener implements OnPageChangeListener {

private OnPageChangeListener listener;
private int position;

public InnerPageChangeListener(OnPageChangeListener listener) {
this.listener = listener;

}

@Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
if (listener != null) {
listener.onPageScrolled(position, positionOffset,
positionOffsetPixels);
}
}

@Override
public void onPageSelected(int position) {
this.position = position;
if (listener != null) {
listener.onPageSelected(position);
}
}

@Override
public void onPageScrollStateChanged(int state) {
//判断ViewPager的滑动状态,当滑动状态变为空闲的时候再完成切换页面,能够给用户不突兀的感觉
if (state == ViewPager.SCROLL_STATE_IDLE) {
if (position == getAdapter().getCount() - 1) {
// 当图片滑动到最后一个位置的时候,将位置改变为A图片
position = 1;
} else if (position == 0) {
// 当图片滑动到第一个位置的时候,将位置改变为D图片
position = getAdapter().getCount() - 2;
}
//false代表页面不平滑移动
setCurrentItem(position, false);
}
if (listener != null) {
listener.onPageScrollStateChanged(state);
}
}

}

private class InnerPagerAdapter extends PagerAdapter {

private PagerAdapter adapter;

public InnerPagerAdapter(PagerAdapter adapter) {
this.adapter = adapter;
}

@Override
public int getCount() {
//在ViewPager的头部和尾部分别添加两个页面(***)
return adapter.getCount() + 2;
}

@Override
public Object instantiateItem(ViewGroup container, int position) {
if (position == getCount() - 1) {
// 当图片滑动到最后一个位置的时候,将位置改变为A图片
position = 0;
} else if (position == 0) {
// 当图片滑动到第一个位置的时候,将位置改变为D图片
position = getCount() - 3;
} else {
position = position - 1;
}
return adapter.instantiateItem(container, position);
}

@Override
public boolean isViewFromObject(View view, Object object) {
return adapter.isViewFromObject(view, object);
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
adapter.destroyItem(container, position, object);
}
}
}

四、结果展示

android中使用ViewPager实现无限轮播图

源代码:https://github.com/Duckdan/CycleViewPager