Skip to content

Commit 9de4db4

Browse files
author
uis
committed
重构翻页、轮播
1 parent 7c268b7 commit 9de4db4

1 file changed

Lines changed: 98 additions & 33 deletions

File tree

stacklayout/src/main/java/com/uis/stackviewlayout/StackViewLayout.java

Lines changed: 98 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import android.view.View;
1111
import android.view.ViewConfiguration;
1212
import android.view.ViewGroup;
13+
import android.view.animation.Interpolator;
1314
import android.widget.Scroller;
1415
import androidx.core.view.ViewCompat;
1516

@@ -53,9 +54,19 @@ public class StackViewLayout extends ViewGroup{
5354

5455
private int dragModel;
5556
private boolean mIsDragged = false;
57+
private boolean mIsFling = false;
58+
5659
private List<Integer> xSpace = new ArrayList<>(stackSize);
5760
private List<Integer> ySpace = new ArrayList<>(stackSize);
5861

62+
private static final Interpolator sInterpolator = new Interpolator() {
63+
@Override
64+
public float getInterpolation(float t) {
65+
t -= 1.0f;
66+
return t * t * t * t * t + 1.0f;
67+
}
68+
};
69+
5970
public StackViewLayout(Context context) {
6071
this(context, null);
6172
}
@@ -90,7 +101,7 @@ public StackViewLayout(Context context, AttributeSet attrs, int defStyleAttr) {
90101
ViewConfiguration configuration = ViewConfiguration.get(getContext());
91102
mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
92103
mTouchSlop = configuration.getScaledTouchSlop();
93-
mScroller = new Scroller(context);
104+
mScroller = new Scroller(context,sInterpolator);
94105
if(isInEditMode()){
95106
adapter = new StackViewAdapter() {
96107
@Override
@@ -111,6 +122,18 @@ public int getItemCount() {
111122
}
112123
}
113124

125+
@Override
126+
protected void onAttachedToWindow() {
127+
super.onAttachedToWindow();
128+
startAutoPlay();
129+
}
130+
131+
@Override
132+
protected void onDetachedFromWindow() {
133+
super.onDetachedFromWindow();
134+
stopAutoPlay(true);
135+
}
136+
114137
@Override
115138
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
116139
int width = getDefaultSize(0, widthMeasureSpec);
@@ -177,6 +200,8 @@ public void computeScroll() {
177200
int dx = mScroller.getCurrX();
178201
scrollDx(dx);
179202
ViewCompat.postInvalidateOnAnimation(this);
203+
}else{
204+
nextPage();
180205
}
181206
}
182207

@@ -200,20 +225,66 @@ private void scrollDx(int dx){
200225
child.layout(left,top,right,bottom);
201226
}
202227

228+
private void resetTouch(){
229+
mScroller.abortAnimation();
230+
stopAutoPlay(false);
231+
}
232+
233+
private int getSign(){
234+
return MODEL_LEFT == stackModel?1:-1;
235+
}
236+
203237
private void scrollVelocity(int velocity){
204238
int count = getChildCount();
205239
View child;
206240
int dx;
241+
int sign;
207242
if( 0 == (dragModel&stackModel)) {
208243
int i = count - 2;
209244
child = getChildAt(i);
210245
dx = getPaddingLeft()+edge+xSpace.get(i-1)-child.getLeft();
246+
sign = getSign();
211247
}else{
212248
int i = count-1;
213249
child = getChildAt(i);
214250
dx = getPaddingLeft()+(MODEL_LEFT == stackModel?getMeasuredWidth():-childWidthMeasure)-child.getLeft();
251+
sign = -getSign();
252+
}
253+
if(velocity*sign>getMeasuredWidth() || -dx*sign>0.45*childWidthMeasure){
254+
int dnx = dx+sign*(getMeasuredWidth()+edge);
255+
startScroll(-dx,dnx);
256+
mIsFling = true;
257+
}else {
258+
startScroll(-dx, dx);
259+
}
260+
startAutoPlay();
261+
}
262+
263+
private void autoScroll(){
264+
if(mScroller.isFinished() && adapter!=null && adapter.getItemCount()>1){
265+
dragModel = MODEL_LEFT==stackModel ? MODEL_RIGHT:MODEL_LEFT;
266+
scrollVelocity(2*getMeasuredWidth()*getSign());
267+
}
268+
}
269+
270+
private void nextPage(){
271+
if(mIsFling) {
272+
mIsFling = false;
273+
int cnt = adapter.getItemCount();
274+
if (0 == (dragModel & stackModel)){
275+
current = (current+1)%cnt;
276+
int position = (current+stackSize)%cnt;
277+
int viewType = adapter.getItemViewType(position);
278+
View child = adapter.onCreateView(this, viewType);
279+
addView(child,0);
280+
removeViewAt(getChildCount() - 1);
281+
adapter.onBindView(child,position);
282+
adapter.onPageSelected(current);
283+
} else {
284+
current = (current-1+cnt)%cnt;
285+
removeViewAt(0);
286+
}
215287
}
216-
startScroll(-dx,dx);
217288
}
218289

219290
private void startScroll(int begin,int dx){
@@ -222,28 +293,42 @@ private void startScroll(int begin,int dx){
222293
ViewCompat.postInvalidateOnAnimation(this);
223294
}
224295

225-
private void handleAutoPlay(boolean play){
226-
if(play) {
227-
if(executor == null || executor.isShutdown()){
296+
private void startAutoPlay(){
297+
if(autoPlay) {
298+
if (executor == null || executor.isShutdown()) {
228299
executor = new ScheduledThreadPoolExecutor(1);
300+
}
301+
if (executor.getQueue().size() <= 0) {
229302
executor.scheduleWithFixedDelay(new Runnable() {
230303
@Override
231304
public void run() {
232-
305+
autoScroll();
233306
}
234307
}, mDelay, mDelay, TimeUnit.MILLISECONDS);
235308
}
236-
}else{
309+
}
310+
}
311+
312+
private void stopAutoPlay(boolean force){
313+
if(force) {
237314
if(executor != null && !executor.isShutdown()) {
238315
executor.shutdownNow();
239316
executor = null;
240317
}
318+
}else{
319+
if(executor != null){
320+
executor.getQueue().clear();
321+
}
241322
}
242323
}
243324

244325
public void setAutoPlay(boolean autoPlay){
245326
this.autoPlay = autoPlay;
246-
handleAutoPlay(autoPlay);
327+
if(autoPlay){
328+
startAutoPlay();
329+
}else{
330+
stopAutoPlay(false);
331+
}
247332
}
248333

249334
public void setAdapter(StackViewAdapter adapter) {
@@ -255,25 +340,16 @@ public StackViewAdapter getAdapter(){
255340
return adapter;
256341
}
257342

258-
@Override
259-
protected void onAttachedToWindow() {
260-
super.onAttachedToWindow();
261-
handleAutoPlay(autoPlay);
262-
}
263-
264-
@Override
265-
protected void onDetachedFromWindow() {
266-
super.onDetachedFromWindow();
267-
handleAutoPlay(false);
268-
}
269-
270343
@Override
271344
public boolean onInterceptTouchEvent(MotionEvent ev) {
272345
log(" action="+ev.getAction()+",x="+ev.getX()+",y="+ev.getY()+",slop="+mTouchSlop);
346+
if(adapter == null || adapter.getItemCount() <= 1){
347+
return false;
348+
}
273349
final int action = ev.getAction() & MotionEvent.ACTION_MASK;
274350
switch (action) {
275351
case MotionEvent.ACTION_DOWN:
276-
mScroller.abortAnimation();
352+
resetTouch();
277353
mIsDragged = false;
278354
initVelocityTracker();
279355
lastX = initX = ev.getX();
@@ -293,16 +369,13 @@ public boolean onInterceptTouchEvent(MotionEvent ev) {
293369
return true;
294370
}
295371
break;
296-
case MotionEvent.ACTION_UP:
297-
case MotionEvent.ACTION_CANCEL:
298-
scrollVelocity(0);
299-
break;
300372
}
301373
return false;
302374
}
303375

304376
@Override
305377
public boolean onTouchEvent(MotionEvent ev) {
378+
log(" action="+ev.getAction()+",x="+ev.getX()+",y="+ev.getY());
306379
if(adapter == null || adapter.getItemCount() <= 1){
307380
return false;
308381
}
@@ -312,10 +385,6 @@ public boolean onTouchEvent(MotionEvent ev) {
312385
mVelocity.addMovement(ev);
313386
int action = ev.getActionMasked();
314387
switch (action) {
315-
case MotionEvent.ACTION_DOWN:
316-
mScroller.abortAnimation();
317-
mIsDragged = false;
318-
break;
319388
case MotionEvent.ACTION_MOVE:
320389
if(!mIsDragged) {
321390
float dx = ev.getX()-lastX;
@@ -342,10 +411,6 @@ public boolean onTouchEvent(MotionEvent ev) {
342411
return true;
343412
}
344413

345-
private void resetTouch(){
346-
347-
}
348-
349414
private void initVelocityTracker() {
350415
if (mVelocity == null) {
351416
mVelocity = VelocityTracker.obtain();

0 commit comments

Comments
 (0)