Drag implementation,

Source: Internet
Author: User

Drag implementation,

Drag <1> A single drag-and-drop component is created based on onTouchEvent, which can be called the drag-and-drop implementation of a single view.

Drag <2> mainly implements the drag-and-drop layout. You can drag the ViewGroup and drag all the ChildView in the parent container.

Xml layout file:

     
         
          
           
        
    
   
  
 
Custom Layout code:
Package com. hjk. shiny. androidcontrols; import android. animation. animator; import android. animation. animatorListenerAdapter; import android. animation. animatorSet; import android. animation. valueAnimator; import android. content. context; import android. graphics. rect; import android. support. v4.view. viewCompat; import android. support. v4.widget. viewDragHelper; import android. util. attributeSet; import android. util. L Og; import android. view. motionEvent; import android. view. view; import android. view. viewConfiguration; import android. widget. frameLayout;/*** Created by frank on. */public class DragViewGroup extends FrameLayout {private static final String TAG = "TestViewGroup"; // records the coordinates of the last touch of the finger, private float mLastPointX; private float mLastPointY; // The child coordinate before the record is dragged as the coordinate point of the rebound record private float mDragViewOri GX; private float mDragViewOrigY; // used to identify the smallest sliding distance. private int mSlop has been initialized in the construction; // used to identify the child being dragged, if it is null, no child is dragged to the private View mDragView; // The State is IDLE, and the two enum States {IDLE, DRAGGING} // The current event State, corresponding to the enum State mCurrentState; // layout construct public DragViewGroup (Context context) {this (context, null);} public DragViewGroup (Context context, AttributeSet attrs) {this (context, attrs, 0);} public DragViewGroup (Context context, AttributeSet attrs, int defStyleAttr) {super (context, attrs, defStyleAttr); mSlop = ViewConfiguration. getWindowTouchSlop ();} // event passing listener @ Override public boolean onInterceptTouchEvent (MotionEvent ev) {return true ;} // layout event monitoring/*** computing environment of view Coordinate System * event. getX (), event. getY () is used to obtain the distance between the trigger event point and the parent container x and y. * The ViewCompat class mainly provides the view compatibility. * Here, offsetLeftAndRight, offsetTopAndB Ottom shifts the target childview */@ Override public boolean onTouchEvent (MotionEvent event) {int action = event. getAction (); switch (action) {case MotionEvent. ACTION_DOWN: // only records the event location that triggers childview if (isPointOnViews (event) {// mark the status as drag and drop, and records the last touch coordinate mCurrentState = State. DRAGGING; mLastPointX = event. getX (); mLastPointY = event. getY ();} break; case MotionEvent. ACTION_MOVE: // calculates the moving difference int deltaX = (int) (event. g EtX ()-mLastPointX); int deltaY = (int) (event. getY ()-mLastPointY); if (mCurrentState = State. DRAGGING & mDragView! = Null & (Math. abs (deltaX)> mSlop | Math. abs (deltaY)> mSlop) {// if the conditions are met, move the position of the dragged child to ViewCompat. offsetLeftAndRight (mDragView, deltaX); ViewCompat. offsetTopAndBottom (mDragView, deltaY); // record the current vertex location mLastPointX = event. getX (); mLastPointY = event. getY ();} break; case MotionEvent. ACTION_CANCEL: case MotionEvent. ACTION_UP: if (mCurrentState = State. DRAGGING) {// flag the status as idle and set the mDragView variable to nul L // mCurrentState = State. IDLE; // mDragView = null; // you can specify the coordinates of the child's original position. * 2. When the finger is released, the attribute animation is used to change the value from the new position to the original position. When the finger is released, the child moves in the process of change to form a rebound animation effect. */If (mDragView! = Null) {// create a rebound animation to determine the animation start point and end point ValueAnimator animator = ValueAnimator. ofFloat (mDragView. getX (), mDragViewOrigX); // create an X animation to listen to animator. addUpdateListener (new ValueAnimator. animatorUpdateListener () {@ Override public void onAnimationUpdate (ValueAnimator animation) {mDragView. setX (float) animation. getAnimatedValue () ;}}); ValueAnimator animator1 = ValueAnimator. ofFloat (mDragView. getY (), mDragViewOrigY); // create Y Animation Listen to animator1.addUpdateListener (new ValueAnimator. animatorUpdateListener () {@ Override public void onAnimationUpdate (ValueAnimator animation) {mDragView. setY (float) animation. getAnimatedValue () ;}}); AnimatorSet animatorSet = new AnimatorSet (); animatorSet. play (animator ). before (animator1); // Add end animation to listen to animatorSet. addListener (new AnimatorListenerAdapter () {@ Override public void onAnimationEnd (Anima Tor animation) {super. onAnimationEnd (animation); mDragView = null ;}}); animatorSet. start () ;}else {mDragView = null;} mCurrentState = State. IDLE;} break;} return true;}/*** determines whether the touch is on the child *** // private boolean isPointOnViews (MotionEvent ev) {// boolean result = false; // create the childView matrix // Rect rect = new Rect (); // The parent layout of the event is all childView, determine whether the trigger point is on the subview // for (int I = 0; I <getChildCount (); I ++) {// View view = getChildAt (I); // * // relative to the parent layout, the distance from left, top, right, bottom distance // * // rect. set (int) view. getX (), (int) view. getY (), (int) view. getX () + (int) view. getWidth () //, (int) view. getY () + view. getHeight (); // determine the inclusion relationship // if (rect. contains (int) ev. getX (), (int) ev. getY () {// mark the dragged child // mDragView = view; // result = true; // break; /// // before mCurrentState determination, the mCurrentState has not been assigned a value of State. dragging // r Eturn result & mCurrentState! = State. DRAGGING; //}/* due to the FrameLayout feature, the top child is actually at the bottom of the ViewGroup index, so we can put the traversal order upside down, the drag-and-drop problem is solved in the order of view drag-and-drop, but the cascade problem cannot be solved, the post-rendered view can only be stacked above the previously rendered view. This is related to the order of the Pressure stack */private boolean isPointOnViews (MotionEvent event) {boolean result = false; rect rect = new Rect ();/* Note: in reverse order retrieval, the last child should start with the getChildCount-1, and the first child when I = 0, similar to String. length Processing */for (int I = getChildCount ()-1; I> = 0; I --) {View view = getChildAt (I); rect. set (int) view. getX (), (int) view. getY (), (int) view. getX () + (int) view. getWidth (), (int) view. getY () + (int) view. getHeight (); if (rect. contains (int) event. getX (), (int) event. getY () {mDragView = view; // Save the coordinates of the child position between the drag and drop operations to rebound the mDragViewOrigX = mDragView. getX (); mDragViewOrigY = mDragView. getY (); result = true; break;} return result & mCurrentState! = State. DRAGGING ;}}

The annotations are very detailed, so I will not elaborate on the steps.

The steps are as follows: Implement childView drag and drop, implement the orderly drag and drop of childView, and implement the Rebound mechanism of childView.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.