首页 > 站长在线 > 怎样在android实现uc和墨迹天气那样的左右拖动效果

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

  1. import android.app.Activity;
  2. import android.os.Bundle;
  3. import android.content.Context;
  4. import android.graphics.Color;
  5. import android.util.Log;
  6. import android.view.Gravity;
  7. import android.view.MotionEvent;
  8. import android.view.View;
  9. import android.view.ViewGroup;
  10. import android.view.View.OnClickListener;
  11. import android.widget.ArrayAdapter;
  12. import android.widget.Button;
  13. import android.widget.CheckBox;
  14. import android.widget.EditText;
  15. import android.widget.LinearLayout;
  16. import android.widget.TableLayout;
  17. import android.widget.TextView;
  18. public class FlingGalleryActivity extends Activity
  19. {
  20.     private final int color_red = Color.argb(100, 200, 0, 0);
  21.     private final int color_green = Color.argb(100, 0, 200, 0);
  22.     private final int color_blue = Color.argb(100, 0, 0, 200);
  23.     private final int color_yellow = Color.argb(100, 200, 200, 0);
  24.     private final int color_purple = Color.argb(100, 200, 0, 200);
  25.     private final String[] mLabelArray = {"View1", "View2", "View3", "View4", "View5"};
  26.     private final int[] mColorArray = {color_red, color_green, color_blue, color_yellow, color_purple};
  27.     private FlingGallery mGallery;
  28.     private CheckBox mCheckBox;
  29.     // Note: The following handler is critical to correct function of
  30.     // the FlingGallery class. This enables the FlingGallery class to
  31.     // detect when the motion event has ended by finger being lifted
  32.     @Override
  33.     public boolean onTouchEvent(MotionEvent event)
  34.     {
  35.         return mGallery.onGalleryTouchEvent(event);
  36.     }
  37.     public void onCreate(Bundle savedInstanceState)
  38.     {
  39.         super.onCreate(savedInstanceState);
  40.         mGallery = new FlingGallery(this);
  41.         mGallery.setPaddingWidth(5);
  42.         mGallery.setAdapter(new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, mLabelArray)
  43.         {
  44.             @Override
  45.             public View getView(int position, View convertView, ViewGroup parent)
  46.             {
  47.                 Log.d("111", "count="+position);
  48. //              if (convertView != null && convertView instanceof GalleryViewItem)
  49. //                {
  50. //                  GalleryViewItem galleryView = (GalleryViewItem) convertView;
  51. //
  52. //                  galleryView.mEdit1.setText("");
  53. //                  galleryView.mText1.setText(mLabelArray[position]);
  54. //                  galleryView.mText1.setBackgroundColor(mColorArray[position]);
  55. //                  galleryView.mText2.setText(mLabelArray[position]);
  56. //                  galleryView.mText2.setBackgroundColor(mColorArray[position]);
  57. //
  58. //                  Log.d("111", "count="+position);
  59. //
  60. //                  return galleryView;
  61. //
  62. //                }
  63.                 return new GalleryViewItem(getApplicationContext(), position);
  64.             }
  65.         });
  66.         LinearLayout layout = new LinearLayout(getApplicationContext());
  67.         layout.setOrientation(LinearLayout.VERTICAL);
  68.         LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
  69.                 LinearLayout.LayoutParams.MATCH_PARENT,
  70.                 LinearLayout.LayoutParams.MATCH_PARENT);
  71.         layoutParams.setMargins(10, 10, 10, 10);
  72.         layoutParams.weight = 1.0f;
  73.         layout.addView(mGallery, layoutParams);
  74.         mCheckBox = new CheckBox(getApplicationContext());
  75.         mCheckBox.setText("Gallery is Circular");
  76.         mCheckBox.setText("Gallery is Circular");
  77.         mCheckBox.setPadding(50, 10, 0, 10);
  78.         mCheckBox.setTextSize(30);
  79.         mCheckBox.setChecked(true);
  80.         mCheckBox.setOnClickListener(new OnClickListener()
  81.         {
  82.             @Override
  83.             public void onClick(View view)
  84.             {
  85.                 mGallery.setIsGalleryCircular(mCheckBox.isChecked());
  86.             }
  87.         });
  88.         layout.addView(mCheckBox, new LinearLayout.LayoutParams(
  89.                 LinearLayout.LayoutParams.MATCH_PARENT,
  90.                 LinearLayout.LayoutParams.WRAP_CONTENT));
  91.         setContentView(layout);
  92.     }
  93.     private class GalleryViewItem extends TableLayout
  94.     {
  95.         private EditText mEdit1;
  96.         private TextView mText1;
  97.         private TextView mText2;
  98.         private Button mButton1;
  99.         private Button mButton2;
  100.         public GalleryViewItem(Context context, int position)
  101.         {
  102.             super(context);
  103.             this.setOrientation(LinearLayout.VERTICAL);
  104.             this.setLayoutParams(new LinearLayout.LayoutParams(
  105.                     LinearLayout.LayoutParams.MATCH_PARENT,
  106.                     LinearLayout.LayoutParams.MATCH_PARENT));
  107.             mEdit1 = new EditText(context);
  108.             this.addView(mEdit1, new LinearLayout.LayoutParams(
  109.                     LinearLayout.LayoutParams.MATCH_PARENT,
  110.                     LinearLayout.LayoutParams.WRAP_CONTENT));
  111.             mText1 = new TextView(context);
  112.             mText1.setText(mLabelArray[position]);
  113.             mText1.setTextSize(30);
  114.             mText1.setGravity(Gravity.LEFT);
  115.             mText1.setBackgroundColor(mColorArray[position]);
  116.             this.addView(mText1, new LinearLayout.LayoutParams(
  117.                     LinearLayout.LayoutParams.MATCH_PARENT,
  118.                     LinearLayout.LayoutParams.WRAP_CONTENT));
  119.             mButton1 = new Button(context);
  120.             mButton1.setText("<<");
  121.             mButton1.setGravity(Gravity.LEFT);
  122.             mButton1.setOnClickListener(new OnClickListener()
  123.             {
  124.                 @Override
  125.                 public void onClick(View view)
  126.                 {
  127.                     mGallery.movePrevious();
  128.                 }
  129.             });
  130.             this.addView(mButton1, new LinearLayout.LayoutParams(
  131.                     LinearLayout.LayoutParams.MATCH_PARENT,
  132.                     LinearLayout.LayoutParams.WRAP_CONTENT));
  133.             mButton2 = new Button(context);
  134.             mButton2.setText(">>");
  135.             mButton2.setGravity(Gravity.RIGHT);
  136.             mButton2.setOnClickListener(new OnClickListener()
  137.             {
  138.                 @Override
  139.                 public void onClick(View view)
  140.                 {
  141.                     mGallery.moveNext();
  142.                 }
  143.             });
  144.             this.addView(mButton2, new LinearLayout.LayoutParams(
  145.                     LinearLayout.LayoutParams.MATCH_PARENT,
  146.                     LinearLayout.LayoutParams.WRAP_CONTENT));
  147.             mText2 = new TextView(context);
  148.             mText2.setText(mLabelArray[position]);
  149.             mText2.setTextSize(30);
  150.             mText2.setGravity(Gravity.RIGHT);
  151.             mText2.setBackgroundColor(mColorArray[position]);
  152.             this.addView(mText2, new LinearLayout.LayoutParams(
  153.                     LinearLayout.LayoutParams.MATCH_PARENT,
  154.                     LinearLayout.LayoutParams.MATCH_PARENT, 1));
  155.         }
  156.     }
  157. }
 

. [代码]FlingGallery

[html][/html] 

  1. import android.content.Context;
  2. import android.view.GestureDetector;
  3. import android.view.KeyEvent;
  4. import android.view.MotionEvent;
  5. import android.view.View;
  6. import android.view.animation.Animation;
  7. import android.view.animation.AnimationUtils;
  8. import android.view.animation.Interpolator;
  9. import android.view.animation.Transformation;
  10. import android.widget.Adapter;
  11. import android.widget.FrameLayout;
  12. import android.widget.LinearLayout;
  13. // TODO:
  14. // 1. In order to improve performance Cache screen bitmap and use for animation
  15. // 2. Establish superfluous memory allocations and delay or replace with reused objects
  16. //    Probably need to make sure we are not allocating objects (strings, etc.) in loops
  17. public class FlingGallery extends FrameLayout
  18. {
  19.     // Constants
  20.     private final int swipe_min_distance = 120;
  21.     private final int swipe_max_off_path = 250;
  22.     private final int swipe_threshold_veloicty = 400;
  23.     // Properties
  24.     private int mViewPaddingWidth = 0;
  25.     private int mAnimationDuration = 250;
  26.     private float mSnapBorderRatio = 0.5f;
  27.     private boolean mIsGalleryCircular = true;
  28.     // Members
  29.     private int mGalleryWidth = 0;
  30.     private boolean mIsTouched = false;
  31.     private boolean mIsDragging = false;
  32.     private float mCurrentOffset = 0.0f;
  33.     private long mScrollTimestamp = 0;
  34.     private int mFlingDirection = 0;
  35.     private int mCurrentPosition = 0;
  36.     private int mCurrentViewNumber = 0;
  37.     private Context mContext;
  38.     private Adapter mAdapter;
  39.     private FlingGalleryView[] mViews;
  40.     private FlingGalleryAnimation mAnimation;
  41.     private GestureDetector mGestureDetector;
  42.     private Interpolator mDecelerateInterpolater;
  43.     public FlingGallery(Context context)
  44.     {
  45.         super(context);
  46.         mContext = context;
  47.         mAdapter = null;
  48.         mViews = new FlingGalleryView[3];
  49.         mViews[0] = new FlingGalleryView(0, this);
  50.         mViews[1] = new FlingGalleryView(1, this);
  51.         mViews[2] = new FlingGalleryView(2, this);
  52.         mAnimation = new FlingGalleryAnimation();
  53.         mGestureDetector = new GestureDetector(new FlingGestureDetector());
  54.         mDecelerateInterpolater = AnimationUtils.loadInterpolator(mContext, android.R.anim.decelerate_interpolator);
  55.     }
  56.     public void setPaddingWidth(int viewPaddingWidth)
  57.     {
  58.         mViewPaddingWidth = viewPaddingWidth;
  59.     }
  60.     public void setAnimationDuration(int animationDuration)
  61.     {
  62.         mAnimationDuration = animationDuration;
  63.     }
  64.     public void setSnapBorderRatio(float snapBorderRatio)
  65.     {
  66.         mSnapBorderRatio = snapBorderRatio;
  67.     }
  68.     public void setIsGalleryCircular(boolean isGalleryCircular)
  69.     {
  70.         if (mIsGalleryCircular != isGalleryCircular)
  71.         {
  72.             mIsGalleryCircular = isGalleryCircular;
  73.             if (mCurrentPosition == getFirstPosition())
  74.             {
  75.                 // We need to reload the view immediately to the left to change it to circular view or blank
  76.                 mViews[getPrevViewNumber(mCurrentViewNumber)].recycleView(getPrevPosition(mCurrentPosition));
  77.             }
  78.             if (mCurrentPosition == getLastPosition())
  79.             {
  80.                 // We need to reload the view immediately to the right to change it to circular view or blank
  81.                 mViews[getNextViewNumber(mCurrentViewNumber)].recycleView(getNextPosition(mCurrentPosition));
  82.             }
  83.         }
  84.     }
  85.     public int getGalleryCount()
  86.     {
  87.         return (mAdapter == null) ? 0 : mAdapter.getCount();
  88.     }
  89.     public int getFirstPosition()
  90.     {
  91.         return 0;
  92.     }
  93.     public int getLastPosition()
  94.     {
  95.         return (getGalleryCount() == 0) ? 0 : getGalleryCount() - 1;
  96.     }
  97.     private int getPrevPosition(int relativePosition)
  98.     {
  99.         int prevPosition = relativePosition - 1;
  100.         if (prevPosition < getFirstPosition())
  101.         {
  102.             prevPosition = getFirstPosition() - 1;
  103.             if (mIsGalleryCircular == true)
  104.             {
  105.                 prevPosition = getLastPosition();
  106.             }
  107.         }
  108.         return prevPosition;
  109.     }
  110.     private int getNextPosition(int relativePosition)
  111.     {
  112.         int nextPosition = relativePosition + 1;
  113.         if (nextPosition > getLastPosition())
  114.         {
  115.             nextPosition = getLastPosition() + 1;
  116.             if (mIsGalleryCircular == true)
  117.             {
  118.                 nextPosition = getFirstPosition();
  119.             }
  120.         }
  121.         return nextPosition;
  122.     }
  123.     private int getPrevViewNumber(int relativeViewNumber)
  124.     {
  125.         return (relativeViewNumber == 0) ? 2 : relativeViewNumber - 1;
  126.     }
  127.     private int getNextViewNumber(int relativeViewNumber)
  128.     {
  129.         return (relativeViewNumber == 2) ? 0 : relativeViewNumber + 1;
  130.     }
  131.     @Override
  132.     protected void onLayout(boolean changed, int left, int top, int right, int bottom)
  133.     {
  134.         super.onLayout(changed, left, top, right, bottom);
  135.         // Calculate our view width
  136.         mGalleryWidth = right - left;
  137.         if (changed == true)
  138.         {
  139.             // Position views at correct starting offsets
  140.             mViews[0].setOffset(0, 0, mCurrentViewNumber);
  141.             mViews[1].setOffset(0, 0, mCurrentViewNumber);
  142.             mViews[2].setOffset(0, 0, mCurrentViewNumber);
  143.         }
  144.     }
  145.     public void setAdapter(Adapter adapter)
  146.     {
  147.         mAdapter = adapter;
  148.         mCurrentPosition = 0;
  149.         mCurrentViewNumber = 0;
  150.         // Load the initial views from adapter
  151.         mViews[0].recycleView(mCurrentPosition);
  152.         mViews[1].recycleView(getNextPosition(mCurrentPosition));
  153.         mViews[2].recycleView(getPrevPosition(mCurrentPosition));
  154.         // Position views at correct starting offsets
  155.         mViews[0].setOffset(0, 0, mCurrentViewNumber);
  156.         mViews[1].setOffset(0, 0, mCurrentViewNumber);
  157.         mViews[2].setOffset(0, 0, mCurrentViewNumber);
  158.     }
  159.     private int getViewOffset(int viewNumber, int relativeViewNumber)
  160.     {
  161.         // Determine width including configured padding width
  162.         int offsetWidth = mGalleryWidth + mViewPaddingWidth;
  163.         // Position the previous view one measured width to left
  164.         if (viewNumber == getPrevViewNumber(relativeViewNumber))
  165.         {
  166.             return offsetWidth;
  167.         }
  168.         // Position the next view one measured width to the right
  169.         if (viewNumber == getNextViewNumber(relativeViewNumber))
  170.         {
  171.             return offsetWidth * -1;
  172.         }
  173.         return 0;
  174.     }
  175.     void movePrevious()
  176.     {
  177.         // Slide to previous view
  178.         mFlingDirection = 1;
  179.         processGesture();
  180.     }
  181.     void moveNext()
  182.     {
  183.         // Slide to next view
  184.         mFlingDirection = -1;
  185.         processGesture();
  186.     }
  187.      @Override
  188.      public boolean onKeyDown(int keyCode, KeyEvent event)
  189.      {
  190.         switch (keyCode)
  191.         {
  192.         case KeyEvent.KEYCODE_DPAD_LEFT:
  193.             movePrevious();
  194.             return true;
  195.         case KeyEvent.KEYCODE_DPAD_RIGHT:
  196.             moveNext();
  197.             return true;
  198.         case KeyEvent.KEYCODE_DPAD_CENTER:
  199.         case KeyEvent.KEYCODE_ENTER:
  200.         }
  201.         return super.onKeyDown(keyCode, event);
  202.     }
  203.     public boolean onGalleryTouchEvent(MotionEvent event)
  204.     {
  205.         boolean consumed = mGestureDetector.onTouchEvent(event);
  206.         if (event.getAction() == MotionEvent.ACTION_UP)
  207.         {
  208.             if (mIsTouched || mIsDragging)
  209.             {
  210.                 processScrollSnap();
  211.                 processGesture();
  212.             }
  213.         }
  214.         return consumed;
  215.     }
  216.     void processGesture()
  217.     {
  218.         int newViewNumber = mCurrentViewNumber;
  219.         int reloadViewNumber = 0;
  220.         int reloadPosition = 0;
  221.         mIsTouched = false;
  222.         mIsDragging = false;
  223.         if (mFlingDirection > 0)
  224.         {
  225.             if (mCurrentPosition > getFirstPosition() || mIsGalleryCircular == true)
  226.             {
  227.                 // Determine previous view and outgoing view to recycle
  228.                 newViewNumber = getPrevViewNumber(mCurrentViewNumber);
  229.                 mCurrentPosition = getPrevPosition(mCurrentPosition);
  230.                 reloadViewNumber = getNextViewNumber(mCurrentViewNumber);
  231.                 reloadPosition = getPrevPosition(mCurrentPosition);
  232.             }
  233.         }
  234.         if (mFlingDirection < 0)
  235.         {
  236.             if (mCurrentPosition < getLastPosition() || mIsGalleryCircular == true)
  237.             {
  238.                 // Determine the next view and outgoing view to recycle
  239.                 newViewNumber = getNextViewNumber(mCurrentViewNumber);
  240.                 mCurrentPosition = getNextPosition(mCurrentPosition);
  241.                 reloadViewNumber = getPrevViewNumber(mCurrentViewNumber);
  242.                 reloadPosition = getNextPosition(mCurrentPosition);
  243.             }
  244.         }
  245.         if (newViewNumber != mCurrentViewNumber)
  246.         {
  247.             mCurrentViewNumber = newViewNumber;
  248.             // Reload outgoing view from adapter in new position
  249.             mViews[reloadViewNumber].recycleView(reloadPosition);
  250.         }
  251.         // Ensure input focus on the current view
  252.         mViews[mCurrentViewNumber].requestFocus();
  253.         // Run the slide animations for view transitions
  254.         mAnimation.prepareAnimation(mCurrentViewNumber);
  255.         this.startAnimation(mAnimation);
  256.         // Reset fling state
  257.         mFlingDirection = 0;
  258.     }
  259.     void processScrollSnap()
  260.     {
  261.         // Snap to next view if scrolled passed snap position
  262.         float rollEdgeWidth = mGalleryWidth * mSnapBorderRatio;
  263.         int rollOffset = mGalleryWidth - (int) rollEdgeWidth;
  264.         int currentOffset = mViews[mCurrentViewNumber].getCurrentOffset();
  265.         if (currentOffset <= rollOffset * -1)
  266.         {
  267.             // Snap to previous view
  268.             mFlingDirection = 1;
  269.         }
  270.         if (currentOffset >= rollOffset)
  271.         {
  272.             // Snap to next view
  273.             mFlingDirection = -1;
  274.         }
  275.     }
  276.     private class FlingGalleryView
  277.     {
  278.         private int mViewNumber;
  279.         private FrameLayout mParentLayout;
  280.         private FrameLayout mInvalidLayout = null;
  281.         private LinearLayout mInternalLayout = null;
  282.         private View mExternalView = null;
  283.         public FlingGalleryView(int viewNumber, FrameLayout parentLayout)
  284.         {
  285.             mViewNumber = viewNumber;
  286.             mParentLayout = parentLayout;
  287.             // Invalid layout is used when outside gallery
  288.             mInvalidLayout = new FrameLayout(mContext);
  289.             mInvalidLayout.setLayoutParams(new LinearLayout.LayoutParams(
  290.                     LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
  291.             // Internal layout is permanent for duration
  292.             mInternalLayout = new LinearLayout(mContext);
  293.             mInternalLayout.setLayoutParams(new LinearLayout.LayoutParams(
  294.                     LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
  295.             mParentLayout.addView(mInternalLayout);
  296.         }
  297.         public void recycleView(int newPosition)
  298.         {
  299.             if (mExternalView != null)
  300.             {
  301.                 mInternalLayout.removeView(mExternalView);
  302.             }
  303.             if (mAdapter != null)
  304.             {
  305.                 if (newPosition >= getFirstPosition() && newPosition <= getLastPosition())
  306.                 {
  307.                     mExternalView = mAdapter.getView(newPosition, mExternalView, mInternalLayout);
  308.                 }
  309.                 else
  310.                 {
  311.                     mExternalView = mInvalidLayout;
  312.                 }
  313.             }
  314.             if (mExternalView != null)
  315.             {
  316.                 mInternalLayout.addView(mExternalView, new LinearLayout.LayoutParams(
  317.                     LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
  318.             }
  319.         }
  320.         public void setOffset(int xOffset, int yOffset, int relativeViewNumber)
  321.         {
  322.             // Scroll the target view relative to its own position relative to currently displayed view
  323.             mInternalLayout.scrollTo(getViewOffset(mViewNumber, relativeViewNumber) + xOffset, yOffset);
  324.         }
  325.         public int getCurrentOffset()
  326.         {
  327.             // Return the current scroll position
  328.             return mInternalLayout.getScrollX();
  329.         }
  330.         public void requestFocus()
  331.         {
  332.             mInternalLayout.requestFocus();
  333.         }
  334.     }
  335.     private class FlingGalleryAnimation extends Animation
  336.     {
  337.         private boolean mIsAnimationInProgres;
  338.         private int mRelativeViewNumber;
  339.         private int mInitialOffset;
  340.         private int mTargetOffset;
  341.         private int mTargetDistance;
  342.         public FlingGalleryAnimation()
  343.         {
  344.             mIsAnimationInProgres = false;
  345.             mRelativeViewNumber = 0;
  346.             mInitialOffset = 0;
  347.             mTargetOffset = 0;
  348.             mTargetDistance = 0;
  349.         }
  350.         public void prepareAnimation(int relativeViewNumber)
  351.         {
  352.             // If we are animating relative to a new view
  353.             if (mRelativeViewNumber != relativeViewNumber)
  354.             {
  355.                 if (mIsAnimationInProgres == true)
  356.                 {
  357.                     // We only have three views so if requested again to animate in same direction we must snap
  358.                     int newDirection = (relativeViewNumber == getPrevViewNumber(mRelativeViewNumber)) ? 1 : -1;
  359.                     int animDirection = (mTargetDistance < 0) ? 1 : -1;
  360.                     // If animation in same direction
  361.                     if (animDirection == newDirection)
  362.                     {
  363.                         // Ran out of time to animate so snap to the target offset
  364.                         mViews[0].setOffset(mTargetOffset, 0, mRelativeViewNumber);
  365.                         mViews[1].setOffset(mTargetOffset, 0, mRelativeViewNumber);
  366.                         mViews[2].setOffset(mTargetOffset, 0, mRelativeViewNumber);
  367.                     }
  368.                 }
  369.                 // Set relative view number for animation
  370.                 mRelativeViewNumber = relativeViewNumber;
  371.             }
  372.             // Note: In this implementation the targetOffset will always be zero
  373.             // as we are centering the view; but we include the calculations of
  374.             // targetOffset and targetDistance for use in future implementations
  375.             mInitialOffset = mViews[mRelativeViewNumber].getCurrentOffset();
  376.             mTargetOffset = getViewOffset(mRelativeViewNumber, mRelativeViewNumber);
  377.             mTargetDistance = mTargetOffset - mInitialOffset;
  378.             // Configure base animation properties
  379.             this.setDuration(mAnimationDuration);
  380.             this.setInterpolator(mDecelerateInterpolater);
  381.             // Start/continued animation
  382.             mIsAnimationInProgres = true;
  383.         }
  384.         @Override
  385.         protected void applyTransformation(float interpolatedTime, Transformation transformation)
  386.         {
  387.             // Ensure interpolatedTime does not over-shoot then calculate new offset
  388.             interpolatedTime = (interpolatedTime > 1.0f) ? 1.0f : interpolatedTime;
  389.             int offset = mInitialOffset + (int) (mTargetDistance * interpolatedTime);
  390.             for (int viewNumber = 0; viewNumber < 3; viewNumber++)
  391.             {
  392.                 // Only need to animate the visible views as the other view will always be off-screen
  393.                 if ((mTargetDistance > 0 && viewNumber != getNextViewNumber(mRelativeViewNumber)) ||
  394.                     (mTargetDistance < 0 && viewNumber != getPrevViewNumber(mRelativeViewNumber)))
  395.                 {
  396.                     mViews[viewNumber].setOffset(offset, 0, mRelativeViewNumber);
  397.                 }
  398.             }
  399.         }
  400.         @Override
  401.         public boolean getTransformation(long currentTime, Transformation outTransformation)
  402.         {
  403.             if (super.getTransformation(currentTime, outTransformation) == false)
  404.             {
  405.                 // Perform final adjustment to offsets to cleanup animation
  406.                 mViews[0].setOffset(mTargetOffset, 0, mRelativeViewNumber);
  407.                 mViews[1].setOffset(mTargetOffset, 0, mRelativeViewNumber);
  408.                 mViews[2].setOffset(mTargetOffset, 0, mRelativeViewNumber);
  409.                 // Reached the animation target
  410.                 mIsAnimationInProgres = false;
  411.                 return false;
  412.             }
  413.             // Cancel if the screen touched
  414.             if (mIsTouched || mIsDragging)
  415.             {
  416.                 // Note that at this point we still consider ourselves to be animating
  417.                 // because we have not yet reached the target offset; its just that the
  418.                 // user has temporarily interrupted the animation with a touch gesture
  419.                 return false;
  420.             }
  421.             return true;
  422.         }
  423.     }
  424.     private class FlingGestureDetector extends GestureDetector.SimpleOnGestureListener
  425.     {
  426.         @Override
  427.         public boolean onDown(MotionEvent e)
  428.         {
  429.             // Stop animation
  430.             mIsTouched = true;
  431.             // Reset fling state
  432.             mFlingDirection = 0;
  433.             return true;
  434.         }
  435.         @Override
  436.         public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
  437.         {
  438.             if (e2.getAction() == MotionEvent.ACTION_MOVE)
  439.             {
  440.                 if (mIsDragging == false)
  441.                 {
  442.                     // Stop animation
  443.                     mIsTouched = true;
  444.                     // Reconfigure scroll
  445.                     mIsDragging = true;
  446.                     mFlingDirection = 0;
  447.                     mScrollTimestamp = System.currentTimeMillis();
  448.                     mCurrentOffset = mViews[mCurrentViewNumber].getCurrentOffset();
  449.                 }
  450.                 float maxVelocity = mGalleryWidth / (mAnimationDuration / 1000.0f);
  451.                 long timestampDelta = System.currentTimeMillis() - mScrollTimestamp;
  452.                 float maxScrollDelta = maxVelocity * (timestampDelta / 1000.0f);
  453.                 float currentScrollDelta = e1.getX() - e2.getX();
  454.                 if (currentScrollDelta < maxScrollDelta * -1) currentScrollDelta = maxScrollDelta * -1;
  455.                 if (currentScrollDelta > maxScrollDelta) currentScrollDelta = maxScrollDelta;
  456.                 int scrollOffset = Math.round(mCurrentOffset + currentScrollDelta);
  457.                 // We can't scroll more than the width of our own frame layout
  458.                 if (scrollOffset >= mGalleryWidth) scrollOffset = mGalleryWidth;
  459.                 if (scrollOffset <= mGalleryWidth * -1) scrollOffset = mGalleryWidth * -1;
  460.                 mViews[0].setOffset(scrollOffset, 0, mCurrentViewNumber);
  461.                 mViews[1].setOffset(scrollOffset, 0, mCurrentViewNumber);
  462.                 mViews[2].setOffset(scrollOffset, 0, mCurrentViewNumber);
  463.             }
  464.             return false;
  465.         }
  466.         @Override
  467.         public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
  468.         {
  469.             if (Math.abs(e1.getY() - e2.getY()) <= swipe_max_off_path)
  470.             {
  471.                 if (e2.getX() - e1.getX() > swipe_min_distance && Math.abs(velocityX) > swipe_threshold_veloicty)
  472.                 {
  473.                     movePrevious();
  474.                 }
  475.                 if(e1.getX() - e2.getX() > swipe_min_distance && Math.abs(velocityX) > swipe_threshold_veloicty)
  476.                 {
  477.                     moveNext();
  478.                 }
  479.             }
  480.             return false;
  481.         }
  482.         @Override
  483.         public void onLongPress(MotionEvent e)
  484.         {
  485.             // Finalise scrolling
  486.             mFlingDirection = 0;
  487.             processGesture();
  488.         }
  489.         @Override
  490.         public void onShowPress(MotionEvent e)
  491.         {
  492.         }
  493.         @Override
  494.         public boolean onSingleTapUp(MotionEvent e)
  495.         {
  496.             // Reset fling state
  497.             mFlingDirection = 0;
  498.             return false;
  499.         }
  500.     }
  501. }

本文固定链接: http://www.devba.com/index.php/archives/1365.html | 开发吧

报歉!评论已关闭.