升级版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 = ViewCo
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值