Skip to content

Commit 7c268b7

Browse files
author
uis
committed
重构scroll
1 parent 783994b commit 7c268b7

1 file changed

Lines changed: 62 additions & 38 deletions

File tree

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

Lines changed: 62 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@
2424

2525
public class StackViewLayout extends ViewGroup{
2626

27-
public final static int MODEL_LEFT = 1;
28-
public final static int MODEL_RIGHT = 2;
29-
public final static int MODEL_TOP = 3;
30-
public final static int MODEL_BOTTOM = 4;
27+
public final static int MODEL_LEFT = 0x01;
28+
public final static int MODEL_RIGHT = 0x02;
29+
public final static int MODEL_TOP = 0x04;
30+
public final static int MODEL_BOTTOM = 0x08;
3131

3232
private int stackSize = 3;
3333
private float aspectRatio = 0;
@@ -39,16 +39,19 @@ public class StackViewLayout extends ViewGroup{
3939
private int paddingY = 10;
4040
private int offsetY = 2;
4141

42-
private int startX, startY,current;
42+
private float initX,lastX,initY, lastY;
43+
private int current;
4344
private VelocityTracker mVelocity;
4445
private int mMaximumVelocity;
4546
private int mTouchSlop;
4647
private Scroller mScroller;
4748
private ScheduledThreadPoolExecutor executor;
4849
private StackViewAdapter adapter;
49-
private int mDuration = 500;
50+
private int mDuration = 600;
5051
private int mDelay = 3000;
5152
private int childWidthMeasure,childHeightMeasure;
53+
54+
private int dragModel;
5255
private boolean mIsDragged = false;
5356
private List<Integer> xSpace = new ArrayList<>(stackSize);
5457
private List<Integer> ySpace = new ArrayList<>(stackSize);
@@ -122,7 +125,6 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
122125

123126
@Override
124127
protected void onLayout(boolean changed, int l, int t, int r, int b) {
125-
log("onLayout "+changed+",l="+l);
126128
int size = getOffsetXSize();
127129
for (int i = getChildCount(); i<size+2 && size>0; i++) {
128130
int cnt = adapter.getItemCount();
@@ -175,17 +177,23 @@ public void computeScroll() {
175177
int dx = mScroller.getCurrX();
176178
scrollDx(dx);
177179
ViewCompat.postInvalidateOnAnimation(this);
178-
}else{
179-
endScroll();
180180
}
181181
}
182182

183183
private void scrollDx(int dx){
184+
int x = dx*childWidthMeasure/getMeasuredWidth();
184185
int count = getChildCount();
185-
int i = count-2;
186-
View child = getChildAt(i);
187-
188-
int left = getPaddingLeft()+edge+xSpace.get(i-1)+dx;
186+
View child;
187+
int left;
188+
if( 0 == (dragModel&stackModel)){
189+
int i = count-2;
190+
child = getChildAt(i);
191+
left = getPaddingLeft()+edge+xSpace.get(i-1)+x;
192+
}else{
193+
int i = count-1;
194+
child = getChildAt(i);
195+
left = getPaddingLeft()+(MODEL_LEFT == stackModel?getMeasuredWidth():-childWidthMeasure)+x;
196+
}
189197
int right = left + childWidthMeasure;
190198
int top = getPaddingTop();
191199
int bottom = childHeightMeasure-top;
@@ -194,22 +202,26 @@ private void scrollDx(int dx){
194202

195203
private void scrollVelocity(int velocity){
196204
int count = getChildCount();
197-
int i = count-2;
198-
199-
View child = getChildAt(i);
200-
int dx = getPaddingLeft()+edge+xSpace.get(i-1)-child.getLeft();
205+
View child;
206+
int dx;
207+
if( 0 == (dragModel&stackModel)) {
208+
int i = count - 2;
209+
child = getChildAt(i);
210+
dx = getPaddingLeft()+edge+xSpace.get(i-1)-child.getLeft();
211+
}else{
212+
int i = count-1;
213+
child = getChildAt(i);
214+
dx = getPaddingLeft()+(MODEL_LEFT == stackModel?getMeasuredWidth():-childWidthMeasure)-child.getLeft();
215+
}
201216
startScroll(-dx,dx);
202217
}
203218

204219
private void startScroll(int begin,int dx){
205-
mScroller.startScroll(begin,0,dx,0,mDuration);
220+
int mills = Math.max(mDuration*Math.abs(dx)/getMeasuredWidth(),mDuration/2);
221+
mScroller.startScroll(begin,0,dx,0,mills);
206222
ViewCompat.postInvalidateOnAnimation(this);
207223
}
208224

209-
private void endScroll(){
210-
211-
}
212-
213225
private void handleAutoPlay(boolean play){
214226
if(play) {
215227
if(executor == null || executor.isShutdown()){
@@ -257,32 +269,40 @@ protected void onDetachedFromWindow() {
257269

258270
@Override
259271
public boolean onInterceptTouchEvent(MotionEvent ev) {
260-
log(" action="+ev.getAction()+",x="+ev.getX()+",y="+ev.getY());
272+
log(" action="+ev.getAction()+",x="+ev.getX()+",y="+ev.getY()+",slop="+mTouchSlop);
261273
final int action = ev.getAction() & MotionEvent.ACTION_MASK;
262274
switch (action) {
263275
case MotionEvent.ACTION_DOWN:
276+
mScroller.abortAnimation();
277+
mIsDragged = false;
264278
initVelocityTracker();
265-
startX = (int) ev.getX();
266-
startY = (int) ev.getY();
279+
lastX = initX = ev.getX();
280+
lastY = initY = ev.getY();
267281
break;
268282
//fixed inner view touch
269283
case MotionEvent.ACTION_MOVE:
270-
float xDistance = Math.abs(startX - ev.getX());
271-
float yDistance = Math.abs(startY - ev.getY());
272-
if (xDistance > yDistance && xDistance > mTouchSlop) {
284+
float dx = ev.getX() - lastX;
285+
float xDistance = Math.abs(dx);
286+
float yDistance = Math.abs(lastY - ev.getY());
287+
if (xDistance > mTouchSlop && xDistance/2 > yDistance) {
273288
//水平滑动,需要拦截 在RecyclerView中需要禁止父类拦截
274289
requestDisallowInterceptTouchEvent(true);
290+
dragModel = dx > 0 ? MODEL_RIGHT : MODEL_LEFT;
291+
lastX = dx > 0 ? initX+mTouchSlop : initX-mTouchSlop;
275292
mIsDragged = true;
276293
return true;
277294
}
278-
default:
295+
break;
296+
case MotionEvent.ACTION_UP:
297+
case MotionEvent.ACTION_CANCEL:
298+
scrollVelocity(0);
299+
break;
279300
}
280301
return false;
281302
}
282303

283304
@Override
284305
public boolean onTouchEvent(MotionEvent ev) {
285-
log("action="+ev.getAction()+",x="+ev.getX()+",y="+ev.getY());
286306
if(adapter == null || adapter.getItemCount() <= 1){
287307
return false;
288308
}
@@ -293,18 +313,23 @@ public boolean onTouchEvent(MotionEvent ev) {
293313
int action = ev.getActionMasked();
294314
switch (action) {
295315
case MotionEvent.ACTION_DOWN:
316+
mScroller.abortAnimation();
296317
mIsDragged = false;
297318
break;
298319
case MotionEvent.ACTION_MOVE:
299-
float xDistance = Math.abs(startX - ev.getX());
300-
float yDistance = Math.abs(startY - ev.getY());
301-
if (xDistance > yDistance && xDistance > mTouchSlop) {
302-
requestDisallowInterceptTouchEvent(true);
303-
mIsDragged = true;
320+
if(!mIsDragged) {
321+
float dx = ev.getX()-lastX;
322+
float xDistance = Math.abs(dx);
323+
float yDistance = Math.abs(ev.getY() - lastY);
324+
if (xDistance > yDistance && xDistance > mTouchSlop) {
325+
requestDisallowInterceptTouchEvent(true);
326+
mIsDragged = true;
327+
dragModel = dx > 0 ? MODEL_RIGHT : MODEL_LEFT;
328+
lastX = dx > 0 ? initX+mTouchSlop : initX-mTouchSlop;
329+
}
304330
}
305331
if(mIsDragged){
306-
int currentX = (int) ev.getX();
307-
scrollDx(currentX-startX);
332+
scrollDx((int)(ev.getX()-lastX));
308333
}
309334
break;
310335
case MotionEvent.ACTION_UP:
@@ -313,7 +338,6 @@ public boolean onTouchEvent(MotionEvent ev) {
313338
int velocity = (int) mVelocity.getXVelocity();
314339
scrollVelocity(velocity);
315340
recycleVelocityTracker();
316-
default:
317341
}
318342
return true;
319343
}

0 commit comments

Comments
 (0)