一、使用
布局就不贴了,直接写业务逻辑:
private ViewPager mPager;
private LinearLayout mVPIndicate;
private void initPager() {
mPager = (ViewPager)findViewById(R.id.mPager);
mVPIndicate = (LinearLayout)findViewById(R.id.mVPIndicate);
List<View> mViews = mVPController.createGridRecyclerS(
mVPController.initViewPagerData(Arrays.asList(hotWordDefList)));
final int pageCount = mViews.size();
mPager.setAdapter(new LoopVPAdapter(mViews));
mVPController.setVPSlideEnable(mPager);
final List<ImageView> mVPIndicateImgView = mVPController.initViewPagerIndicate(pageCount - 1);
for (ImageView childImg : mVPIndicateImgView) {
mVPIndicate.addView(childImg);
}
mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
Drawable noSelected = Main2Activity.this.getResources().getDrawable(R.drawable.ad_white_dot);
Drawable selected = Main2Activity.this.getResources().getDrawable(R.drawable.ad_selected_dot);
for (int i = 0; i < pageCount; i++) {
if (i == pageCount - 1) {
if (position == i) {
mVPIndicateImgView.get(0).setImageDrawable(selected);
}
} else if (position != i) {
mVPIndicateImgView.get(i).setImageDrawable(noSelected);
} else {
mVPIndicateImgView.get(i).setImageDrawable(selected);
}
}
}
@Override
public void onPageScrollStateChanged(int state) {
int currentPosition = mPager.getCurrentItem();
if (state != ViewPager.SCROLL_STATE_IDLE)
return;
if (currentPosition >= pageCount - 1) {
mPager.setCurrentItem(0, false);
} else {
mPager.setCurrentItem(currentPosition, false);
}
}
});
}
二、辅助控制类VPController
public class VPController {
private Context context;
private Subscription subscription;
private final static int NumPerVP = 8;
public VPController(Context context) {
this.context = context;
}
public List<String[]> initViewPagerData(List<String> mListData) {
List<String[]> resultList = new ArrayList<>();
int hotWordSize = mListData.size();
int pageSize = (hotWordSize / NumPerVP) + ((hotWordSize % NumPerVP) > 0 ? 1 : 0);
for (int i = 0; i < pageSize; i++){
String[] hotWord = new String[NumPerVP];
for (int j = i * NumPerVP; j < (i + 1) * NumPerVP && j < hotWordSize; j++){
hotWord[j % NumPerVP] = mListData.get(j);
}
resultList.add(hotWord);
}
return resultList;
}
private RecyclerView createGridRecycler(final List<String> mData) {
RecyclerView mRecycler = new RecyclerView(context);
mRecycler.setLayoutManager(new GridLayoutManager(context, 2));
HotSearchAdapter gridAdapter = new HotSearchAdapter();
mRecycler.setAdapter(gridAdapter);
gridAdapter.setLists(mData);
gridAdapter.setOnItemClickListener(new OnRecyclerItemClickListener() {
@Override
public void onItemRecyclerClick(Object object) {
Log.i("TAG", "onItemRecyclerClick");
}
});
return mRecycler;
}
public List<View> createGridRecyclerS(List<String[]> source) {
source.add(source.get(0));
List<View> resultList = new ArrayList<>();
for (String[] datas : source) {
resultList.add(createGridRecycler(Arrays.asList(datas)));
}
return resultList;
}
/**
* 生成指示器
* @param size
* @return
*/
public List<ImageView> initViewPagerIndicate(int size) {
List<ImageView> result = new ArrayList<>();
ImageView mImg ;
for (int i = 0; i < size; i++){
mImg = new ImageView(context);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(10,10);
layoutParams.setMargins(10, 0, 0, 0);
mImg.setLayoutParams(layoutParams);
result.add(mImg);
if (i == 0) {
mImg.setImageDrawable(context.getResources().getDrawable(R.drawable.ad_selected_dot));
} else {
mImg.setImageDrawable(context.getResources().getDrawable(R.drawable.ad_white_dot));
}
}
return result;
}
/**
* 左右滑动的动画降速
* @param mViewPage
*/
public void vpSlideVelocityControl(ViewPager mViewPage) {
try {
Field mScroller = ViewPager.class.getDeclaredField("mScroller");
mScroller.setAccessible(true);
Interpolator sInterpolator = new AccelerateDecelerateInterpolator();
FixedScroller scroller = new FixedScroller(mViewPage.getContext(), sInterpolator);
mScroller.set(mViewPage, scroller);
} catch (Exception e) {
Log.e("exception", e.getMessage());
}
}
/**
* 是否启动向右无限循环滑动
* @param mViewPage
*/
public void setVPSlideEnable(final ViewPager mViewPage) {
subscription = Observable.interval(3000, 3000, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Long>() {
@Override
public void call(Long aLong) {
int currentIndex = mViewPage.getCurrentItem();
mViewPage.setCurrentItem(currentIndex + 1, true);
}
});
}
/**
* 和setVPSlideEnable()相对于,关闭自动滑动
*/
public void setVPSlideDisenable() {
if (subscription != null) {
subscription.unsubscribe();
}
}
}
以上就是完整的使用,就是这么简单粗暴,不做任何扩展!
实现图片的更加简单。可以直接修改。
三、原理
下面简单说下原理吧,主要是在ViewPager.OnPageChangeListener修改:
@Override
public void onPageScrollStateChanged(int state) {
int currentPosition = mPager.getCurrentItem();
if (state != ViewPager.SCROLL_STATE_IDLE)
return;
if (currentPosition >= pageCount - 1) {
mPager.setCurrentItem(0, false);
} else {
mPager.setCurrentItem(currentPosition, false);
}
}
————————————>无限的向右循环
View1 View2 View3 View11
其实想表达的是如果你有三个页面需要展示,那么就在List里面多添加一个View,添加第一个View到List表尾就行了。之所以这样做,其实就是为了掩盖最后一项滑动第一项那个不太友好的动画。处理的逻辑是,当正在现实最后一项的时候,手动设置mPager.setCurrentItem(0, false);成第一项,这个是没有动画的,至少人的肉眼是看不到有什么变化的,这样就又从第一项开始循环下去。
注意指示器处的设置别出错,因为我们虽然有四个页面,但实际上我们要显示的是三页:
@Override
public void onPageSelected(int position) {
Drawable noSelected = Main2Activity.this.getResources().getDrawable(R.drawable.ad_white_dot);
Drawable selected = Main2Activity.this.getResources().getDrawable(R.drawable.ad_selected_dot);
for (int i = 0; i < pageCount; i++) {
if (i == pageCount - 1) {
if (position == i) {
mVPIndicateImgView.get(0).setImageDrawable(selected);
}
} else if (position != i) {
mVPIndicateImgView.get(i).setImageDrawable(noSelected);
} else {
mVPIndicateImgView.get(i).setImageDrawable(selected);
}
}
}
顺便把参考网上的FixedScroller也贴上来吧:
public class FixedScroller extends Scroller {
private int mDuration = 500;
public FixedScroller(Context context) {
super(context);
}
public FixedScroller(Context context, Interpolator interpolator) {
super(context, interpolator);
}
@Override
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
// Ignore received duration, use fixed one instead
super.startScroll(startX, startY, dx, dy, mDuration);
}
@Override
public void startScroll(int startX, int startY, int dx, int dy) {
// Ignore received duration, use fixed one instead
super.startScroll(startX, startY, dx, dy, mDuration);
}
}
四、无限循环的另一种实现方式
实现原理:在适配器中将getcount的值设置为无限大
然后就是在adapter中的实现:
public class ViewPagerAdapter extends PagerAdapter {
@Override
public int getCount() {
// return drawables.length;
return Integer.MAX_VALUE;
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
ImageView view = imageViews[position % imageViews.length];
((ViewPager) container).removeView(view);
}
@Override
public Object instantiateItem(View container, int position) {
int length = imageViews.length;
try {
if (imageViews[position % length].getParent() == null) {
((ViewPager) container).addView(imageViews[position % length], 0);
} else {
((ViewGroup) (imageViews[position % length].getParent()))
.removeView(imageViews[position % length]);
}
} catch (Exception e) {
}
return imageViews[position % imageViews.length];
}
}