升级版draggedLayout *固定其中一个按钮*

Posted 疼老婆的coder

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了升级版draggedLayout *固定其中一个按钮*相关的知识,希望对你有一定的参考价值。

系统桌面的图标是可以拖拽,大家用起来好像也很习惯。不知道从什么时候开始,应用中的gridview也常常被人拿来做类似的效果。像支付宝,uc,还有一些新闻类的app都有拖拽控件的效果。对于item数量比较多的情况使用拖拽控件是一个比较不错的选择。
然后客户就开始想象自己有很多很多的类似小功能,然后就出现了这篇blog。
虽然只有十个不到的功能按钮,然而我们要有雄伟的蓝图,以后我们会有好多好多的功能的。用户使用的时候就会觉得不方便的。我们需要把按钮的排序权利交给用户。然后我们还要展开收缩的功能。为了界面的整洁美观,一行就放5个按钮,第一行的第五个按钮就是更多按钮,这是用来展开收拢的。按钮全部来自网络,我们需要随时更新的。
其实拖拽还是简单的,展开收拢也没什么难度。然而为什么要让第五个按钮成为更多呢?!?!?!?!?瞬间日子就很难过了。

有一个失败的例子就是继承自gridview的拖拽控件,动画效果十分生硬,还有各种闪烁的情况。想想网上的大神们应该没有写过这一类的帅气的空间吧。

感谢 http://blog.csdn.net/sk719887916/article/details/40074663 博主 为我提供了这个帅帅拖拽基础控件。

package com.kting.baijinka.util;

/*


import java.util.ArrayList;

import android.content.Context;
import android.database.DataSetObserver;
import android.graphics.Rect;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.VelocityTrackerCompat;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.ViewConfigurationCompat;
import android.util.AttributeSet;
import android.util.Log;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.animation.AlphaAnimation;
import android.view.animation.AnimationSet;
import android.view.animation.Interpolator;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.Adapter;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.Scroller;

import com.kting.baijinka.adapter.ICBCButtonAdapter;

/**
 * Zaker style grid view pager, support dragging & rearrange, using as zaker's main screen.
 */
public class DraggableGridViewPager extends ViewGroup 
    private static final String TAG = "DraggableGridViewPager";
    private static final boolean DEBUG = true;
    private static final boolean USE_CACHE = false;

    private static void DEBUG_LOG(String msg) 
        if (DEBUG) 
            Log.v(TAG, msg);
        
    

    // layout
    private static final int DEFAULT_COL_COUNT = 5;
    private static final int DEFAULT_ROW_COUNT = 12;
    private static final int DEFAULT_GRID_GAP = 2; // gap between grids (dips)

    private static final int MAX_SETTLE_DURATION = 600; // ms
    private static final int MIN_DISTANCE_FOR_FLING = 25; // dips
    private static final int MIN_FLING_VELOCITY = 600; // dips
    private static final int CLOSE_ENOUGH = 5; // dp

    private static final Interpolator sInterpolator = new Interpolator() 
        public float getInterpolation(float t) 
            t -= 1.0f;
            return t * t * t * t * t + 1.0f;
        
    ;

    private static final int INVALID_POINTER = -1;

    public static final int SCROLL_STATE_IDLE = 0;
    public static final int SCROLL_STATE_DRAGGING = 1;
    public static final int SCROLL_STATE_SETTLING = 2;

    private static final long LONG_CLICK_DURATION = 500; // ms
    private static final long ANIMATION_DURATION = 150; // ms

    private static final int EDGE_LFET = 0;
    private static final int EDGE_RIGHT = 1;

    private static final long EDGE_HOLD_DURATION = 1200; // ms

    private int mColCount = DEFAULT_COL_COUNT;
    private int mRowCount = DEFAULT_ROW_COUNT;
    private int mPageSize = mColCount * mRowCount;
    private int mGridGap;

    private int mPageCount;
    private int mGridWidth;
    private int mGridHeight;
    private int mMaxOverScrollSize;
    private int mEdgeSize;

    // internal paddings
    private int mPaddingLeft;
    private int mPaddingTop;
    private int mPaddingRight;
    private int mPaddingButtom;

    private int mCurItem; // Index of currently displayed page.
    private Adapter mAdapter;
    private final DataSetObserver mDataSetObserver = new DataSetObserver() 
        @Override
        public void onChanged() 
            dataSetChanged();
        

        @Override
        public void onInvalidated() 
            dataSetChanged();
        
    ;

    private Scroller mScroller;

    private boolean mScrollingCacheEnabled;

    private boolean mIsBeingDragged;
    private boolean mIsUnableToDrag;
    private int mTouchSlop;

    private float mLastMotionX;
    private float mLastMotionY;
    private float mInitialMotionX;
    private float mInitialMotionY;
    private int mActivePointerId = INVALID_POINTER;

    private VelocityTracker mVelocityTracker;
    private int mMinimumVelocity;
    private int mMaximumVelocity;
    private int mFlingDistance;
    private int mCloseEnough;

    // click & long click
    private int mLastPosition = -1;
    private long mLastDownTime = Long.MAX_VALUE;

    // rearrange
    private int mLastDragged = -1;
    private int mLastTarget = -1;

    // edge holding
    private int mLastEdge = -1;
    private long mLastEdgeTime = Long.MAX_VALUE;

    private ArrayList<Integer> newPositions = new ArrayList<Integer>();

    private boolean mCalledSuper;

    private OnPageChangeListener mOnPageChangeListener;
    private OnItemClickListener mOnItemClickListener;
    private OnItemLongClickListener mOnItemLongClickListener;
    private OnRearrangeListener mOnRearrangeListener;

    private final Runnable mEndScrollRunnable = new Runnable() 
        public void run() 
            setScrollState(SCROLL_STATE_IDLE);
        
    ;

    private int mScrollState = SCROLL_STATE_IDLE;

    /**
     * Callback interface for responding to changing state of the selected page.
     */
    public interface OnPageChangeListener 

        /**
         * This method will be invoked when the current page is scrolled, either as part of a programmatically initiated
         * smooth scroll or a user initiated touch scroll.
         * 
         * @param position
         *            Position index of the first page currently being displayed. Page position+1 will be visible if
         *            positionOffset is nonzero.
         * @param positionOffset
         *            Value from [0, 1) indicating the offset from the page at position.
         * @param positionOffsetPixels
         *            Value in pixels indicating the offset from position.
         */
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);

        /**
         * This method will be invoked when a new page becomes selected. Animation is not necessarily complete.
         * 
         * @param position
         *            Position index of the new selected page.
         */
        public void onPageSelected(int position);

        /**
         * Called when the scroll state changes. Useful for discovering when the user begins dragging, when the pager is
         * automatically settling to the current page, or when it is fully stopped/idle.
         * 
         * @param state
         *            The new scroll state.
         * @see DraggableGridViewPager#SCROLL_STATE_IDLE
         * @see DraggableGridViewPager#SCROLL_STATE_DRAGGING
         * @see DraggableGridViewPager#SCROLL_STATE_SETTLING
         */
        public void onPageScrollStateChanged(int state);
    

    /**
     * Simple implementation of the @link OnPageChangeListener interface with stub implementations of each method.
     * Extend this if you do not intend to override every method of @link OnPageChangeListener.
     */
    public static class SimpleOnPageChangeListener implements OnPageChangeListener 
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) 
            // This space for rent
        

        @Override
        public void onPageSelected(int position) 
            // This space for rent
        

        @Override
        public void onPageScrollStateChanged(int state) 
            // This space for rent
        
    

    public interface OnRearrangeListener 
        public abstract void onRearrange(int oldIndex, int newIndex);
    

    public DraggableGridViewPager(Context context) 
        super(context);
        initDraggableGridViewPager();
    

    public DraggableGridViewPager(Context context, AttributeSet attrs) 
        super(context, attrs);
        initDraggableGridViewPager();
    

    public DraggableGridViewPager(Context context, AttributeSet attrs, int defStyle) 
        super(context, attrs, defStyle);
        initDraggableGridViewPager();
    

    private void initDraggableGridViewPager() 
        setWillNotDraw(false);
        setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
        setFocusable(true);
        setChildrenDrawingOrderEnabled(true);

        final Context context = getContext();
        final ViewConfiguration configuration = ViewConfiguration.get(context);
        final float density = context.getResources().getDisplayMetrics().density;

        mGridGap = (int) (DEFAULT_GRID_GAP * density);

        // internal paddings
        mPaddingLeft = getPaddingLeft();
        mPaddingTop = getPaddingTop();
        mPaddingRight = getPaddingRight();
        mPaddingButtom = getPaddingBottom();
        super.setPadding(0, 0, 0, 0);

        mScroller = new Scroller(context, sInterpolator);
        mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration);
        mMinimumVelocity = (int) (MIN_FLING_VELOCITY * density);
        mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
        mFlingDistance = (int) (MIN_DISTANCE_FOR_FLING * density);
        mCloseEnough = (int) (CLOSE_ENOUGH * density);
    

    @Override
    protected void onDetachedFromWindow() 
        removeCallbacks(mEndScrollRunnable);
        if (mAdapter != null) 
            mAdapter.unregisterDataSetObserver(mDataSetObserver);
        
        super.onDetachedFromWindow();
    

    public int getColCount() 
        return mColCount;
    

    public void setColCount(int colCount) 
        if (colCount < 1) 
            colCount = 1;
        
        mColCount = colCount;
        mPageSize = mColCount * mRowCount;
        requestLayout();
    

    public int getRowCount() 
        return mRowCount;
    

    public void setRowCount(int rowCount) 
        if (rowCount < 1) 
            rowCount = 1;
        
        mRowCount = rowCount;
        mPageSize = mColCount * mRowCount;
        requestLayout();
    

    public int getGridGap() 
        return mGridGap;
    

    public void setGridGap(int gridGap) 
        if (gridGap < 0) 
            gridGap = 0;
        
        mGridGap = gridGap;
        requestLayout();
    

    public int getPageCount() 
        return (getChildCount() + mPageSize - 1) / mPageSize;
    

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) 
        final int childCount = getChildCount();
        mPageCount = (childCount + mPageSize - 1) / mPageSize;
        //Log.e("stuart","width="+String.valueOf(getWidth()));
        mGridWidth = (getWidth() - mPaddingLeft - mPaddingRight - (mColCount - 1) * mGridGap) / mColCount;
        //mGridHeight = (getHeight() - mPaddingTop - mPaddingButtom - (mRowCount - 1) * mGridGap) / mRowCount;
        mGridWidth = mGridHeight = mGridWidth;
        mMaxOverScrollSize = mGridWidth / 2;
        mEdgeSize = mGridWidth / 2;
        newPositions.clear();
        for (int i = 0; i < childCount; i++) 
            final View child = getChildAt(i);
            final Rect rect = getRectByPosition(i);
            child.measure(MeasureSpec.makeMeasureSpec(rect.width(), MeasureSpec.EXACTLY),
                    MeasureSpec.makeMeasureSpec(rect.height(), MeasureSpec.EXACTLY));
            DEBUG_LOG("child.layout position=" + i + ", rect=" + rect);
            child.layout(rect.left, rect.top, rect.right, rect.bottom);
            newPositions.add(-1);
        
        if (mCurItem > 0 && mCurItem < mPageCount) 
            final int curItem = mCurItem;
            mCurItem = 0;
            setCurrentItem(curItem);
        
    

    private void setScrollState(int newState) 
        if (mScrollState == newState) 
            return;
        
        mScrollState = newState;
        if (mOnPageChangeListener != null) 
            mOnPageChangeListener.onPageScrollStateChanged(newState);
        
    

    public int getCurrentItem() 
        return mCurItem;
    

    public void setCurrentItem(int item) 
        setCurrentItemInternal(item, false, false);
    

    public void setCurrentItem(int item, boolean smoothScroll) 
        setCurrentItemInternal(item, smoothScroll, false);
    

    void setCurrentItemInternal(int item, boolean smoothScroll, boolean always) 
        setCurrentItemInternal(item, smoothScroll, always, 0);
    

    void setCurrentItemInternal(int item, boolean smoothScroll, boolean always, int velocity) 
        if (mPageCount <= 0) 
            setScrollingCacheEnabled(false);
            return;
        
        if (!always && mCurItem == item) 
            setScrollingCacheEnabled(false);
            return;
        

        if (item < 0) 
            item = 0;
         else if (item >= mPageCount) 
            item = mPageCount - 1;
        
        final boolean dispatchSelected = mCurItem != item;
        mCurItem = item;
        scrollToItem(item, smoothScroll, velocity, dispatchSelected);
    

    private void scrollToItem(int item, boolean smoothScroll, int velocity, boolean dispatchSelected) 
        final int destX = getWidth() * item;
        if (smoothScroll) 
            smoothScrollTo(destX, 0, velocity);
            if (dispatchSelected && mOnPageChangeListener != null) 
                mOnPageChangeListener.onPageSelected(item);
            
         else 
            if (dispatchSelected && mOnPageChangeListener != null) 
                mOnPageChangeListener.onPageSelected(item);
            
            completeScroll(false);
            scrollTo(destX, 0);
            pageScrolled(destX);
        
    

    public void setOnPageChangeListener(OnPageChangeListener listener) 
        mOnPageChangeListener = listener;
    

    public void setOnItemClickListener(OnItemClickListener listener) 
        mOnItemClickListener = listener;
    

    public void setOnItemLongClickListener(OnItemLongClickListener listener) 
        mOnItemLongClickListener = listener;
    

    public void setOnRearrangeListener(OnRearrangeListener listener) 
        mOnRearrangeListener = listener;
    

    float distanceInfluenceForSnapDuration(float f) 
        f -= 0.5f; // center the values about 0.
        f *= 0.3f * Math.PI / 2.0f;
        return (float) Math.sin(f);
    

    void smoothScrollTo(int x, int y) 
        smoothScrollTo(x, y, 0);
    

    void smoothScrollTo(int x, int y, int velocity) 
        if (getChildCount() == 0) 
            // Nothing to do.
            setScrollingCacheEnabled(false);
            return;
        
        int sx = getScrollX();
        int sy = getScrollY();
        int dx = x - sx;
        int dy = y - sy;
        if (dx == 0 && dy == 0) 
            completeScroll(false);
            setScrollState(SCROLL_STATE_IDLE);
            return;
        

        setScrollingCacheEnabled(true);
        setScrollState(SCROLL_STATE_SETTLING);

        final int width = getWidth();
        final int halfWidth = width / 2;
        final float distanceRatio = Math.min(1f, 1.0f * Math.abs(dx) / width);
        final float distance = halfWidth + halfWidth *
                distanceInfluenceForSnapDuration(distanceRatio);

        int duration = 0;
        velocity = Math.abs(velocity);
        if (velocity > 0) 
            duration = 4 * Math.round(1000 * Math.abs(distance / velocity));
         else 
            final float pageDelta = (float) Math.abs(dx) / width;
            duration = (int) ((pageDelta + 1) * 100);
        
        duration = Math.min(duration, MAX_SETTLE_DURATION);

        mScroller.startScroll(sx, sy, dx, dy, duration);
        ViewCompat.postInvalidateOnAnimation(this);
    

    @Override
    public void computeScroll() 
        if (!mScroller.isFinished() && mScroller.computeScrollOffset()) 
            int oldX = getScrollX();
            int oldY = getScrollY();
            int x = mScroller.getCurrX();
            int y = mScroller.getCurrY();

            if (oldX != x || oldY != y) 
                scrollTo(x, y);
                if (!pageScrolled(x)) 
                    mScroller.abortAnimation();
                    scrollTo(0, y);
                
            

            // Keep on drawing until the animation has finished.
            ViewCompat.postInvalidateOnAnimation(this);
            return;
        

        // Done with scroll, clean up state.
        completeScroll(true);
    

    private boolean pageScrolled(int xpos) 
        if (mPageCount <= 0) 
            mCalledSuper = false;
            onPageScrolled(0, 0, 0);
            if (!mCalledSuper) 
                throw new IllegalStateException("onPageScrolled did not call superclass implementation");
            
            return false;
        
        final int width = getWidth();
        final int currentPage = xpos / width;
        final int offsetPixels = xpos - currentPage * width;
        final float pageOffset = (float) offsetPixels / (float) width;

        mCalledSuper = false;
        onPageScrolled(currentPage, pageOffset, offsetPixels);
        if (!mCalledSuper) 
            throw new IllegalStateException("onPageScrolled did not call superclass implementation");
        
        return true;
    

    /**
     * This method will be invoked when the current page is scrolled, either as part of a programmatically initiated
     * smooth scroll or a user initiated touch scroll. If you override this method you must call through to the
     * superclass implementation (e.g. super.onPageScrolled(position, offset, offsetPixels)) before onPageScrolled
     * returns.
     * 
     * @param position
     *            Position index of the first page currently being displayed. Page position+1 will be visible if
     *            positionOffset is nonzero.
     * @param offset
     *            Value from [0, 1) indicating the offset from the page at position.
     * @param offsetPixels
     *            Value in pixels indicating the offset from position.
     */
    protected void onPageScrolled(int position, float offset, int offsetPixels) 
        if (mOnPageChangeListener != null) 
            mOnPageChangeListener.onPageScrolled(position, offset, offsetPixels);
        
        mCalledSuper = true;
    

    private void completeScroll(boolean postEvents) 
        if (mScrollState == SCROLL_STATE_SETTLING) 
            // Done with scroll, no longer want to cache view drawing.
            setScrollingCacheEnabled(false);
            mScroller.abortAnimation();
            int oldX = getScrollX();
            int oldY = getScrollY();
            int x = mScroller.getCurrX();
            int y = mScroller.getCurrY();
            if (oldX != x || oldY != y) 
                scrollTo(x, y);
            
            if (postEvents) 
                ViewCompat.postOnAnimation(this, mEndScrollRunnable);
             else 
                mEndScrollRunnable.run();
            
        
    

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) 
        /*
         * This method JUST determines whether we want to intercept the motion. If we return true, onMotionEvent will be
         * called and we do the actual scrolling there.
         */

        final int action = ev.getAction() & MotionEventCompat.ACTION_MASK;

        // Always take care of the touch gesture being complete.
        if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) 
            // Release the drag.
            DEBUG_LOG("Intercept done!");
            mIsBeingDragged = false;
            mIsUnableToDrag = false;
            mActivePointerId = INVALID_POINTER;
            if (mVelocityTracker != null) 
                mVelocityTracker.recycle();
                mVelocityTracker = null;
            
            return false;
        

        // Nothing more to do here if we have decided whether or not we
        // are dragging.
        if (action != MotionEvent.ACTION_DOWN) 
            if (mIsBeingDragged || mLastDragged >= 0) 
                DEBUG_LOG("Intercept returning true!");
                return true;
            
            if (mIsUnableToDrag) 
                DEBUG_LOG("Intercept returning false!");
                return false;
            
        

        switch (action) 
        case MotionEvent.ACTION_MOVE: 
            /*
             * mIsBeingDragged == false, otherwise the shortcut would have caught it. Check whether the user has moved
             * far enough from his original down touch.
             */

            /*
             * Locally do absolute value. mLastMotionY is set to the y value of the down event.
             */
            final int activePointerId = mActivePointerId;
            if (activePointerId == INVALID_POINTER) 
                // If we don't have a valid id, the touch down wasn't on content.
                break;
            

            final int pointerIndex = MotionEventCompat.findPointerIndex(ev, activePointerId);
            final float x = MotionEventCompat.getX(ev, pointerIndex);
            final float dx = x - mLastMotionX;
            final float xDiff = Math.abs(dx);
            final float y = MotionEventCompat.getY(ev, pointerIndex);
            final float yDiff = Math.abs(y - mInitialMotionY);
            DEBUG_LOG("***Moved to " + x + "," + y + " diff=" + xDiff + "," + yDiff);

            if (xDiff > mTouchSlop && xDiff * 0.5f > yDiff) 
                DEBUG_LOG("***Starting drag!");
                mIsBeingDragged = true;
                requestParentDisallowInterceptTouchEvent(true);
                setScrollState(SCROLL_STATE_DRAGGING);
                mLastMotionX = dx > 0 ? mInitialMotionX + mTouchSlop :
                        mInitialMotionX - mTouchSlop;
                mLastMotionY = y;
                setScrollingCacheEnabled(true);
             else if (yDiff > mTouchSlop) 
                // The finger has moved enough in the vertical
                // direction to be counted as a drag... abort
                // any attempt to drag horizontally, to work correctly
                // with children that have scrolling containers.
                DEBUG_LOG("***Unable to drag!");
                mIsUnableToDrag = true;
            
            if (mIsBeingDragged) 
                // Scroll to follow the motion event
                if (performDrag(x)) 
                    ViewCompat.postInvalidateOnAnimation(this);
                
            
            break;
        

        case MotionEvent.ACTION_DOWN: 
            /*
             * Remember location of down touch. ACTION_DOWN always refers to pointer index 0.
             */
            mLastMotionX = mInitialMotionX = ev.getX();
            mLastMotionY = mInitialMotionY = ev.getY();
            mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
            mIsUnableToDrag = false;

            mScroller.computeScrollOffset();
            if (mScrollState == SCROLL_STATE_SETTLING &&
                    Math.abs(mScroller.getFinalX() - mScroller.getCurrX()) > mCloseEnough) 
                // Let the user 'catch' the pager as it animates.
                mScroller.abortAnimation();
                mIsBeingDragged = true;
                requestParentDisallowInterceptTouchEvent(true);
                setScrollState(SCROLL_STATE_DRAGGING);
             else 
                completeScroll(false);
                mIsBeingDragged = false;
            

            DEBUG_LOG("***Down at " + mLastMotionX + "," + mLastMotionY
                    + " mIsBeingDragged=" + mIsBeingDragged
                    + " mIsUnableToDrag=" + mIsUnableToDrag);
            mLastDragged = -1;
            break;
        

        case MotionEventCompat.ACTION_POINTER_UP:
            onSecondaryPointerUp(ev);
            break;
        

        if (mVelocityTracker == null) 
            mVelocityTracker = VelocityTracker.obtain();
        
        mVelocityTracker.addMovement(ev);

        /*
         * The only time we want to intercept motion events is if we are in the drag mode.
         */
        return mIsBeingDragged;
    


    @Override
    public boolean onTouchEvent(MotionEvent ev) 
        if (ev.getAction() == MotionEvent.ACTION_DOWN && ev.getEdgeFlags() != 0) 
            // Don't handle edge touches immediately -- they may actually belong to one of our
            // descendants.
            return false;
        

        if (mPageCount <= 0) 
            // Nothing to present or scroll; nothing to touch.
            return false;
        

        if (mVelocityTracker == null) 
            mVelocityTracker = VelocityTracker.obtain();
        
        mVelocityTracker.addMovement(ev);

        final int action = ev.getAction();
        boolean needsInvalidate = false;

        switch (action & MotionEventCompat.ACTION_MASK) 
        case MotionEvent.ACTION_DOWN: 
            mScroller.abortAnimation();
            // Remember where the motion event started
            mLastMotionX = mInitialMotionX = ev.getX();
            mLastMotionY = mInitialMotionY = ev.getY();
            mActivePointerId = MotionEventCompat.getPointerId(ev, 0);

            DEBUG_LOG("Down at " + mLastMotionX + "," + mLastMotionY
                    + " mIsBeingDragged=" + mIsBeingDragged
                    + " mIsUnableToDrag=" + mIsUnableToDrag);

            if (!mIsBeingDragged && mScrollState == SCROLL_STATE_IDLE) 
                mLastPosition = getPositionByXY((int) mLastMotionX, (int) mLastMotionY);

             else 
                mLastPosition = -1;
            
            if (mLastPosition >= 0) 
                mLastDownTime = System.currentTimeMillis();
             else 
                mLastDownTime = Long.MAX_VALUE;
            
            DEBUG_LOG("Down at mLastPosition=" + mLastPosition);
            mLastDragged = -1;
            break;
        
        case MotionEvent.ACTION_MOVE: 
            final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
            final float x = MotionEventCompat.getX(ev, pointerIndex);
            final float y = MotionEventCompat.getY(ev, pointerIndex);

            if (mLastDragged >= 0) 
                // change draw location of dragged visual
                final View v = getChildAt(mLastDragged);
                final int l = getScrollX() + (int) x - v.getWidth() / 2;
                final int t = getScrollY() + (int) y - v.getHeight() / 2;
                v.layout(l, t, l + v.getWidth(), t + v.getHeight());

                // check for new target hover
                if (mScrollState == SCROLL_STATE_IDLE) 
                    final int target = getTargetByXY((int) x, (int) y);
                    if (target != -1 && mLastTarget != target) 
                        animateGap(target);
                        mLastTarget = target;
                        DEBUG_LOG("Moved to mLastTarget=" + mLastTarget);
                    
                    // edge holding
                    final int edge = getEdgeByXY((int) x, (int) y);
                    if (mLastEdge == -1) 
                        if (edge != mLastEdge) 
                            mLastEdge = edge;
                            mLastEdgeTime = System.currentTimeMillis();
                        
                     else 
                        if (edge != mLastEdge) 
                            mLastEdge = -1;
                         else 
                            if ((System.currentTimeMillis() - mLastEdgeTime) >= EDGE_HOLD_DURATION) 
                                performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
                                triggerSwipe(edge);
                                mLastEdge = -1;
                            
                        
                    
                
             else if (!mIsBeingDragged) 
                final float xDiff = Math.abs(x - mLastMotionX);
                final float yDiff = Math.abs(y - mLastMotionY);
                DEBUG_LOG("Moved to " + x + "," + y + " diff=" + xDiff + "," + yDiff);

                if (xDiff > mTouchSlop && xDiff > yDiff) 
                    DEBUG_LOG("Starting drag!");
                    mIsBeingDragged = true;
                    requestParentDisallowInterceptTouchEvent(true);
                    mLastMotionX = x - mInitialMotionX > 0 ? mInitialMotionX + mTouchSlop :
                            mInitialMotionX - mTouchSlop;
                    mLastMotionY = y;
                    setScrollState(SCROLL_STATE_DRAGGING);
                    setScrollingCacheEnabled(true);
                
            
            // Not else! Note that mIsBeingDragged can be set above.
            if (mIsBeingDragged) 
                // Scroll to follow the motion event
                needsInvalidate |= performDrag(x);
             else if (mLastPosition >= 0) 
                final int currentPosition = getPositionByXY((int) x, (int) y);
                DEBUG_LOG("Moved to currentPosition=" + currentPosition);
                if (currentPosition == mLastPosition) 
                    if ((System.currentTimeMillis() - mLastDownTime) >= LONG_CLICK_DURATION) 
                        if (onItemLongClick(currentPosition)) 
                            performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
                            mLastDragged = mLastPosition;
                            requestParentDisallowInterceptTouchEvent(true);
                            mLastTarget = -1;
                            animateDragged();
                            mLastPosition = -1;
                        
                        mLastDownTime = Long.MAX_VALUE;
                    
                 else 
                    mLastPosition = -1;
                
            
            break;
        
        case MotionEvent.ACTION_UP: 
            DEBUG_LOG("Touch up!!!");
            final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
            final float x = MotionEventCompat.getX(ev, pointerIndex);
            final float y = MotionEventCompat.getY(ev, pointerIndex);

            if (mLastDragged >= 0) 
                rearrange();
             else if (mIsBeingDragged) 
                final VelocityTracker velocityTracker = mVelocityTracker;
                velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
                int initialVelocity = (int) VelocityTrackerCompat.getXVelocity(velocityTracker, mActivePointerId);
                final int width = getWidth();
                final int scrollX = getScrollX();
                final int currentPage = scrollX / width;
                final int offsetPixels = scrollX - currentPage * width;
                final float pageOffset = (float) offsetPixels / (float) width;
                final int totalDelta = (int) (x - mInitialMotionX);
                int nextPage = determineTargetPage(currentPage, pageOffset, initialVelocity, totalDelta);
                setCurrentItemInternal(nextPage, true, true, initialVelocity);

                mActivePointerId = INVALID_POINTER;
                endDrag();
             else if (mLastPosition >= 0) 
                final int currentPosition = getPositionByXY((int) x, (int) y);
                DEBUG_LOG("Touch up!!! currentPosition=" + currentPosition);
                if (currentPosition == mLastPosition) 
                    onItemClick(currentPosition);
                
            
            break;
        
        case MotionEvent.ACTION_CANCEL:
            DEBUG_LOG("Touch cancel!!!");
            if (mLastDragged >= 0) 
                rearrange();
             else if (mIsBeingDragged) 
                scrollToItem(mCurItem, true, 0, false);
                mActivePointerId =

以上是关于升级版draggedLayout *固定其中一个按钮*的主要内容,如果未能解决你的问题,请参考以下文章

R:如何读取固定宽度的数据文件,其中数据连接成两组,堆叠在一个文件的顶部

如何在固定大小的表格单元格内按比例缩放图像

升级到 Django 1.8 后“提供的固定默认值”

pip 安装升级升级固定的包

java.util.Timer简介

JVM--类加载