前言
這次要在上一篇輪播圖的基礎上做改造,增加兩個功能:
- 用戶觸摸到輪播圖時,停止輪播
- 在輪播圖上展示一個小指示器,指示當前輪播組件的位置
觸摸停播
觸摸停播的設計思路是:監聽實現輪播圖的觸摸事件,如果用戶正在觸摸就停止自動輪播。
package com.example.loopapplication.looper;import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.viewpager.widget.ViewPager;public class TouchableViewPager extends ViewPager {OnViewPagerTouchListener mOnViewPagerTouchListener;public TouchableViewPager(@NonNull Context context) {super(context);}public TouchableViewPager(@NonNull Context context, @Nullable AttributeSet attrs) {super(context, attrs);}@Overridepublic boolean onTouchEvent(MotionEvent ev) {switch (ev.getAction()) {case MotionEvent.ACTION_DOWN:// 觸摸開始if (mOnViewPagerTouchListener != null) {mOnViewPagerTouchListener.onPageTouched(true);}break;case MotionEvent.ACTION_CANCEL:case MotionEvent.ACTION_UP:// 觸摸結束if (mOnViewPagerTouchListener != null) {mOnViewPagerTouchListener.onPageTouched(false);}break;}return super.onTouchEvent(ev);}public void setOnTouchListener(TouchableViewPager.OnViewPagerTouchListener listener) {mOnViewPagerTouchListener = listener;}public interface OnViewPagerTouchListener{void onPageTouched(boolean isTouched);}
}
mViewPager.setOnTouchListener(new TouchableViewPager.OnViewPagerTouchListener() {@Overridepublic void onPageTouched(boolean isTouched) {mIsTouch = isTouched;}});
private Runnable mLoopTask = new Runnable() {@Overridepublic void run() {if (!mIsTouch) {int currentItems = mViewPager.getCurrentItem();// 將當前組件序號自增,達到自動輪播的效果mViewPager.setCurrentItem(++currentItems);}// 自動輪播間隔1秒mHandler.postDelayed(this, 2000);}};
?
指示器
指示器的設計思路是:
輪播圖初始化時,創建數據個數相等的小圓點,默認為未選中狀態。
監聽輪播圖切換輪播視圖事件,每次組件切換都遍歷一次圓點,將對應當前數據位置的圓點改成選中態。
/*** 初始化圓點陣列*/private void initPointIndication() {mPointIndication = this.findViewById(R.id.point_indication);for (int i = 0; i < mPictures.size(); i++) {View viewPoint = new View(this);LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewUtils.dp2dx(this, 15), ViewUtils.dp2dx(this, 15));layoutParams.leftMargin = ViewUtils.dp2dx(this, 10);viewPoint.setLayoutParams(layoutParams);viewPoint.setBackground(getResources().getDrawable(R.drawable.shape_point_normal));mPointIndication.addView(viewPoint);}}/*** 設置圓點選中態* @param curPosition*/private void setPointIndication(int curPosition) {if (mPointIndication != null) {for (int i = 0; i < mPointIndication.getChildCount(); i++) {View point = mPointIndication.getChildAt(i);if (point != null) {if (i == curPosition) {Log.d(TAG, "setPointIndication: 選中 " + i);point.setBackground(getResources().getDrawable(R.drawable.shape_point_selected));} else {point.setBackground(getResources().getDrawable(R.drawable.shape_point_normal));}}}}}
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {@Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}@Overridepublic void onPageSelected(int position) {// 輪播當前展示的位置 需要換算成數據里面的真實位置int realPosition = 0;if (mLooperPagerAdapter.getDataSize() != 0) {realPosition = position % mLooperPagerAdapter.getDataSize();}Log.d(TAG, "onPageSelected: position = " + position + ", real position = " + realPosition + ", data size = " + mLooperPagerAdapter.getDataSize());setPointIndication(realPosition);}@Overridepublic void onPageScrollStateChanged(int state) {}});