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

来源:互联网 发布:乐股软件官方下载 编辑:程序博客网 时间:2024/06/02 10:01

代码片段(2)

[代码] FlingGalleryActivity

001import android.app.Activity;
002import android.os.Bundle;
003 
004import android.content.Context;
005import android.graphics.Color;
006import android.util.Log;
007import android.view.Gravity;
008import android.view.MotionEvent;
009import android.view.View;
010import android.view.ViewGroup;
011import android.view.View.OnClickListener;
012import android.widget.ArrayAdapter;
013import android.widget.Button;
014import android.widget.CheckBox;
015import android.widget.EditText;
016import android.widget.LinearLayout;
017import android.widget.TableLayout;
018import android.widget.TextView;
019 
020public classFlingGalleryActivity extendsActivity
021{
022    privatefinal int color_red = Color.argb(100,200, 0,0);
023    privatefinal int color_green = Color.argb(100,0, 200,0);
024    privatefinal int color_blue = Color.argb(100,0, 0,200);
025    privatefinal int color_yellow = Color.argb(100,200, 200,0);
026    privatefinal int color_purple = Color.argb(100,200, 0,200);
027 
028    privatefinal String[] mLabelArray = {"View1","View2", "View3","View4", "View5"};
029    privatefinal int[] mColorArray = {color_red, color_green, color_blue, color_yellow, color_purple};
030 
031    privateFlingGallery mGallery;
032    privateCheckBox mCheckBox;
033 
034    // Note: The following handler is critical to correct function of
035    // the FlingGallery class. This enables the FlingGallery class to
036    // detect when the motion event has ended by finger being lifted
037 
038    @Override
039    publicboolean onTouchEvent(MotionEvent event)
040    {
041        returnmGallery.onGalleryTouchEvent(event);
042    }
043 
044    publicvoid onCreate(Bundle savedInstanceState)
045    {
046        super.onCreate(savedInstanceState);
047 
048        mGallery =new FlingGallery(this);
049        mGallery.setPaddingWidth(5);
050        mGallery.setAdapter(newArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, mLabelArray)
051        {
052            @Override
053            publicView getView(int position, View convertView, ViewGroup parent)
054            {
055                Log.d("111","count="+position);
056//              if (convertView != null && convertView instanceof GalleryViewItem)
057//                {
058//                  GalleryViewItem galleryView = (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//                  return galleryView;
069//                 
070//                }
071                 
072                returnnew GalleryViewItem(getApplicationContext(), position);
073            }
074        });
075 
076        LinearLayout layout =new LinearLayout(getApplicationContext());
077        layout.setOrientation(LinearLayout.VERTICAL);
078 
079        LinearLayout.LayoutParams layoutParams =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("Gallery is Circular");
090        mCheckBox.setText("Gallery is Circular");
091        mCheckBox.setPadding(50,10, 0,10);
092        mCheckBox.setTextSize(30);
093        mCheckBox.setChecked(true);
094        mCheckBox.setOnClickListener(newOnClickListener()
095        {
096            @Override
097            publicvoid onClick(View view)
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    privateclass GalleryViewItem extendsTableLayout
111    {
112        privateEditText mEdit1;
113        privateTextView mText1;
114        privateTextView mText2;
115        privateButton mButton1;
116        privateButton mButton2;
117 
118        publicGalleryViewItem(Context context, intposition)
119        {
120            super(context);
121 
122            this.setOrientation(LinearLayout.VERTICAL);
123 
124            this.setLayoutParams(newLinearLayout.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(newOnClickListener()
148            {
149                @Override
150                publicvoid onClick(View view)
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(newOnClickListener()
164            {
165                @Override
166                publicvoid onClick(View view)
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

001import android.content.Context;
002import android.view.GestureDetector;
003import android.view.KeyEvent;
004import android.view.MotionEvent;
005import android.view.View;
006import android.view.animation.Animation;
007import android.view.animation.AnimationUtils;
008import android.view.animation.Interpolator;
009import android.view.animation.Transformation;
010import android.widget.Adapter;
011import android.widget.FrameLayout;
012import android.widget.LinearLayout;
013 
014// TODO:
015 
016// 1. In order to improve performance Cache screen bitmap and use for animation
017// 2. Establish superfluous memory allocations and delay or replace with reused objects
018//    Probably need to make sure we are not allocating objects (strings, etc.) in loops
019 
020public classFlingGallery extends FrameLayout
021{
022    // Constants
023     
024    privatefinal int swipe_min_distance = 120;
025    privatefinal int swipe_max_off_path = 250;
026    privatefinal int swipe_threshold_veloicty = 400;
027 
028    // Properties
029     
030    privateint mViewPaddingWidth = 0;
031    privateint mAnimationDuration = 250;
032    privatefloat mSnapBorderRatio = 0.5f;
033    privateboolean mIsGalleryCircular = true;
034 
035    // Members
036 
037    privateint mGalleryWidth = 0;
038    privateboolean mIsTouched = false;
039    privateboolean mIsDragging = false;
040    privatefloat mCurrentOffset = 0.0f;
041    privatelong mScrollTimestamp = 0;
042    privateint mFlingDirection = 0;
043    privateint mCurrentPosition = 0;
044    privateint mCurrentViewNumber = 0;
045 
046    privateContext mContext;
047    privateAdapter mAdapter;
048    privateFlingGalleryView[] mViews;
049    privateFlingGalleryAnimation mAnimation;
050    privateGestureDetector mGestureDetector;
051    privateInterpolator mDecelerateInterpolater;
052 
053    publicFlingGallery(Context context)
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(newFlingGestureDetector());
067        mDecelerateInterpolater = AnimationUtils.loadInterpolator(mContext, android.R.anim.decelerate_interpolator);
068    }
069 
070    publicvoid setPaddingWidth(intviewPaddingWidth)
071    {
072        mViewPaddingWidth = viewPaddingWidth;
073    }
074 
075    publicvoid setAnimationDuration(intanimationDuration)
076    {
077        mAnimationDuration = animationDuration;
078    }
079     
080    publicvoid setSnapBorderRatio(floatsnapBorderRatio)
081    {
082        mSnapBorderRatio = snapBorderRatio;
083    }
084 
085    publicvoid setIsGalleryCircular(booleanisGalleryCircular)
086    {
087        if(mIsGalleryCircular != isGalleryCircular)
088        {
089            mIsGalleryCircular = isGalleryCircular;
090     
091            if(mCurrentPosition == getFirstPosition())
092            {
093                // We need to reload the view immediately to the left to change it to circular view or blank
094                mViews[getPrevViewNumber(mCurrentViewNumber)].recycleView(getPrevPosition(mCurrentPosition));          
095            }
096     
097            if(mCurrentPosition == getLastPosition())
098            {
099                // We need to reload the view immediately to the right to change it to circular view or blank
100                mViews[getNextViewNumber(mCurrentViewNumber)].recycleView(getNextPosition(mCurrentPosition));          
101            }
102        }
103    }
104 
105    publicint getGalleryCount()
106    {
107        return(mAdapter == null) ?0 : mAdapter.getCount();
108    }
109 
110    publicint getFirstPosition()
111    {
112        return0;
113    }
114 
115    publicint getLastPosition()
116    {
117        return(getGalleryCount() == 0) ?0 : getGalleryCount() - 1;
118    }
119 
120    privateint getPrevPosition(intrelativePosition)
121    {
122        intprevPosition = 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        returnprevPosition;
135    }
136 
137    privateint getNextPosition(intrelativePosition)
138    {
139        intnextPosition = 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        returnnextPosition;
152    }
153 
154    privateint getPrevViewNumber(intrelativeViewNumber)
155    {
156        return(relativeViewNumber == 0) ?2 : relativeViewNumber - 1;
157    }
158 
159    privateint getNextViewNumber(intrelativeViewNumber)
160    {
161        return(relativeViewNumber == 2) ?0 : relativeViewNumber + 1;
162    }
163     
164    @Override
165    protectedvoid onLayout(booleanchanged, int left, int top, intright, int bottom)
166    {
167        super.onLayout(changed, left, top, right, bottom);
168 
169        // Calculate our view width
170        mGalleryWidth = right - left;
171 
172        if(changed == true)
173        {
174            // Position views at correct starting offsets
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    publicvoid setAdapter(Adapter adapter)
182    {
183        mAdapter = adapter;
184        mCurrentPosition =0;
185        mCurrentViewNumber =0;
186 
187        // Load the initial views from adapter
188        mViews[0].recycleView(mCurrentPosition);
189        mViews[1].recycleView(getNextPosition(mCurrentPosition));
190        mViews[2].recycleView(getPrevPosition(mCurrentPosition));
191 
192        // Position views at correct starting offsets
193        mViews[0].setOffset(0,0, mCurrentViewNumber);
194        mViews[1].setOffset(0,0, mCurrentViewNumber);
195        mViews[2].setOffset(0,0, mCurrentViewNumber);
196    }
197 
198    privateint getViewOffset(intviewNumber, int relativeViewNumber)
199    {
200        // Determine width including configured padding width
201        intoffsetWidth = mGalleryWidth + mViewPaddingWidth;
202 
203        // Position the previous view one measured width to left
204        if(viewNumber == getPrevViewNumber(relativeViewNumber))
205        {
206            returnoffsetWidth;
207        }
208 
209        // Position the next view one measured width to the right
210        if(viewNumber == getNextViewNumber(relativeViewNumber))
211        {
212            returnoffsetWidth * -1;
213        }
214 
215        return0;
216    }
217 
218    voidmovePrevious()
219    {
220        // Slide to previous view
221        mFlingDirection =1;
222        processGesture();
223    }
224 
225    voidmoveNext()
226    {
227        // Slide to next view
228        mFlingDirection = -1;
229        processGesture();
230    }
231 
232     @Override
233     publicboolean onKeyDown(intkeyCode, KeyEvent event)
234     {
235        switch(keyCode)
236        {
237        caseKeyEvent.KEYCODE_DPAD_LEFT:
238            movePrevious();
239            returntrue;
240     
241        caseKeyEvent.KEYCODE_DPAD_RIGHT:
242            moveNext();
243            returntrue;
244     
245        caseKeyEvent.KEYCODE_DPAD_CENTER:
246        caseKeyEvent.KEYCODE_ENTER:
247        }
248 
249        returnsuper.onKeyDown(keyCode, event);
250    }
251 
252    publicboolean onGalleryTouchEvent(MotionEvent event)
253    {
254        booleanconsumed = 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        returnconsumed;
266    }
267 
268    voidprocessGesture()
269    {
270        intnewViewNumber = mCurrentViewNumber;
271        intreloadViewNumber = 0;
272        intreloadPosition = 0;
273 
274        mIsTouched =false;
275        mIsDragging =false;
276 
277        if(mFlingDirection > 0)
278        {
279            if(mCurrentPosition > getFirstPosition() || mIsGalleryCircular ==true)
280            {
281                // Determine previous view and outgoing view to recycle
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                // Determine the next view and outgoing view to recycle
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            // Reload outgoing view from adapter in new position
306            mViews[reloadViewNumber].recycleView(reloadPosition);
307        }
308 
309        // Ensure input focus on the current view
310        mViews[mCurrentViewNumber].requestFocus();
311 
312        // Run the slide animations for view transitions
313        mAnimation.prepareAnimation(mCurrentViewNumber);
314        this.startAnimation(mAnimation);
315 
316        // Reset fling state
317        mFlingDirection =0;
318    }
319 
320    voidprocessScrollSnap()
321    {
322        // Snap to next view if scrolled passed snap position
323        floatrollEdgeWidth = mGalleryWidth * mSnapBorderRatio;
324        introllOffset = mGalleryWidth - (int) rollEdgeWidth;
325        intcurrentOffset = mViews[mCurrentViewNumber].getCurrentOffset();
326 
327        if(currentOffset <= rollOffset * -1)
328        {
329            // Snap to previous view
330            mFlingDirection =1;
331        }
332 
333        if(currentOffset >= rollOffset)
334        {
335            // Snap to next view
336            mFlingDirection = -1;
337        }
338    }
339 
340    privateclass FlingGalleryView
341    {
342        privateint mViewNumber;
343        privateFrameLayout mParentLayout;
344         
345        privateFrameLayout mInvalidLayout = null;
346        privateLinearLayout mInternalLayout = null;
347        privateView mExternalView = null;
348 
349        publicFlingGalleryView(int viewNumber, FrameLayout parentLayout)
350        {
351            mViewNumber = viewNumber;
352            mParentLayout = parentLayout;
353 
354            // Invalid layout is used when outside gallery
355            mInvalidLayout =new FrameLayout(mContext);
356            mInvalidLayout.setLayoutParams(newLinearLayout.LayoutParams(
357                    LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
358 
359            // Internal layout is permanent for duration
360            mInternalLayout =new LinearLayout(mContext);
361            mInternalLayout.setLayoutParams(newLinearLayout.LayoutParams(
362                    LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
363 
364            mParentLayout.addView(mInternalLayout);
365        }
366 
367        publicvoid recycleView(intnewPosition)
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        publicvoid setOffset(intxOffset, int yOffset, int relativeViewNumber)
394        {
395            // Scroll the target view relative to its own position relative to currently displayed view
396            mInternalLayout.scrollTo(getViewOffset(mViewNumber, relativeViewNumber) + xOffset, yOffset);
397        }
398         
399        publicint getCurrentOffset()
400        {
401            // Return the current scroll position
402            returnmInternalLayout.getScrollX();
403        }
404 
405        publicvoid requestFocus()
406        {
407            mInternalLayout.requestFocus();
408        }
409    }
410 
411    privateclass FlingGalleryAnimation extends Animation
412    {
413        privateboolean mIsAnimationInProgres;
414        privateint mRelativeViewNumber;
415        privateint mInitialOffset;
416        privateint mTargetOffset;
417        privateint mTargetDistance;   
418  
419        publicFlingGalleryAnimation()
420        {
421            mIsAnimationInProgres =false;
422            mRelativeViewNumber =0;
423            mInitialOffset =0;
424            mTargetOffset =0;
425            mTargetDistance =0;
426        }
427  
428        publicvoid prepareAnimation(intrelativeViewNumber)
429        {
430            // If we are animating relative to a new view
431            if(mRelativeViewNumber != relativeViewNumber)
432            {
433                if(mIsAnimationInProgres == true)
434                {
435                    // We only have three views so if requested again to animate in same direction we must snap
436                    intnewDirection = (relativeViewNumber == getPrevViewNumber(mRelativeViewNumber)) ?1 : -1;
437                    intanimDirection = (mTargetDistance < 0) ?1 : -1;
438 
439                    // If animation in same direction
440                    if(animDirection == newDirection)
441                    {
442                        // Ran out of time to animate so snap to the target offset
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                // Set relative view number for animation
450                mRelativeViewNumber = relativeViewNumber;
451            }
452 
453            // Note: In this implementation the targetOffset will always be zero
454            // as we are centering the view; but we include the calculations of
455            // targetOffset and targetDistance for use in future implementations
456 
457            mInitialOffset = mViews[mRelativeViewNumber].getCurrentOffset();
458            mTargetOffset = getViewOffset(mRelativeViewNumber, mRelativeViewNumber);
459            mTargetDistance = mTargetOffset - mInitialOffset;
460 
461            // Configure base animation properties
462            this.setDuration(mAnimationDuration);
463            this.setInterpolator(mDecelerateInterpolater);
464 
465            // Start/continued animation
466            mIsAnimationInProgres =true;
467        }
468 
469        @Override
470        protectedvoid applyTransformation(floatinterpolatedTime, Transformation transformation)
471        {
472            // Ensure interpolatedTime does not over-shoot then calculate new offset
473            interpolatedTime = (interpolatedTime >1.0f) ? 1.0f : interpolatedTime;
474            intoffset = mInitialOffset + (int) (mTargetDistance * interpolatedTime);
475 
476            for(int viewNumber = 0; viewNumber <3; viewNumber++)
477            {
478                // Only need to animate the visible views as the other view will always be off-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        publicboolean getTransformation(longcurrentTime, Transformation outTransformation)
489        {
490            if(super.getTransformation(currentTime, outTransformation) ==false)
491            {
492                // Perform final adjustment to offsets to cleanup animation
493                mViews[0].setOffset(mTargetOffset,0, mRelativeViewNumber);
494                mViews[1].setOffset(mTargetOffset,0, mRelativeViewNumber);
495                mViews[2].setOffset(mTargetOffset,0, mRelativeViewNumber);
496 
497                // Reached the animation target
498                mIsAnimationInProgres =false;
499 
500                returnfalse;
501            }
502  
503            // Cancel if the screen touched
504            if(mIsTouched || mIsDragging)
505            {
506                // Note that at this point we still consider ourselves to be animating
507                // because we have not yet reached the target offset; its just that the
508                // user has temporarily interrupted the animation with a touch gesture
509 
510                returnfalse;
511            }
512 
513            returntrue;
514        }
515    }
516 
517    privateclass FlingGestureDetector extends GestureDetector.SimpleOnGestureListener
518    {
519        @Override
520        publicboolean onDown(MotionEvent e)
521        {
522            // Stop animation
523            mIsTouched =true;
524 
525            // Reset fling state
526            mFlingDirection =0;
527            returntrue;
528        }
529 
530        @Override
531        publicboolean onScroll(MotionEvent e1, MotionEvent e2,float distanceX, floatdistanceY)
532        {
533            if(e2.getAction() == MotionEvent.ACTION_MOVE)
534            {
535                if(mIsDragging == false)
536                {
537                    // Stop animation
538                    mIsTouched =true;
539      
540                    // Reconfigure scroll
541                    mIsDragging =true;
542                    mFlingDirection =0;
543                    mScrollTimestamp = System.currentTimeMillis();
544                    mCurrentOffset = mViews[mCurrentViewNumber].getCurrentOffset();
545                }
546 
547                floatmaxVelocity = mGalleryWidth / (mAnimationDuration / 1000.0f);
548                longtimestampDelta = System.currentTimeMillis() - mScrollTimestamp;
549                floatmaxScrollDelta = maxVelocity * (timestampDelta / 1000.0f);
550                floatcurrentScrollDelta = e1.getX() - e2.getX();
551 
552                if(currentScrollDelta < maxScrollDelta * -1) currentScrollDelta = maxScrollDelta * -1;
553                if(currentScrollDelta > maxScrollDelta) currentScrollDelta = maxScrollDelta;
554                intscrollOffset = Math.round(mCurrentOffset + currentScrollDelta);
555 
556                // We can't scroll more than the width of our own frame layout
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            returnfalse;
566        }
567 
568        @Override
569        publicboolean onFling(MotionEvent e1, MotionEvent e2,float velocityX, floatvelocityY)
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            returnfalse;
585        }
586 
587        @Override
588        publicvoid onLongPress(MotionEvent e)
589        {
590            // Finalise scrolling
591            mFlingDirection =0;
592            processGesture();
593        }
594 
595        @Override
596        publicvoid onShowPress(MotionEvent e)
597        {
598        }
599 
600        @Override
601        publicboolean onSingleTapUp(MotionEvent e)
602        {
603            // Reset fling state
604            mFlingDirection =0;
605            returnfalse;
606        }
607    }
608}