一个无限滚动的轮播图
1、首先定义出一个轮播图的布局,我们可以直接把它加入到布局中,也可以用include标签来加入,我这里采用了include的方式
home_viewpager.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="160dp"
android:id="@+id/home_viewpager">
<LinearLayout
android:id="@+id/top_roll_viewpager"
android:layout_width="fill_parent"
android:layout_height="160dp"
android:orientation="horizontal" />
<LinearLayout
android:id="@+id/dots_ll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp"
android:layout_marginTop="145dp"
android:orientation="horizontal" />
</RelativeLayout>
利用include加入到主布局中
<include layout="@layout/home_viewpager"/>
2、然后我们在Activity中找到这几个关键的控件
//轮播图所在的大布局
View mTopView =findViewById(R.id.home_viewpager);
//得到点的集合
LinearLayout mAllDots = (LinearLayout) mTopView.findViewById(R.id.dots_ll);
//得到轮播图的集合
LinearLayout mViewPager = (LinearLayout) mTopView.findViewById(R.id.top_roll_viewpager);
3、在我们给将自定义的轮播图添加进去之前,我们先初始化那些指示的点
/**
* 初始化点的集合
*
* @param size 点的数量
*/
private void initDot(int size) {
// 先清空Linear集合中的点的集合
mAllDots.removeAllViews();
// 初始化list集合
mDots = new ArrayList<View>();
// 遍历集合
for (int i = 0; i < size; i++) {
// 创建点的集合
View view = new View(UiUtils.getContext());
// 点的布局参数
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(CommonUtil.dip2px(
UiUtils.getContext(), 5), CommonUtil.dip2px(
UiUtils.getContext(), 5));
// 设置左右的间距
params.leftMargin = 10;
// 将显示布局设置进点
view.setLayoutParams(params);
// 设置每个点的默认显示样式
if (i == 0) {// 如果是第0个点
view.setBackgroundResource(R.drawable.dot_focus);
} else {
// 其他界面显示为不选中界面
view.setBackgroundResource(R.drawable.dot_normal);
}
// 将点放入到控件中
mAllDots.addView(view);
// 将点放入到List集合中
mDots.add(view);
}
这段代码主要是用来初始化点的,我们可以在这里设置点之间的间距,注释比较详细,就不多说。
生成轮播图控件,然后将控件添加到我们的布局中
RollViewPager rollViewPager = new RollViewPager(MainActivity.this,mDots);
rollViewPager.setImageUrl(mImageViewUrl);
rollViewPager.start();
mViewPager.removeAllViews();
mViewPager.addView(rollViewPager);
mImageViewUrl这个是一个List,用来装我们轮播图图片的地址的。
5、接下来就是我们的轮播图控件了
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import com.bumptech.glide.Glide;
import java.util.ArrayList;
import java.util.List;
import cn.mifengkong.loanmarket.R;
import cn.mifengkong.loanmarket.utils.UiUtils;
/**
* ============================================================
*
* 描 述 :
*
* 自定义可左右滑动的ViewPager 修订历史 :
*
* ============================================================
**/
public class RollViewPager extends ViewPager {
// 轮播图上点的集合
private List<View> mDots;
// // 初始化接口对象
private onTouchClickListener mListener;
private MyOnTouchListener mTouchListener;
private Task mTask;
private List<String> mImageUrl;//图片地址
private int viewPagerCount = 10000;//用来表示需要创建多少个pager,用来左右滑动和自行滚动
private int firstPosition;//初始化viewpager默认的选择是哪一页
private boolean hasAdapter = false;
private boolean isFirst = true;
private Context mContext;
private RollPagerAdapter adapter;
public RollViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
public interface onTouchClickListener { // 接口回调,当轮播图条目被点击的时候的调用的方法
void onItemtTouchClickListener(int posstion);
}
// 初始化监听器对象
public void setmListener(onTouchClickListener listener) {
this.mListener = listener;
}
public RollViewPager(Context context, List<View> dots) {
super(context);
this.mContext = context;
this.mDots = dots;// 接收数点的集合
firstPosition = viewPagerCount / 2 / mDots.size() * mDots.size();
// 初始化点击监听
mTouchListener = new MyOnTouchListener();
mCurrentPositon = firstPosition;
// 初始化任务
mTask = new Task();
}
public void stop(){
handler.removeCallbacksAndMessages(null);
}
private class Task implements Runnable {
@Override
public void run() {
// 获取到当前的值
mCurrentPositon = (mCurrentPositon + 1);
Message message = Message.obtain();
handler.sendMessage(message);
}
}
// 让轮播图滚动起来的方法
public void start() {
if (!hasAdapter) {
hasAdapter = true;
adapter = new RollPagerAdapter();
RollViewPager.this.setAdapter(adapter);
// 设置滚动监听
RollViewPager.this
.setOnPageChangeListener(new MyOnPageChangeListener());
if(isFirst){
RollViewPager.this.setCurrentItem(firstPosition);//这句代码可以让Viewpager左右无限滑动
isFirst = false;
}
// 设置滚动监听
RollViewPager.this
.setOnPageChangeListener(new MyOnPageChangeListener());
}
handler.postDelayed(mTask, 3000);
}
private int mCurrentPositon = 0;
private int oldPosition = 0;
private class MyOnPageChangeListener implements OnPageChangeListener {
/**
* 界面选中的时候调用,初始化点的滚动
*/
@Override
public void onPageSelected(int position) {
mCurrentPositon = position;
if (null != mDots && mDots.size() > 0) {
mDots.get(oldPosition).setBackgroundResource(
R.drawable.dot_normal);
mDots.get(position % mImageUrl.size()).setBackgroundResource(R.drawable.dot_focus);
}
oldPosition = position % mImageUrl.size();
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
}
private class RollPagerAdapter extends PagerAdapter {
@Override
public int getCount() {
return viewPagerCount;
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
((RollViewPager) container).removeView((View) object);
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
ImageView imageView = new ImageView(UiUtils.getContext());
imageView.setScaleType(ScaleType.FIT_XY);
imageView.setOnTouchListener(mTouchListener);
Glide.with(mContext).load(mImageUrl.get(position%mImageUrl.size())).into(imageView);
// imageView.setImageResource(mImageUrl.get(position % mImageUrl.size()));
((RollViewPager) container).addView(imageView);
return imageView;
}
}
// Handler用于处理消息
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
// 设置当前界面
RollViewPager.this.setCurrentItem(mCurrentPositon, false);
start();
};
};
private class MyOnTouchListener implements OnTouchListener {
private long downThreadTimeMillis;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// 停止跳动
handler.removeCallbacksAndMessages(null);
// 区分到底是长按还是单机事件
// 获取到当前的时间
downThreadTimeMillis = SystemClock.currentThreadTimeMillis();
// 判断当前时间如果小于500毫秒。那么就是单机事件
break;
case MotionEvent.ACTION_MOVE:
handler.removeCallbacks(mTask);
break;
case MotionEvent.ACTION_UP:
long currentThreadTimeMillis = SystemClock
.currentThreadTimeMillis();
if (currentThreadTimeMillis - downThreadTimeMillis < 500) {
//短按事件
if(mListener!=null){
mListener.onItemtTouchClickListener(mCurrentPositon % mImageUrl.size());
}
}
start();
break;
default:
break;
}
return true;
}
}
/**
* 是否滑动
*/
private boolean is_move;
private int downX;
private int downY;
/**
* 事件分发
*/
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_MOVE:
int currentX = (int) ev.getX();
int currentY = (int) ev.getY();
if (Math.abs(currentX - downX) > Math.abs(currentY - downY)) {
// 请求父类不要拦截子类
// getParent()获取到父类
is_move = false;
} else {
is_move = true;
}
break;
case MotionEvent.ACTION_DOWN:
downX = (int) ev.getX();
downY = (int) ev.getY();
is_move = false;
break;
case MotionEvent.ACTION_UP:
handler.removeCallbacks(mTask);
start();
break;
}
getParent().requestDisallowInterceptTouchEvent(!is_move);
return super.dispatchTouchEvent(ev);
}
// 接收图片地址的url
public void setImageUrl(ArrayList<String> ImageList) {
// 非空判断
if (ImageList != null && ImageList.size() > 0) {
this.mImageUrl = ImageList;
}
}
}
6、我们可能还要用到轮播图的点击事件
rollViewPager.setmListener(new RollViewPager.onTouchClickListener() {
@Override
public void onItemtTouchClickListener(int posstion) {
}
});
在这里进行处理就行了