前言
在许多APP中,我们都会看到有广告无限轮播的UI。我们公司的项目也有这个需求,我本来是想利用GitHub上的第三方去实现的,但是我们公司有要显示多个item同时显示进行无限轮播,我只好自己写一个。
效果图
实现多个item进行无限轮播,我们要求是实现3个item进行无限轮播并且添加点击事件。我做出的效果是这样的。
源代码
布局文件XML
实现多个item,需要在布局文件XML中ViewPager的布局加入android:clipChildren="false"
这样才能让ViewPager的item显示多个。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:background="@color/colorAccent"
android:layout_height="@dimen/dp_size_188"/>
<LinearLayout
android:id="@+id/ly"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_size_150"
android:layout_marginTop="@dimen/dp_size_15"
android:clipChildren="false"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:id="@+id/main_viewpager"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_size_150"
android:layout_marginLeft="@dimen/dp_size_25"
android:layout_marginRight="@dimen/dp_size_25"
android:clipChildren="false"/>
</LinearLayout>
</LinearLayout>
item的布局文件XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_size_150" />
</LinearLayout>
加载图片的Adapter
import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import java.util.ArrayList;
/**
* 类说明:无限轮播图片适配器
*
* @author wujiahua
* @date 2018/1/17
*/
public class ImageAdapter extends PagerAdapter {
private Context mContext;
private ArrayList<Integer> pagesArrayList;
public ImageAdapter(Context mContext) {
this.mContext = mContext;
}
/**
* 设置ViewPager将要显示的数据
* 当图片数量小于3张的时候,通过复制数组拼接数据
*/
public void setAdapterData(ArrayList<Integer> arrayList) {
pagesArrayList = arrayList;
if (pagesArrayList.size() < 2) {
pagesArrayList.add(pagesArrayList.get(0));
pagesArrayList.add(pagesArrayList.get(0));
pagesArrayList.add(pagesArrayList.get(0));
} else if (pagesArrayList.size() < 3) {
pagesArrayList.add(pagesArrayList.get(0));
pagesArrayList.add(pagesArrayList.get(1));
}
}
@Override
public int getCount() {
//无限轮播取一个Int类型的最大:2147483647
return Integer.MAX_VALUE;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
if (pagesArrayList.size() > 0) {
View itemView = LayoutInflater.from(mContext).inflate(R.layout.viewpager_adapter, null);
itemView.setFocusable(true);
ImageView imageView = itemView.findViewById(R.id.imageView);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setBackgroundResource(pagesArrayList.get(position % pagesArrayList.size()));
container.addView(itemView);
return itemView;
}
return null;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
}
Activity或Fragment中的源码
我这是单独的一个Demo,所以写在MainActivity中,可以写在自己想要的界面当中。
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.Toast;
import java.util.ArrayList;
/**
* 类说明:这是一个加载本地资源的无限轮播。
*
* @author wujiahua
*/
public class MainActivity extends AppCompatActivity {
/**上下文*/
private Context mContext;
/**
* 使用Handler通信
*/
private Handler mHandler;
/**
* ViewPager组件
*/
private ViewPager mViewPager;
/**单个item的下标*/
private int viewPagerItemSize = 0;
/**
* 滑动时间间隔设置成3s
*/
private final int INTERVAL = 1000 * 3;
/**
* 图片数组
*/
private ArrayList<Integer> mArrayList;
/**
* 设置常量
*/
private final static int SET_VIEWPAGER_ITEM = 9527;
/**
* 适配器
*/
private ImageAdapter mViewPagerAdapter;
/**
* 判断是否进行轮播
*/
private boolean isLoop = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化
init();
}
private void init() {
//初始化数据
initData();
if (viewPagerItemSize > 0) {
//初始化ViewPager视图
initViewPager();
//设置自动滑动
setAutoChangeViewPager();
}
}
private void initData() {
//初始化数据
mContext = this;
mArrayList = new ArrayList<>();
mArrayList.add(R.mipmap.vp_1);
mArrayList.add(R.mipmap.vp_2);
mArrayList.add(R.mipmap.vp_3);
viewPagerItemSize = mArrayList.size();
}
private void initViewPager() {
//初始化ViewPager
mViewPager = findViewById(R.id.main_viewpager);
//ViewPager的父布局
LinearLayout linearLayout = findViewById(R.id.ly);
mViewPagerAdapter = new ImageAdapter(mContext);
mViewPagerAdapter.setAdapterData(mArrayList);
mViewPager.setAdapter(mViewPagerAdapter);
//设置图片缓存为3
mViewPager.setOffscreenPageLimit(3);
//设置item之间间距为15dp
mViewPager.setPageMargin(15);
//设置item的出现位置
int currentItem = Integer.MAX_VALUE / 2 - Integer.MAX_VALUE / 2 % viewPagerItemSize;
mViewPager.setCurrentItem(currentItem);
//设置父布局的LinearLayout的事件分发,反正只有中间的item可以滑动
linearLayout.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
mViewPager.dispatchTouchEvent(motionEvent);
return true;
}
});
//设置ViewPager事件分发
mViewPager.setOnTouchListener(new View.OnTouchListener() {
long downTime;
int downX;
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
mViewPager.requestDisallowInterceptTouchEvent(true);
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.e("TAG", "==========用户按下item");
isLoop = false;
//记录按下的坐标
downX = (int) motionEvent.getX();
//记录按下的时间
downTime = System.currentTimeMillis();
break;
case MotionEvent.ACTION_UP:
Log.e("TAG", "==========用户抬起item");
if (System.currentTimeMillis() - downTime < 500
&& Math.abs(downX - motionEvent.getX()) < 30) {
int item = mViewPager.getCurrentItem() % 3;
Log.e("TAG", "==============item=" + item);
Log.e("TAG", "==============item=" + mViewPager.getCurrentItem());
if (item == 0) {
Toast.makeText(MainActivity.this,
"用户触发点击事件,点击第一张图片", Toast.LENGTH_SHORT).show();
} else if (item == 1) {
Toast.makeText(MainActivity.this,
"用户触发点击事件,点击第二张图片", Toast.LENGTH_SHORT).show();
} else if (item == 2) {
Toast.makeText(MainActivity.this,
"用户触发点击事件,点击第三张图片", Toast.LENGTH_SHORT).show();
}
}
isLoop = true;
break;
case MotionEvent.ACTION_CANCEL:
//第二个case设置item的顶级点击事件,写这个item是为了防止item失效
isLoop = true;
break;
default:
break;
}
return false;
}
});
}
/**自动滑动*/
@SuppressLint("HandlerLeak")
public void setAutoChangeViewPager() {
PageChangeListenerImpl mPageChangeListenerImpl = new PageChangeListenerImpl();
mViewPager.addOnPageChangeListener(mPageChangeListenerImpl);
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case SET_VIEWPAGER_ITEM:
if (mViewPager != null && mViewPagerAdapter != null) {
int currentItemIndex = mViewPager.getCurrentItem();
int itemsCount = mViewPagerAdapter.getCount();
if ((currentItemIndex + 1) < itemsCount) {
mViewPager.setCurrentItem(currentItemIndex + 1, true);
} else {
mViewPager.setCurrentItem(0, false);
}
}
break;
default:
break;
}
}
};
new Thread(new Runnable() {
@Override
public void run() {
Message message = mHandler.obtainMessage();
message.what = SET_VIEWPAGER_ITEM;
if (isLoop) {
mHandler.sendMessage(message);
}
mHandler.removeCallbacks(this);
mHandler.postDelayed(this, INTERVAL);
}
}).start();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (null != mViewPager) {
mViewPager.removeAllViews();
mViewPager = null;
}
}
private class PageChangeListenerImpl implements ViewPager.OnPageChangeListener {
@Override
public void onPageScrolled(final int position, float positionOffset, int positionOffsetPixels) {
//在ViewPager实现无限轮播的时候,需要指示器的发生变化的时候,可以在这里进行修改
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
}
}
总结
这个Demo是利用ViewPager实现无限轮播功能,然后添加了每一个item的点击事件。希望对看我博客的小伙伴的学习和开发有帮助。最后附上源码的下载链接,如果有需要的小伙伴可以去下载运行看一下结果或者直接复制上面的源码。http://download.csdn.net/download/chengxu_kuangrexintu/10215738