您的位置:首页 > 移动开发 > Android开发

android实现uc和墨迹天气那样的左右拖动效果

2012-11-29 09:13 351 查看

[代码]FlingGalleryActivity

001
import
android.app.Activity;
002
import
android.os.Bundle;
003
004
import

android.content.Context;
005
import

android.graphics.Color;
006
import

android.util.Log;
007
import

android.view.Gravity;
008
import

android.view.MotionEvent;
009
import

android.view.View;
010
import

android.view.ViewGroup;
011
import

android.view.View.OnClickListener;
012
import

android.widget.ArrayAdapter;
013
import

android.widget.Button;
014
import

android.widget.CheckBox;
015
import

android.widget.EditText;
016
import

android.widget.LinearLayout;
017
import

android.widget.TableLayout;
018
import

android.widget.TextView;
019
020
public
class
FlingGalleryActivity
extends

Activity
021
{
022
private

final
int

color_red=Color.argb(
100
,
200
,
0
,
0
);
023
private

final
int

color_green=Color.argb(
100
,
0
,
200
,
0
);
024
private

final
int

color_blue=Color.argb(
100
,
0
,
0
,
200
);
025
private

final
int

color_yellow=Color.argb(
100
,
200
,
200
,
0
);
026
private

final
int

color_purple=Color.argb(
100
,
200
,
0
,
200
);
027
028
private

final
String[]mLabelArray={
"View1"
,
"View2"
,

"View3"
,
"View4"
,
"View5"
};

029
private

final
int
[]mColorArray={color_red,color_green,color_blue,color_yellow,color_purple};
030
031
private

FlingGallerymGallery;
032
private

CheckBoxmCheckBox;
033
034
//Note:Thefollowinghandleriscriticaltocorrectfunctionof
035
//theFlingGalleryclass.ThisenablestheFlingGalleryclassto
036
//detectwhenthemotioneventhasendedbyfingerbeinglifted
037
038
@Override
039
public

boolean
onTouchEvent(MotionEventevent)
040
{

041
return

mGallery.onGalleryTouchEvent(event);
042
}

043
044
public

void
onCreate(BundlesavedInstanceState)
045
{

046
super
.onCreate(savedInstanceState);
047
048
mGallery=
new
FlingGallery(
this
);
049
mGallery.setPaddingWidth(
5
);
050
mGallery.setAdapter(
new

ArrayAdapter<String>(getApplicationContext(),android.R.layout.simple_list_item_1,mLabelArray)
051
{
052
@Override
053
public

ViewgetView(
int

position,ViewconvertView,ViewGroupparent)
054
{
055
Log.d(
"111"
,
"count="
+position);
056
//if(convertView!=null&&convertViewinstanceofGalleryViewItem)
057
//{
058
//GalleryViewItemgalleryView=(GalleryViewItem)convertView;
059
//
060
//galleryView.mEdit1.setText("");
061
//galleryView.mText1.setText(mLabelArray[position]);
062
//galleryView.mText1.setBackgroundColor(mColorArray[position]);
063
//galleryView.mText2.setText(mLabelArray[position]);
064
//galleryView.mText2.setBackgroundColor(mColorArray[position]);
065
//
066
//Log.d("111","count="+position);
067
//
068
//returngalleryView;
069
//
070
//}
071
072
return

new
GalleryViewItem(getApplicationContext(),position);
073
}
074
});
075
076
LinearLayoutlayout=
new
LinearLayout(getApplicationContext());
077
layout.setOrientation(LinearLayout.VERTICAL);
078
079
LinearLayout.LayoutParamslayoutParams=
new
LinearLayout.LayoutParams(
080
LinearLayout.LayoutParams.MATCH_PARENT,
081
LinearLayout.LayoutParams.MATCH_PARENT);
082
083
layoutParams.setMargins(
10
,
10
,
10
,
10
);
084
layoutParams.weight=
1
.0f;
085
086
layout.addView(mGallery,layoutParams);
087
088
mCheckBox=
new
CheckBox(getApplicationContext());
089
mCheckBox.setText(
"GalleryisCircular"
);
090
mCheckBox.setText(
"GalleryisCircular"
);
091
mCheckBox.setPadding(
50
,
10
,
0
,
10
);
092
mCheckBox.setTextSize(
30
);
093
mCheckBox.setChecked(
true
);
094
mCheckBox.setOnClickListener(
new

OnClickListener()
095
{
096
@Override
097
public

void
onClick(Viewview)
098
{
099
mGallery.setIsGalleryCircular(mCheckBox.isChecked());
100
}
101
});
102
103
layout.addView(mCheckBox,
new
LinearLayout.LayoutParams(
104
LinearLayout.LayoutParams.MATCH_PARENT,
105
LinearLayout.LayoutParams.WRAP_CONTENT));
106
107
setContentView(layout);
108
}
109
110
private

class
GalleryViewItem

extends
TableLayout

111
{

112
private

EditTextmEdit1;
113
private

TextViewmText1;
114
private

TextViewmText2;
115
private

ButtonmButton1;
116
private

ButtonmButton2;
117
118
public

GalleryViewItem(Contextcontext,
int

position)
119
{
120
super
(context);
121
122
this
.setOrientation(LinearLayout.VERTICAL);
123
124
this
.setLayoutParams(
new

LinearLayout.LayoutParams(
125
LinearLayout.LayoutParams.MATCH_PARENT,
126
LinearLayout.LayoutParams.MATCH_PARENT));
127
128
mEdit1=
new
EditText(context);
129
130
this
.addView(mEdit1,
new
LinearLayout.LayoutParams(
131
LinearLayout.LayoutParams.MATCH_PARENT,
132
LinearLayout.LayoutParams.WRAP_CONTENT));
133
134
mText1=
new
TextView(context);
135
mText1.setText(mLabelArray[position]);
136
mText1.setTextSize(
30
);
137
mText1.setGravity(Gravity.LEFT);
138
mText1.setBackgroundColor(mColorArray[position]);
139
140
this
.addView(mText1,
new
LinearLayout.LayoutParams(
141
LinearLayout.LayoutParams.MATCH_PARENT,
142
LinearLayout.LayoutParams.WRAP_CONTENT));
143
144
mButton1=
new
Button(context);
145
mButton1.setText(
"<<"
);
146
mButton1.setGravity(Gravity.LEFT);
147
mButton1.setOnClickListener(
new

OnClickListener()
148
{
149
@Override
150
public

void
onClick(Viewview)
151
{
152
mGallery.movePrevious();
153
}
154
});
155
156
this
.addView(mButton1,
new
LinearLayout.LayoutParams(
157
LinearLayout.LayoutParams.MATCH_PARENT,
158
LinearLayout.LayoutParams.WRAP_CONTENT));
159
160
mButton2=
new
Button(context);
161
mButton2.setText(
">>"
);
162
mButton2.setGravity(Gravity.RIGHT);
163
mButton2.setOnClickListener(
new

OnClickListener()
164
{
165
@Override
166
public

void
onClick(Viewview)
167
{
168
mGallery.moveNext();
169
}
170
});
171
172
this
.addView(mButton2,
new
LinearLayout.LayoutParams(
173
LinearLayout.LayoutParams.MATCH_PARENT,
174
LinearLayout.LayoutParams.WRAP_CONTENT));
175
176
mText2=
new
TextView(context);
177
mText2.setText(mLabelArray[position]);
178
mText2.setTextSize(
30
);
179
mText2.setGravity(Gravity.RIGHT);
180
mText2.setBackgroundColor(mColorArray[position]);
181
182
this
.addView(mText2,
new
LinearLayout.LayoutParams(
183
LinearLayout.LayoutParams.MATCH_PARENT,
184
LinearLayout.LayoutParams.MATCH_PARENT,
1
));
185
}
186
}

187
}

[代码]FlingGallery

viewsource

print?

001
import

android.content.Context;
002
import

android.view.GestureDetector;
003
import

android.view.KeyEvent;
004
import

android.view.MotionEvent;
005
import

android.view.View;
006
import

android.view.animation.Animation;
007
import

android.view.animation.AnimationUtils;
008
import

android.view.animation.Interpolator;
009
import

android.view.animation.Transformation;
010
import

android.widget.Adapter;
011
import

android.widget.FrameLayout;
012
import

android.widget.LinearLayout;
013
014
//TODO:
015
016
//1.InordertoimproveperformanceCachescreenbitmapanduseforanimation
017
//2.Establishsuperfluousmemoryallocationsanddelayorreplacewithreusedobjects
018
//Probablyneedtomakesurewearenotallocatingobjects(strings,etc.)inloops
019
020
public
class
FlingGallery
extends

FrameLayout
021
{
022
//Constants
023
024
private

final
int

swipe_min_distance=
120
;
025
private

final
int

swipe_max_off_path=
250
;
026
private

final
int

swipe_threshold_veloicty=
400
;
027
028
//Properties
029
030
private

int
mViewPaddingWidth=
0
;
031
private

int
mAnimationDuration=
250
;
032
private

float
mSnapBorderRatio=
0
.5f;
033
private

boolean
mIsGalleryCircular=
true
;
034
035
//Members
036
037
private

int
mGalleryWidth=

0
;
038
private

boolean
mIsTouched=

false
;
039
private

boolean
mIsDragging=

false
;
040
private

float
mCurrentOffset=
0
.0f;
041
private

long
mScrollTimestamp=
0
;
042
private

int
mFlingDirection=

0
;
043
private

int
mCurrentPosition=
0
;
044
private

int
mCurrentViewNumber=
0
;
045
046
private

ContextmContext;
047
private

AdaptermAdapter;
048
private

FlingGalleryView[]mViews;
049
private

FlingGalleryAnimationmAnimation;
050
private

GestureDetectormGestureDetector;
051
private

InterpolatormDecelerateInterpolater;
052
053
public

FlingGallery(Contextcontext)
054
{

055
super
(context);
056
057
mContext=context;
058
mAdapter=
null
;
059
060
mViews=
new
FlingGalleryView[
3
];
061
mViews[
0
]=
new
FlingGalleryView(
0
,
this
);
062
mViews[
1
]=
new
FlingGalleryView(
1
,
this
);
063
mViews[
2
]=
new
FlingGalleryView(
2
,
this
);
064
065
mAnimation=
new
FlingGalleryAnimation();
066
mGestureDetector=
new
GestureDetector(
new

FlingGestureDetector());
067
mDecelerateInterpolater=AnimationUtils.loadInterpolator(mContext,android.R.anim.decelerate_interpolator);
068
}

069
070
public

void
setPaddingWidth(
int

viewPaddingWidth)
071
{

072
mViewPaddingWidth=viewPaddingWidth;
073
}

074
075
public

void
setAnimationDuration(
int

animationDuration)
076
{

077
mAnimationDuration=animationDuration;
078
}

079
080
public

void
setSnapBorderRatio(
float

snapBorderRatio)
081
{

082
mSnapBorderRatio=snapBorderRatio;
083
}

084
085
public

void
setIsGalleryCircular(
boolean

isGalleryCircular)
086
{

087
if

(mIsGalleryCircular!=isGalleryCircular)
088
{
089
mIsGalleryCircular=isGalleryCircular;
090
091
if

(mCurrentPosition==getFirstPosition())
092
{
093
//Weneedtoreloadtheviewimmediatelytothelefttochangeittocircularvieworblank
094
mViews[getPrevViewNumber(mCurrentViewNumber)].recycleView(getPrevPosition(mCurrentPosition));
095
}
096
097
if

(mCurrentPosition==getLastPosition())
098
{
099
//Weneedtoreloadtheviewimmediatelytotherighttochangeittocircularvieworblank
100
mViews[getNextViewNumber(mCurrentViewNumber)].recycleView(getNextPosition(mCurrentPosition));
101
}
102
}
103
}

104
105
public

int
getGalleryCount()

106
{

107
return

(mAdapter==
null
)?
0
:mAdapter.getCount();
108
}

109
110
public

int
getFirstPosition()
111
{

112
return

0
;
113
}

114
115
public

int
getLastPosition()

116
{

117
return

(getGalleryCount()==
0
)?
0
:getGalleryCount()-
1
;
118
}

119
120
private

int
getPrevPosition(
int

relativePosition)
121
{

122
int

prevPosition=relativePosition-
1
;
123
124
if

(prevPosition<getFirstPosition())
125
{
126
prevPosition=getFirstPosition()-
1
;
127
128
if

(mIsGalleryCircular==
true
)
129
{
130
prevPosition=getLastPosition();
131
}
132
}
133
134
return

prevPosition;
135
}

136
137
private

int
getNextPosition(
int

relativePosition)
138
{

139
int

nextPosition=relativePosition+
1
;
140
141
if

(nextPosition>getLastPosition())
142
{
143
nextPosition=getLastPosition()+
1
;
144
145
if

(mIsGalleryCircular==
true
)
146
{
147
nextPosition=getFirstPosition();
148
}
149
}
150
151
return

nextPosition;
152
}

153
154
private

int
getPrevViewNumber(
int

relativeViewNumber)
155
{

156
return

(relativeViewNumber==
0
)?
2
:relativeViewNumber-
1
;
157
}

158
159
private

int
getNextViewNumber(
int

relativeViewNumber)
160
{

161
return

(relativeViewNumber==
2
)?
0
:relativeViewNumber+
1
;
162
}

163
164
@Override
165
protected

void
onLayout(
boolean

changed,
int

left,
int
top,

int
right,
int

bottom)
166
{

167
super
.onLayout(changed,left,top,right,bottom);
168
169
//Calculateourviewwidth
170
mGalleryWidth=right-left;
171
172
if

(changed==
true
)
173
{
174
//Positionviewsatcorrectstartingoffsets
175
mViews[
0
].setOffset(
0
,
0
,mCurrentViewNumber);
176
mViews[
1
].setOffset(
0
,
0
,mCurrentViewNumber);
177
mViews[
2
].setOffset(
0
,
0
,mCurrentViewNumber);
178
}
179
}

180
181
public

void
setAdapter(Adapteradapter)
182
{

183
mAdapter=adapter;
184
mCurrentPosition=
0
;
185
mCurrentViewNumber=
0
;
186
187
//Loadtheinitialviewsfromadapter
188
mViews[
0
].recycleView(mCurrentPosition);
189
mViews[
1
].recycleView(getNextPosition(mCurrentPosition));
190
mViews[
2
].recycleView(getPrevPosition(mCurrentPosition));
191
192
//Positionviewsatcorrectstartingoffsets
193
mViews[
0
].setOffset(
0
,
0
,mCurrentViewNumber);
194
mViews[
1
].setOffset(
0
,
0
,mCurrentViewNumber);
195
mViews[
2
].setOffset(
0
,
0
,mCurrentViewNumber);
196
}

197
198
private

int
getViewOffset(
int

viewNumber,
int

relativeViewNumber)
199
{

200
//Determinewidthincludingconfiguredpaddingwidth
201
int

offsetWidth=mGalleryWidth+mViewPaddingWidth;

202
203
//Positionthepreviousviewonemeasuredwidthtoleft
204
if

(viewNumber==getPrevViewNumber(relativeViewNumber))

205
{
206
return

offsetWidth;
207
}
208
209
//Positionthenextviewonemeasuredwidthtotheright
210
if

(viewNumber==getNextViewNumber(relativeViewNumber))

211
{
212
return

offsetWidth*-
1
;
213
}
214
215
return

0
;
216
}

217
218
void

movePrevious()
219
{

220
//Slidetopreviousview
221
mFlingDirection=
1
;
222
processGesture();
223
}

224
225
void

moveNext()
226
{

227
//Slidetonextview
228
mFlingDirection=-
1
;
229
processGesture();
230
}

231
232
@Override
233
public

boolean
onKeyDown(
int

keyCode,KeyEventevent)
234
{

235
switch

(keyCode)
236
{
237
case

KeyEvent.KEYCODE_DPAD_LEFT:
238
movePrevious();
239
return

true
;
240
241
case

KeyEvent.KEYCODE_DPAD_RIGHT:
242
moveNext();
243
return

true
;
244
245
case

KeyEvent.KEYCODE_DPAD_CENTER:
246
case

KeyEvent.KEYCODE_ENTER:
247
}
248
249
return

super
.onKeyDown(keyCode,event);
250
}

251
252
public

boolean
onGalleryTouchEvent(MotionEventevent)
253
{

254
boolean

consumed=mGestureDetector.onTouchEvent(event);

255
256
if

(event.getAction()==MotionEvent.ACTION_UP)
257
{
258
if

(mIsTouched||mIsDragging)
259
{
260
processScrollSnap();
261
processGesture();
262
}
263
}
264
265
return

consumed;
266
}

267
268
void

processGesture()
269
{

270
int

newViewNumber=mCurrentViewNumber;
271
int

reloadViewNumber=
0
;
272
int

reloadPosition=
0
;
273
274
mIsTouched=
false
;
275
mIsDragging=
false
;
276
277
if

(mFlingDirection>
0
)
278
{
279
if

(mCurrentPosition>getFirstPosition()||mIsGalleryCircular==
true
)
280
{
281
//Determinepreviousviewandoutgoingviewtorecycle
282
newViewNumber=getPrevViewNumber(mCurrentViewNumber);
283
mCurrentPosition=getPrevPosition(mCurrentPosition);
284
reloadViewNumber=getNextViewNumber(mCurrentViewNumber);
285
reloadPosition=getPrevPosition(mCurrentPosition);
286
}
287
}
288
289
if

(mFlingDirection<
0
)
290
{
291
if

(mCurrentPosition<getLastPosition()||mIsGalleryCircular==
true
)
292
{
293
//Determinethenextviewandoutgoingviewtorecycle
294
newViewNumber=getNextViewNumber(mCurrentViewNumber);
295
mCurrentPosition=getNextPosition(mCurrentPosition);
296
reloadViewNumber=getPrevViewNumber(mCurrentViewNumber);
297
reloadPosition=getNextPosition(mCurrentPosition);
298
}
299
}
300
301
if

(newViewNumber!=mCurrentViewNumber)
302
{
303
mCurrentViewNumber=newViewNumber;
304
305
//Reloadoutgoingviewfromadapterinnewposition
306
mViews[reloadViewNumber].recycleView(reloadPosition);
307
}
308
309
//Ensureinputfocusonthecurrentview
310
mViews[mCurrentViewNumber].requestFocus();
311
312
//Runtheslideanimationsforviewtransitions
313
mAnimation.prepareAnimation(mCurrentViewNumber);
314
this
.startAnimation(mAnimation);
315
316
//Resetflingstate
317
mFlingDirection=
0
;
318
}

319
320
void

processScrollSnap()
321
{

322
//Snaptonextviewifscrolledpassedsnapposition
323
float

rollEdgeWidth=mGalleryWidth*mSnapBorderRatio;

324
int

rollOffset=mGalleryWidth-(
int
)rollEdgeWidth;
325
int

currentOffset=mViews[mCurrentViewNumber].getCurrentOffset();
326
327
if

(currentOffset<=rollOffset*-
1
)
328
{
329
//Snaptopreviousview
330
mFlingDirection=
1
;
331
}
332
333
if

(currentOffset>=rollOffset)
334
{
335
//Snaptonextview
336
mFlingDirection=-
1
;
337
}
338
}

339
340
private

class
FlingGalleryView
341
{

342
private

int
mViewNumber;

343
private

FrameLayoutmParentLayout;
344
345
private

FrameLayoutmInvalidLayout=
null
;
346
private

LinearLayoutmInternalLayout=
null
;
347
private

ViewmExternalView=
null
;
348
349
public

FlingGalleryView(
int

viewNumber,FrameLayoutparentLayout)
350
{
351
mViewNumber=viewNumber;
352
mParentLayout=parentLayout;
353
354
//Invalidlayoutisusedwhenoutsidegallery
355
mInvalidLayout=
new
FrameLayout(mContext);
356
mInvalidLayout.setLayoutParams(
new

LinearLayout.LayoutParams(
357
LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));
358
359
//Internallayoutispermanentforduration
360
mInternalLayout=
new
LinearLayout(mContext);
361
mInternalLayout.setLayoutParams(
new

LinearLayout.LayoutParams(
362
LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));
363
364
mParentLayout.addView(mInternalLayout);
365
}
366
367
public

void
recycleView(
int

newPosition)
368
{
369
if

(mExternalView!=
null
)
370
{
371
mInternalLayout.removeView(mExternalView);
372
}
373
374
if

(mAdapter!=
null
)
375
{
376
if

(newPosition>=getFirstPosition()&&newPosition<=getLastPosition())
377
{
378
mExternalView=mAdapter.getView(newPosition,mExternalView,mInternalLayout);
379
}
380
else
381
{
382
mExternalView=mInvalidLayout;
383
}
384
}
385
386
if

(mExternalView!=
null
)
387
{
388
mInternalLayout.addView(mExternalView,
new
LinearLayout.LayoutParams(
389
LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));
390
}
391
}
392
393
public

void
setOffset(
int

xOffset,
int

yOffset,
int
relativeViewNumber)
394
{
395
//Scrollthetargetviewrelativetoitsownpositionrelativetocurrentlydisplayedview
396
mInternalLayout.scrollTo(getViewOffset(mViewNumber,relativeViewNumber)+xOffset,yOffset);
397
}
398
399
public

int
getCurrentOffset()
400
{
401
//Returnthecurrentscrollposition
402
return

mInternalLayout.getScrollX();
403
}
404
405
public

void
requestFocus()

406
{
407
mInternalLayout.requestFocus();
408
}
409
}

410
411
private

class
FlingGalleryAnimation
extends
Animation
412
{

413
private

boolean
mIsAnimationInProgres;
414
private

int
mRelativeViewNumber;
415
private

int
mInitialOffset;

416
private

int
mTargetOffset;

417
private

int
mTargetDistance;
418
419
public

FlingGalleryAnimation()
420
{
421
mIsAnimationInProgres=
false
;
422
mRelativeViewNumber=
0
;
423
mInitialOffset=
0
;
424
mTargetOffset=
0
;
425
mTargetDistance=
0
;
426
}
427
428
public

void
prepareAnimation(
int

relativeViewNumber)
429
{
430
//Ifweareanimatingrelativetoanewview
431
if

(mRelativeViewNumber!=relativeViewNumber)
432
{
433
if

(mIsAnimationInProgres==
true
)
434
{
435
//Weonlyhavethreeviewssoifrequestedagaintoanimateinsamedirectionwemustsnap
436
int

newDirection=(relativeViewNumber==getPrevViewNumber(mRelativeViewNumber))?
1
:-
1
;
437
int

animDirection=(mTargetDistance<
0
)?
1
:-
1
;
438
439
//Ifanimationinsamedirection
440
if

(animDirection==newDirection)
441
{
442
//Ranoutoftimetoanimatesosnaptothetargetoffset
443
mViews[
0
].setOffset(mTargetOffset,
0
,mRelativeViewNumber);
444
mViews[
1
].setOffset(mTargetOffset,
0
,mRelativeViewNumber);
445
mViews[
2
].setOffset(mTargetOffset,
0
,mRelativeViewNumber);
446
}
447
}
448
449
//Setrelativeviewnumberforanimation
450
mRelativeViewNumber=relativeViewNumber;
451
}
452
453
//Note:InthisimplementationthetargetOffsetwillalwaysbezero
454
//aswearecenteringtheview;butweincludethecalculationsof
455
//targetOffsetandtargetDistanceforuseinfutureimplementations
456
457
mInitialOffset=mViews[mRelativeViewNumber].getCurrentOffset();
458
mTargetOffset=getViewOffset(mRelativeViewNumber,mRelativeViewNumber);
459
mTargetDistance=mTargetOffset-mInitialOffset;
460
461
//Configurebaseanimationproperties
462
this
.setDuration(mAnimationDuration);
463
this
.setInterpolator(mDecelerateInterpolater);
464
465
//Start/continuedanimation
466
mIsAnimationInProgres=
true
;
467
}
468
469
@Override
470
protected

void
applyTransformation(
float

interpolatedTime,Transformationtransformation)

471
{
472
//EnsureinterpolatedTimedoesnotover-shootthencalculatenewoffset
473
interpolatedTime=(interpolatedTime>
1
.0f)?
1
.0f:interpolatedTime;
474
int

offset=mInitialOffset+(
int
)(mTargetDistance*interpolatedTime);
475
476
for

(
int

viewNumber=
0
;viewNumber<
3
;viewNumber++)

477
{
478
//Onlyneedtoanimatethevisibleviewsastheotherviewwillalwaysbeoff-screen
479
if

((mTargetDistance>
0

&&viewNumber!=getNextViewNumber(mRelativeViewNumber))||
480
(mTargetDistance<
0
&&viewNumber!=getPrevViewNumber(mRelativeViewNumber)))
481
{
482
mViews[viewNumber].setOffset(offset,
0
,mRelativeViewNumber);
483
}
484
}
485
}
486
487
@Override
488
public

boolean
getTransformation(
long

currentTime,TransformationoutTransformation)
489
{
490
if

(
super
.getTransformation(currentTime,outTransformation)==
false
)
491
{
492
//Performfinaladjustmenttooffsetstocleanupanimation
493
mViews[
0
].setOffset(mTargetOffset,
0
,mRelativeViewNumber);
494
mViews[
1
].setOffset(mTargetOffset,
0
,mRelativeViewNumber);
495
mViews[
2
].setOffset(mTargetOffset,
0
,mRelativeViewNumber);
496
497
//Reachedtheanimationtarget
498
mIsAnimationInProgres=
false
;
499
500
return

false
;
501
}
502
503
//Cancelifthescreentouched
504
if

(mIsTouched||mIsDragging)
505
{
506
//Notethatatthispointwestillconsiderourselvestobeanimating
507
//becausewehavenotyetreachedthetargetoffset;itsjustthatthe
508
//userhastemporarilyinterruptedtheanimationwithatouchgesture
509
510
return

false
;
511
}
512
513
return

true
;
514
}
515
}

516
517
private

class
FlingGestureDetector
extends
GestureDetector.SimpleOnGestureListener
518
{

519
@Override
520
public

boolean
onDown(MotionEvente)
521
{
522
//Stopanimation
523
mIsTouched=
true
;
524
525
//Resetflingstate
526
mFlingDirection=
0
;
527
return

true
;
528
}
529
530
@Override
531
public

boolean
onScroll(MotionEvente1,MotionEvente2,
float
distanceX,
float
distanceY)
532
{
533
if

(e2.getAction()==MotionEvent.ACTION_MOVE)
534
{
535
if

(mIsDragging==
false
)
536
{
537
//Stopanimation
538
mIsTouched=
true
;
539
540
//Reconfigurescroll
541
mIsDragging=
true
;
542
mFlingDirection=
0
;
543
mScrollTimestamp=System.currentTimeMillis();
544
mCurrentOffset=mViews[mCurrentViewNumber].getCurrentOffset();
545
}
546
547
float

maxVelocity=mGalleryWidth/(mAnimationDuration/

1000
.0f);
548
long

timestampDelta=System.currentTimeMillis()-mScrollTimestamp;
549
float

maxScrollDelta=maxVelocity*(timestampDelta/

1000
.0f);
550
float

currentScrollDelta=e1.getX()-e2.getX();
551
552
if

(currentScrollDelta<maxScrollDelta*-
1
)currentScrollDelta=maxScrollDelta*-
1
;
553
if

(currentScrollDelta>maxScrollDelta)currentScrollDelta=maxScrollDelta;
554
int

scrollOffset=Math.round(mCurrentOffset+currentScrollDelta);
555
556
//Wecan'tscrollmorethanthewidthofourownframelayout
557
if

(scrollOffset>=mGalleryWidth)scrollOffset=mGalleryWidth;
558
if

(scrollOffset<=mGalleryWidth*-
1
)scrollOffset=mGalleryWidth*-
1
;
559
560
mViews[
0
].setOffset(scrollOffset,
0
,mCurrentViewNumber);
561
mViews[
1
].setOffset(scrollOffset,
0
,mCurrentViewNumber);
562
mViews[
2
].setOffset(scrollOffset,
0
,mCurrentViewNumber);
563
}
564
565
return

false
;
566
}
567
568
@Override
569
public

boolean
onFling(MotionEvente1,MotionEvente2,
float
velocityX,
float
velocityY)
570
{
571
if

(Math.abs(e1.getY()-e2.getY())<=swipe_max_off_path)

572
{
573
if

(e2.getX()-e1.getX()>swipe_min_distance&&Math.abs(velocityX)>swipe_threshold_veloicty)
574
{
575
movePrevious();
576
}
577
578
if
(e1.getX()-e2.getX()>swipe_min_distance&&Math.abs(velocityX)>swipe_threshold_veloicty)
579
{
580
moveNext();
581
}
582
}
583
584
return

false
;
585
}
586
587
@Override
588
public

void
onLongPress(MotionEvente)
589
{
590
//Finalisescrolling
591
mFlingDirection=
0
;
592
processGesture();
593
}
594
595
@Override
596
public

void
onShowPress(MotionEvente)
597
{
598
}
599
600
@Override
601
public

boolean
onSingleTapUp(MotionEvente)
602
{
603
//Resetflingstate
604
mFlingDirection=
0
;
605
return

false
;
606
}
607
}

608
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: