void setCurrentItemInternal(int item, boolean smoothScroll, boolean always, int velocity) {
..............
final boolean dispatchSelected = mCurItem != item;
if (mFirstLayout) {
mCurItem = item;
if (dispatchSelected) {
dispatchOnPageSelected(item);
}
requestLayout();
} else {
populate(item);
scrollToItem(item, smoothScroll, velocity, dispatchSelected);
}
}
private void selectFirstItem() {
stopPlay();
setAdapter(null);
setField("android.support.v4.view.ViewPager", AutoPlayViewPager.this, "mFirstLayout", true);
setAdapter(adapter);
if (adapter.getCount() > 0) {
int currentItem = Integer.MAX_VALUE >> 1;
currentItem = currentItem - currentItem % adapter.getCount();
setCurrentItem(currentItem, false);
}
}
public class AutoPlayViewPager extends ViewPager {
private Paint paint;
private int position;
private int size = 15;
private int selected = Color.RED;
private int background = 0x66FFFFFF;
private int displayTime = Integer.MAX_VALUE;
private final AtomicBoolean isPlaying = new AtomicBoolean(false);
private final AutoPlayScroller autoPlayScroller;
private PagerAdapter adapter;
private final AtomicBoolean dataSetObserverRegistered = new AtomicBoolean(false);
public AutoPlayViewPager(@NonNull Context context) {
this(context, null);
}
public AutoPlayViewPager(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
addOnPageChangeListener(mListener);
paint = new Paint();
paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL);
autoPlayScroller = new AutoPlayScroller(context);
setField("android.support.v4.view.ViewPager", this, "mScroller", autoPlayScroller);
}
@Override
public void setAdapter(@Nullable PagerAdapter adapter) {
if (adapter == null) {
super.setAdapter(null);
return;
}
super.setAdapter(new AutoPlayAdapter(adapter));
this.adapter = adapter;
if (dataSetObserverRegistered.get()) {
adapter.unregisterDataSetObserver(mDataSetObserver);
}
adapter.registerDataSetObserver(mDataSetObserver);
dataSetObserverRegistered.set(true);
if (adapter.getCount() > 0) {
int currentItem = Integer.MAX_VALUE >> 1;
currentItem = currentItem - currentItem % adapter.getCount();
setCurrentItem(currentItem, false);
}
}
public void startPlay(int displayTime) {
this.displayTime = displayTime;
if (adapter == null || adapter.getCount() <= 1)
return;
stopPlay();
isPlaying.set(true);
postDelayed(player, this.displayTime);
}
public void stopPlay() {
removeCallbacks(player);
isPlaying.set(false);
}
private final Runnable player = new Runnable() {
@Override
public void run() {
if (isPlaying.get()) {
setCurrentItem(getCurrentItem() + 1, true);
postDelayed(player, displayTime);
}
}
};
public void setSwitchDuration(int duration) {
if (duration >= displayTime) {
throw new IllegalArgumentException("The augment duration must less than displayTime!");
}
autoPlayScroller.setDuration(duration);
}
public void setPointStyle(int size, int background, int selected) {
this.size = size;
this.selected = selected;
this.background = background;
invalidate();
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
final int count = adapter == null ? 0 : adapter.getCount();
if (count < 1) return;
canvas.save();
canvas.translate(getScrollX(), getScrollY());
float x = (getWidth() - size * count * 2) / 2 + size;
float y = getHeight() - size;
paint.setColor(background);
for (int i = 0; i < count; i++) {
canvas.drawCircle(x + i * size * 2, y, size >> 1, paint);
}
paint.setColor(selected);
canvas.drawCircle(x + position * size * 2, y, size >> 1, paint);
canvas.restore();
}
private final OnPageChangeListener mListener = new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_IDLE) {
startPlay(displayTime);
} else if (state == ViewPager.SCROLL_STATE_DRAGGING) {
stopPlay();
}
}
@Override
public void onPageSelected(int pos) {
if (adapter.getCount() > 0) {
position = pos % adapter.getCount();
invalidate();
}
}
};
private final DataSetObserver mDataSetObserver = new DataSetObserver() {
@Override
public void onChanged() {
update();
}
@Override
public void onInvalidated() {
update();
}
private void update() {
if (getAdapter() == null)
return;
getAdapter().notifyDataSetChanged();
selectFirstItem();
if (displayTime != Integer.MAX_VALUE) {
startPlay(displayTime);
}
}
private void selectFirstItem() {
stopPlay();
setField("android.support.v4.view.ViewPager", AutoPlayViewPager.this, "mFirstLayout", true);
setAdapter(null);
setAdapter(adapter);
if (adapter.getCount() > 0) {
int currentItem = Integer.MAX_VALUE >> 1;
currentItem = currentItem - currentItem % adapter.getCount();
setCurrentItem(currentItem, false);
}
}
};
@Override
protected void onDetachedFromWindow() {
stopPlay();
removeOnPageChangeListener(mListener);
if (adapter != null && dataSetObserverRegistered.get()) {
adapter.unregisterDataSetObserver(mDataSetObserver);
dataSetObserverRegistered.set(false);
}
super.onDetachedFromWindow();
}
public static boolean setField(String className, Object object, String filedName, Object filedValue) {
try {
Class clazz = Class.forName(className);
Field field = clazz.getDeclaredField(filedName);
field.setAccessible(true);
field.set(object, filedValue);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
private static class AutoPlayAdapter extends PagerAdapter {
private final PagerAdapter adapter;
AutoPlayAdapter(PagerAdapter adapter) {
if (adapter == null)
throw new NullPointerException("adapter is null!");
this.adapter = adapter;
}
@Override
public int getCount() {
if (adapter.getCount() <= 1)
return adapter.getCount();
return Integer.MAX_VALUE;
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return adapter.isViewFromObject(view, object);
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
if (adapter.getCount() > 0) {
return adapter.instantiateItem(container, position % adapter.getCount());
}
return null;
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
if (adapter.getCount() != 0) {
adapter.destroyItem(container, position % adapter.getCount(), object);
}
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
if (adapter.getCount() != 0) {
return adapter.getPageTitle(position % adapter.getCount());
}
return "";
}
}
private static class AutoPlayScroller extends Scroller {
private int duration = 600;
AutoPlayScroller(Context context) {
super(context, interpolator);
}
private static final Interpolator interpolator = (t) -> {
t -= 1.0f;
return t * t * t * t * t + 1.0f;
};
@Override
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
super.startScroll(startX, startY, dx, dy, Math.max(duration, this.duration));
}
void setDuration(int duration) {
this.duration = duration;
}
}
}
public class TestAutoPlayViewPager extends BaseActivity {
private AutoPlayViewPager viewPager;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_auto_play_viewpager_layout);
init();
}
private void init() {
List<Map.Entry<Integer, String>> data = new ArrayList<>();
data.add(new AbstractMap.SimpleEntry<>(R.mipmap.aaa, "Page-1"));
data.add(new AbstractMap.SimpleEntry<>(R.mipmap.bbb, "Page-2"));
data.add(new AbstractMap.SimpleEntry<>(R.mipmap.ccc, "Page-3"));
PagerAdapter adapter = getPagerAdapter(data);
viewPager = findViewById(R.id.view_page);
viewPager.setAdapter(adapter);
viewPager.setSwitchDuration(800);
viewPager.setPointStyle(UiUtil.dp2px(10), 0x66FFFFFF, Color.RED);
viewPager.postDelayed(() -> {
data.add(new AbstractMap.SimpleEntry<>(R.mipmap.dddd, "Page-4"));
adapter.notifyDataSetChanged();
}, 4000);
}
@Override
protected void onStart() {
super.onStart();
viewPager.startPlay(2000);
}
@Override
protected void onStop() {
super.onStop();
viewPager.stopPlay();
}
private PagerAdapter getPagerAdapter(final List<Map.Entry<Integer, String>> data) {
return new PagerAdapter() {
@Override
public int getCount() {
return data == null ? 0 : data.size();
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view == object;
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
TextView view = new TextView(getBaseContext());
view.setText(data.get(position).getValue());
view.setBackgroundResource(data.get(position).getKey());
container.addView(view);
return view;
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
if (container != null && object != null && object instanceof View) {
container.removeView((View) object);
}
}
};
}
}