viewpager 循环滑动
时间: 2023-09-22 10:11:00 浏览: 108
要实现 ViewPager 的循环滑动,可以通过以下步骤:
1. 继承 ViewPager 类,重写 `onTouchEvent` 方法,使其支持循环滑动。
```java
public class LoopViewPager extends ViewPager {
public LoopViewPager(Context context) {
super(context);
}
public LoopViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN) {
stopAutoScroll();
} else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
startAutoScroll();
}
return super.onTouchEvent(event);
}
}
```
2. 重写 `onMeasure` 方法,使其支持 wrap_content。
```java
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int height = 0;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
int h = child.getMeasuredHeight();
if (h > height) {
height = h;
}
}
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
```
3. 重写 `setAdapter` 方法,使其支持循环滑动。
```java
@Override
public void setAdapter(PagerAdapter adapter) {
super.setAdapter(adapter);
setCurrentItem(0);
}
@Override
public void setCurrentItem(int item) {
int realCount = getRealCount();
if (realCount == 0) {
super.setCurrentItem(item);
return;
}
int position = getRealPosition(item);
super.setCurrentItem(position);
}
private int getRealCount() {
PagerAdapter adapter = getAdapter();
if (adapter == null) {
return 0;
}
return adapter.getCount();
}
private int getRealPosition(int position) {
int realCount = getRealCount();
if (realCount == 0) {
return 0;
}
return position % realCount;
}
```
4. 在 `onPageSelected` 回调中处理循环滑动的逻辑。
```java
@Override
public void onPageSelected(int position) {
int realCount = getRealCount();
if (realCount == 0) {
return;
}
int realPosition = getRealPosition(position);
if (realPosition == 0) {
setCurrentItem(realCount, false);
} else if (realPosition == realCount - 1) {
setCurrentItem(1, false);
}
}
```
5. 在 `startAutoScroll` 和 `stopAutoScroll` 方法中处理自动滑动的逻辑。
```java
private void startAutoScroll() {
stopAutoScroll();
mHandler.postDelayed(mAutoScrollTask, mInterval);
}
private void stopAutoScroll() {
mHandler.removeCallbacks(mAutoScrollTask);
}
private Runnable mAutoScrollTask = new Runnable() {
@Override
public void run() {
int currentItem = getCurrentItem();
setCurrentItem(currentItem + 1, true);
mHandler.postDelayed(this, mInterval);
}
};
```
完整的实现代码如下:
```java
public class LoopViewPager extends ViewPager {
private static final int DEFAULT_INTERVAL = 3000;
private Handler mHandler = new Handler();
private int mInterval = DEFAULT_INTERVAL;
public LoopViewPager(Context context) {
super(context);
init();
}
public LoopViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
setPageTransformer(true, new DefaultTransformer());
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN) {
stopAutoScroll();
} else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
startAutoScroll();
}
return super.onTouchEvent(event);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int height = 0;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
int h = child.getMeasuredHeight();
if (h > height) {
height = h;
}
}
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
public void setAdapter(PagerAdapter adapter) {
super.setAdapter(adapter);
setCurrentItem(0);
}
@Override
public void setCurrentItem(int item) {
int realCount = getRealCount();
if (realCount == 0) {
super.setCurrentItem(item);
return;
}
int position = getRealPosition(item);
super.setCurrentItem(position);
}
@Override
public void setCurrentItem(int item, boolean smoothScroll) {
int realCount = getRealCount();
if (realCount == 0) {
super.setCurrentItem(item, smoothScroll);
return;
}
int position = getRealPosition(item);
super.setCurrentItem(position, smoothScroll);
}
@Override
public int getCurrentItem() {
int realCount = getRealCount();
if (realCount == 0) {
return super.getCurrentItem();
}
int position = super.getCurrentItem();
return getRealPosition(position);
}
private int getRealCount() {
PagerAdapter adapter = getAdapter();
if (adapter == null) {
return 0;
}
return adapter.getCount();
}
private int getRealPosition(int position) {
int realCount = getRealCount();
if (realCount == 0) {
return 0;
}
return position % realCount;
}
@Override
public void onPageSelected(int position) {
int realCount = getRealCount();
if (realCount == 0) {
return;
}
int realPosition = getRealPosition(position);
if (realPosition == 0) {
setCurrentItem(realCount, false);
} else if (realPosition == realCount - 1) {
setCurrentItem(1, false);
}
}
public void setInterval(int interval) {
mInterval = interval;
}
public void startAutoScroll() {
stopAutoScroll();
mHandler.postDelayed(mAutoScrollTask, mInterval);
}
public void stopAutoScroll() {
mHandler.removeCallbacks(mAutoScrollTask);
}
private Runnable mAutoScrollTask = new Runnable() {
@Override
public void run() {
int currentItem = getCurrentItem();
setCurrentItem(currentItem + 1, true);
mHandler.postDelayed(this, mInterval);
}
};
private static class DefaultTransformer implements ViewPager.PageTransformer {
@Override
public void transformPage(View page, float position) {
if (position < -1) {
page.setAlpha(0);
} else if (position <= 1) {
float scaleFactor = Math.max(0.75f, 1 - Math.abs(position - 0.125f));
page.setScaleX(scaleFactor);
page.setScaleY(scaleFactor);
} else {
page.setAlpha(0);
}
}
}
}
```
使用方式:
```xml
<com.example.LoopViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
```
```java
LoopViewPager viewPager = findViewById(R.id.view_pager);
PagerAdapter adapter = new MyPagerAdapter();
viewPager.setAdapter(adapter);
viewPager.setInterval(3000);
viewPager.startAutoScroll();
```
阅读全文