summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/build.gradle1
-rw-r--r--library/drag-sort-listview/.gitignore22
-rw-r--r--library/drag-sort-listview/build.gradle30
-rw-r--r--library/drag-sort-listview/proguard-project.txt20
-rw-r--r--library/drag-sort-listview/src/main/AndroidManifest.xml8
-rw-r--r--library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/DragSortController.java471
-rw-r--r--library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/DragSortCursorAdapter.java241
-rw-r--r--library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/DragSortItemView.java100
-rw-r--r--library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/DragSortItemViewCheckable.java55
-rw-r--r--library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/DragSortListView.java3073
-rw-r--r--library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/ResourceDragSortCursorAdapter.java133
-rw-r--r--library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/SimpleDragSortCursorAdapter.java422
-rw-r--r--library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/SimpleFloatViewManager.java89
-rw-r--r--library/drag-sort-listview/src/main/res/values/dslv_attrs.xml30
-rw-r--r--settings.gradle4
15 files changed, 2 insertions, 4697 deletions
diff --git a/app/build.gradle b/app/build.gradle
index 2cfee552e..ec0bd0167 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -33,7 +33,6 @@ dependencies {
compile "com.github.AntennaPod:AntennaPod-AudioPlayer:v1.0.2"
compile project(":core")
- compile project(":library:drag-sort-listview")
}
def getMyVersionName() {
diff --git a/library/drag-sort-listview/.gitignore b/library/drag-sort-listview/.gitignore
deleted file mode 100644
index a45024b5c..000000000
--- a/library/drag-sort-listview/.gitignore
+++ /dev/null
@@ -1,22 +0,0 @@
-# built application files
-*.apk
-*.ap_
-
-# files for the dex VM
-*.dex
-
-# Java class files
-*.class
-
-# generated files
-bin/
-gen/
-target/
-
-# Local configuration file (sdk path, etc)
-local.properties
-.gitattributes
-
-# Eclipse project files
-.classpath
-.project
diff --git a/library/drag-sort-listview/build.gradle b/library/drag-sort-listview/build.gradle
deleted file mode 100644
index 2ba1aa12a..000000000
--- a/library/drag-sort-listview/build.gradle
+++ /dev/null
@@ -1,30 +0,0 @@
-apply plugin: "com.android.library"
-
-android {
- compileSdkVersion rootProject.ext.compileSdkVersion
- buildToolsVersion rootProject.ext.buildToolsVersion
-
- defaultConfig {
- minSdkVersion rootProject.ext.minSdkVersion
- targetSdkVersion rootProject.ext.targetSdkVersion
- versionCode 4
- versionName "0.6.1"
- }
- buildTypes {
- release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
- }
- }
-
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_7
- targetCompatibility JavaVersion.VERSION_1_7
- }
-
-}
-
-dependencies {
- compile fileTree(dir: "libs", include: ["*.jar"])
- compile "com.android.support:support-v4:$supportVersion"
-}
diff --git a/library/drag-sort-listview/proguard-project.txt b/library/drag-sort-listview/proguard-project.txt
deleted file mode 100644
index f2fe1559a..000000000
--- a/library/drag-sort-listview/proguard-project.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-# To enable ProGuard in your project, edit project.properties
-# to define the proguard.config property as described in that file.
-#
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in ${sdk.dir}/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the ProGuard
-# include property in project.properties.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
diff --git a/library/drag-sort-listview/src/main/AndroidManifest.xml b/library/drag-sort-listview/src/main/AndroidManifest.xml
deleted file mode 100644
index f0ef29f3e..000000000
--- a/library/drag-sort-listview/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.mobeta.android.dslv"
- android:versionCode="4"
- android:versionName="0.6.1">
- <uses-sdk android:targetSdkVersion="7"
- android:minSdkVersion="7" />
-</manifest>
diff --git a/library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/DragSortController.java b/library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/DragSortController.java
deleted file mode 100644
index fef853d22..000000000
--- a/library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/DragSortController.java
+++ /dev/null
@@ -1,471 +0,0 @@
-package com.mobeta.android.dslv;
-
-import android.graphics.Point;
-import android.view.GestureDetector;
-import android.view.HapticFeedbackConstants;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.widget.AdapterView;
-
-/**
- * Class that starts and stops item drags on a {@link DragSortListView}
- * based on touch gestures. This class also inherits from
- * {@link SimpleFloatViewManager}, which provides basic float View
- * creation.
- *
- * An instance of this class is meant to be passed to the methods
- * {@link DragSortListView#setTouchListener()} and
- * {@link DragSortListView#setFloatViewManager()} of your
- * {@link DragSortListView} instance.
- */
-public class DragSortController extends SimpleFloatViewManager implements View.OnTouchListener, GestureDetector.OnGestureListener {
-
- /**
- * Drag init mode enum.
- */
- public static final int ON_DOWN = 0;
- public static final int ON_DRAG = 1;
- public static final int ON_LONG_PRESS = 2;
-
- private int mDragInitMode = ON_DOWN;
-
- private boolean mSortEnabled = true;
-
- /**
- * Remove mode enum.
- */
- public static final int CLICK_REMOVE = 0;
- public static final int FLING_REMOVE = 1;
-
- /**
- * The current remove mode.
- */
- private int mRemoveMode;
-
- private boolean mRemoveEnabled = false;
- private boolean mIsRemoving = false;
-
- private GestureDetector mDetector;
-
- private GestureDetector mFlingRemoveDetector;
-
- private int mTouchSlop;
-
- public static final int MISS = -1;
-
- private int mHitPos = MISS;
- private int mFlingHitPos = MISS;
-
- private int mClickRemoveHitPos = MISS;
-
- private int[] mTempLoc = new int[2];
-
- private int mItemX;
- private int mItemY;
-
- private int mCurrX;
- private int mCurrY;
-
- private boolean mDragging = false;
-
- private float mFlingSpeed = 500f;
-
- private int mDragHandleId;
-
- private int mClickRemoveId;
-
- private int mFlingHandleId;
- private boolean mCanDrag;
-
- private DragSortListView mDslv;
- private int mPositionX;
-
- /**
- * Calls {@link #DragSortController(DragSortListView, int)} with a
- * 0 drag handle id, FLING_RIGHT_REMOVE remove mode,
- * and ON_DOWN drag init. By default, sorting is enabled, and
- * removal is disabled.
- *
- * @param dslv The DSLV instance
- */
- public DragSortController(DragSortListView dslv) {
- this(dslv, 0, ON_DOWN, FLING_REMOVE);
- }
-
- public DragSortController(DragSortListView dslv, int dragHandleId, int dragInitMode, int removeMode) {
- this(dslv, dragHandleId, dragInitMode, removeMode, 0);
- }
-
- public DragSortController(DragSortListView dslv, int dragHandleId, int dragInitMode, int removeMode, int clickRemoveId) {
- this(dslv, dragHandleId, dragInitMode, removeMode, clickRemoveId, 0);
- }
-
- /**
- * By default, sorting is enabled, and removal is disabled.
- *
- * @param dslv The DSLV instance
- * @param dragHandleId The resource id of the View that represents
- * the drag handle in a list item.
- */
- public DragSortController(DragSortListView dslv, int dragHandleId, int dragInitMode,
- int removeMode, int clickRemoveId, int flingHandleId) {
- super(dslv);
- mDslv = dslv;
- mDetector = new GestureDetector(dslv.getContext(), this);
- mFlingRemoveDetector = new GestureDetector(dslv.getContext(), mFlingRemoveListener);
- mFlingRemoveDetector.setIsLongpressEnabled(false);
- mTouchSlop = ViewConfiguration.get(dslv.getContext()).getScaledTouchSlop();
- mDragHandleId = dragHandleId;
- mClickRemoveId = clickRemoveId;
- mFlingHandleId = flingHandleId;
- setRemoveMode(removeMode);
- setDragInitMode(dragInitMode);
- }
-
-
- public int getDragInitMode() {
- return mDragInitMode;
- }
-
- /**
- * Set how a drag is initiated. Needs to be one of
- * {@link ON_DOWN}, {@link ON_DRAG}, or {@link ON_LONG_PRESS}.
- *
- * @param mode The drag init mode.
- */
- public void setDragInitMode(int mode) {
- mDragInitMode = mode;
- }
-
- /**
- * Enable/Disable list item sorting. Disabling is useful if only item
- * removal is desired. Prevents drags in the vertical direction.
- *
- * @param enabled Set <code>true</code> to enable list
- * item sorting.
- */
- public void setSortEnabled(boolean enabled) {
- mSortEnabled = enabled;
- }
-
- public boolean isSortEnabled() {
- return mSortEnabled;
- }
-
- /**
- * One of {@link CLICK_REMOVE}, {@link FLING_RIGHT_REMOVE},
- * {@link FLING_LEFT_REMOVE},
- * {@link SLIDE_RIGHT_REMOVE}, or {@link SLIDE_LEFT_REMOVE}.
- */
- public void setRemoveMode(int mode) {
- mRemoveMode = mode;
- }
-
- public int getRemoveMode() {
- return mRemoveMode;
- }
-
- /**
- * Enable/Disable item removal without affecting remove mode.
- */
- public void setRemoveEnabled(boolean enabled) {
- mRemoveEnabled = enabled;
- }
-
- public boolean isRemoveEnabled() {
- return mRemoveEnabled;
- }
-
- /**
- * Set the resource id for the View that represents the drag
- * handle in a list item.
- *
- * @param id An android resource id.
- */
- public void setDragHandleId(int id) {
- mDragHandleId = id;
- }
-
- /**
- * Set the resource id for the View that represents the fling
- * handle in a list item.
- *
- * @param id An android resource id.
- */
- public void setFlingHandleId(int id) {
- mFlingHandleId = id;
- }
-
- /**
- * Set the resource id for the View that represents click
- * removal button.
- *
- * @param id An android resource id.
- */
- public void setClickRemoveId(int id) {
- mClickRemoveId = id;
- }
-
- /**
- * Sets flags to restrict certain motions of the floating View
- * based on DragSortController settings (such as remove mode).
- * Starts the drag on the DragSortListView.
- *
- * @param position The list item position (includes headers).
- * @param deltaX Touch x-coord minus left edge of floating View.
- * @param deltaY Touch y-coord minus top edge of floating View.
- *
- * @return True if drag started, false otherwise.
- */
- public boolean startDrag(int position, int deltaX, int deltaY) {
-
- int dragFlags = 0;
- if (mSortEnabled && !mIsRemoving) {
- dragFlags |= DragSortListView.DRAG_POS_Y | DragSortListView.DRAG_NEG_Y;
- }
- if (mRemoveEnabled && mIsRemoving) {
- dragFlags |= DragSortListView.DRAG_POS_X;
- dragFlags |= DragSortListView.DRAG_NEG_X;
- }
-
- mDragging = mDslv.startDrag(position - mDslv.getHeaderViewsCount(), dragFlags, deltaX,
- deltaY);
- return mDragging;
- }
-
- @Override
- public boolean onTouch(View v, MotionEvent ev) {
- if (!mDslv.isDragEnabled() || mDslv.listViewIntercepted()) {
- return false;
- }
-
- mDetector.onTouchEvent(ev);
- if (mRemoveEnabled && mDragging && mRemoveMode == FLING_REMOVE) {
- mFlingRemoveDetector.onTouchEvent(ev);
- }
-
- int action = ev.getAction() & MotionEvent.ACTION_MASK;
- switch (action) {
- case MotionEvent.ACTION_DOWN:
- mCurrX = (int) ev.getX();
- mCurrY = (int) ev.getY();
- break;
- case MotionEvent.ACTION_UP:
- if (mRemoveEnabled && mIsRemoving) {
- int x = mPositionX >= 0 ? mPositionX : -mPositionX;
- int removePoint = mDslv.getWidth() / 2;
- if (x > removePoint) {
- mDslv.stopDragWithVelocity(true, 0);
- }
- }
- case MotionEvent.ACTION_CANCEL:
- mIsRemoving = false;
- mDragging = false;
- break;
- }
-
- return false;
- }
-
- /**
- * Overrides to provide fading when slide removal is enabled.
- */
- @Override
- public void onDragFloatView(View floatView, Point position, Point touch) {
-
- if (mRemoveEnabled && mIsRemoving) {
- mPositionX = position.x;
- }
- }
-
- /**
- * Get the position to start dragging based on the ACTION_DOWN
- * MotionEvent. This function simply calls
- * {@link #dragHandleHitPosition(MotionEvent)}. Override
- * to change drag handle behavior;
- * this function is called internally when an ACTION_DOWN
- * event is detected.
- *
- * @param ev The ACTION_DOWN MotionEvent.
- *
- * @return The list position to drag if a drag-init gesture is
- * detected; MISS if unsuccessful.
- */
- public int startDragPosition(MotionEvent ev) {
- return dragHandleHitPosition(ev);
- }
-
- public int startFlingPosition(MotionEvent ev) {
- return mRemoveMode == FLING_REMOVE ? flingHandleHitPosition(ev) : MISS;
- }
-
- /**
- * Checks for the touch of an item's drag handle (specified by
- * {@link #setDragHandleId(int)}), and returns that item's position
- * if a drag handle touch was detected.
- *
- * @param ev The ACTION_DOWN MotionEvent.
-
- * @return The list position of the item whose drag handle was
- * touched; MISS if unsuccessful.
- */
- public int dragHandleHitPosition(MotionEvent ev) {
- return viewIdHitPosition(ev, mDragHandleId);
- }
-
- public int flingHandleHitPosition(MotionEvent ev) {
- return viewIdHitPosition(ev, mFlingHandleId);
- }
-
- public int viewIdHitPosition(MotionEvent ev, int id) {
- final int x = (int) ev.getX();
- final int y = (int) ev.getY();
-
- int touchPos = mDslv.pointToPosition(x, y); // includes headers/footers
-
- final int numHeaders = mDslv.getHeaderViewsCount();
- final int numFooters = mDslv.getFooterViewsCount();
- final int count = mDslv.getCount();
-
- // Log.d("mobeta", "touch down on position " + itemnum);
- // We're only interested if the touch was on an
- // item that's not a header or footer.
- if (touchPos != AdapterView.INVALID_POSITION && touchPos >= numHeaders
- && touchPos < (count - numFooters)) {
- final View item = mDslv.getChildAt(touchPos - mDslv.getFirstVisiblePosition());
- final int rawX = (int) ev.getRawX();
- final int rawY = (int) ev.getRawY();
-
- View dragBox = id == 0 ? item : (View) item.findViewById(id);
- if (dragBox != null) {
- dragBox.getLocationOnScreen(mTempLoc);
-
- if (rawX > mTempLoc[0] && rawY > mTempLoc[1] &&
- rawX < mTempLoc[0] + dragBox.getWidth() &&
- rawY < mTempLoc[1] + dragBox.getHeight()) {
-
- mItemX = item.getLeft();
- mItemY = item.getTop();
-
- return touchPos;
- }
- }
- }
-
- return MISS;
- }
-
- @Override
- public boolean onDown(MotionEvent ev) {
- if (mRemoveEnabled && mRemoveMode == CLICK_REMOVE) {
- mClickRemoveHitPos = viewIdHitPosition(ev, mClickRemoveId);
- }
-
- mHitPos = startDragPosition(ev);
- if (mHitPos != MISS && mDragInitMode == ON_DOWN) {
- startDrag(mHitPos, (int) ev.getX() - mItemX, (int) ev.getY() - mItemY);
- }
-
- mIsRemoving = false;
- mCanDrag = true;
- mPositionX = 0;
- mFlingHitPos = startFlingPosition(ev);
-
- return true;
- }
-
- @Override
- public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
-
- // it can happen where the motion events are null
- if (e1 == null || e2 == null) {
- // we can't really do anything
- return false;
- }
-
- final int x1 = (int) e1.getX();
- final int y1 = (int) e1.getY();
- final int x2 = (int) e2.getX();
- final int y2 = (int) e2.getY();
- final int deltaX = x2 - mItemX;
- final int deltaY = y2 - mItemY;
-
- if (mCanDrag && !mDragging && (mHitPos != MISS || mFlingHitPos != MISS)) {
- if (mHitPos != MISS) {
- if (mDragInitMode == ON_DRAG && Math.abs(y2 - y1) > mTouchSlop && mSortEnabled) {
- startDrag(mHitPos, deltaX, deltaY);
- }
- else if (mDragInitMode != ON_DOWN && Math.abs(x2 - x1) > mTouchSlop && mRemoveEnabled)
- {
- mIsRemoving = true;
- startDrag(mFlingHitPos, deltaX, deltaY);
- }
- } else if (mFlingHitPos != MISS) {
- if (Math.abs(x2 - x1) > mTouchSlop && mRemoveEnabled) {
- mIsRemoving = true;
- startDrag(mFlingHitPos, deltaX, deltaY);
- } else if (Math.abs(y2 - y1) > mTouchSlop) {
- mCanDrag = false; // if started to scroll the list then
- // don't allow sorting nor fling-removing
- }
- }
- }
- // return whatever
- return false;
- }
-
- @Override
- public void onLongPress(MotionEvent e) {
- // Log.d("mobeta", "lift listener long pressed");
- if (mHitPos != MISS && mDragInitMode == ON_LONG_PRESS) {
- mDslv.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
- startDrag(mHitPos, mCurrX - mItemX, mCurrY - mItemY);
- }
- }
-
- // complete the OnGestureListener interface
- @Override
- public final boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
- return false;
- }
-
- // complete the OnGestureListener interface
- @Override
- public boolean onSingleTapUp(MotionEvent ev) {
- if (mRemoveEnabled && mRemoveMode == CLICK_REMOVE) {
- if (mClickRemoveHitPos != MISS) {
- mDslv.removeItem(mClickRemoveHitPos - mDslv.getHeaderViewsCount());
- }
- }
- return true;
- }
-
- // complete the OnGestureListener interface
- @Override
- public void onShowPress(MotionEvent ev) {
- // do nothing
- }
-
- private GestureDetector.OnGestureListener mFlingRemoveListener =
- new GestureDetector.SimpleOnGestureListener() {
- @Override
- public final boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
- float velocityY) {
- ViewConfiguration vc = ViewConfiguration.get(mDslv.getContext());
- int minSwipeVelocity = vc.getScaledMinimumFlingVelocity();
- int maxSwipeVelocity = vc.getScaledMaximumFlingVelocity();
- if (mRemoveEnabled && mIsRemoving) {
- int w = mDslv.getWidth();
- if(mPositionX >= w/2) {
- mDslv.stopDragWithVelocity(true, velocityX);
- } else if(mPositionX >= w/5 && minSwipeVelocity <= velocityX && velocityX <= maxSwipeVelocity) {
- mDslv.stopDragWithVelocity(true, velocityX);
- }
- mIsRemoving = false;
- }
- return false;
- }
- };
-
-}
diff --git a/library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/DragSortCursorAdapter.java b/library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/DragSortCursorAdapter.java
deleted file mode 100644
index 267c6f869..000000000
--- a/library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/DragSortCursorAdapter.java
+++ /dev/null
@@ -1,241 +0,0 @@
-package com.mobeta.android.dslv;
-
-import java.util.ArrayList;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.util.SparseIntArray;
-import android.view.View;
-import android.view.ViewGroup;
-import android.support.v4.widget.CursorAdapter;
-
-
-/**
- * A subclass of {@link android.widget.CursorAdapter} that provides
- * reordering of the elements in the Cursor based on completed
- * drag-sort operations. The reordering is a simple mapping of
- * list positions into Cursor positions (the Cursor is unchanged).
- * To persist changes made by drag-sorts, one can retrieve the
- * mapping with the {@link #getCursorPositions()} method, which
- * returns the reordered list of Cursor positions.
- *
- * An instance of this class is passed
- * to {@link DragSortListView#setAdapter(ListAdapter)} and, since
- * this class implements the {@link DragSortListView.DragSortListener}
- * interface, it is automatically set as the DragSortListener for
- * the DragSortListView instance.
- */
-public abstract class DragSortCursorAdapter extends CursorAdapter implements DragSortListView.DragSortListener {
-
- public static final int REMOVED = -1;
-
- /**
- * Key is ListView position, value is Cursor position
- */
- private SparseIntArray mListMapping = new SparseIntArray();
-
- private ArrayList<Integer> mRemovedCursorPositions = new ArrayList<Integer>();
-
- public DragSortCursorAdapter(Context context, Cursor c) {
- super(context, c);
- }
-
- public DragSortCursorAdapter(Context context, Cursor c, boolean autoRequery) {
- super(context, c, autoRequery);
- }
-
- public DragSortCursorAdapter(Context context, Cursor c, int flags) {
- super(context, c, flags);
- }
-
- /**
- * Swaps Cursor and clears list-Cursor mapping.
- *
- * @see android.widget.CursorAdapter#swapCursor(android.database.Cursor)
- */
- @Override
- public Cursor swapCursor(Cursor newCursor) {
- Cursor old = super.swapCursor(newCursor);
- resetMappings();
- return old;
- }
-
- /**
- * Changes Cursor and clears list-Cursor mapping.
- *
- * @see android.widget.CursorAdapter#changeCursor(android.database.Cursor)
- */
- @Override
- public void changeCursor(Cursor cursor) {
- super.changeCursor(cursor);
- resetMappings();
- }
-
- /**
- * Resets list-cursor mapping.
- */
- public void reset() {
- resetMappings();
- notifyDataSetChanged();
- }
-
- private void resetMappings() {
- mListMapping.clear();
- mRemovedCursorPositions.clear();
- }
-
- @Override
- public Object getItem(int position) {
- return super.getItem(mListMapping.get(position, position));
- }
-
- @Override
- public long getItemId(int position) {
- return super.getItemId(mListMapping.get(position, position));
- }
-
- @Override
- public View getDropDownView(int position, View convertView, ViewGroup parent) {
- return super.getDropDownView(mListMapping.get(position, position), convertView, parent);
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- return super.getView(mListMapping.get(position, position), convertView, parent);
- }
-
- /**
- * On drop, this updates the mapping between Cursor positions
- * and ListView positions. The Cursor is unchanged. Retrieve
- * the current mapping with {@link getCursorPositions()}.
- *
- * @see DragSortListView.DropListener#drop(int, int)
- */
- @Override
- public void drop(int from, int to) {
- if (from != to) {
- int cursorFrom = mListMapping.get(from, from);
-
- if (from > to) {
- for (int i = from; i > to; --i) {
- mListMapping.put(i, mListMapping.get(i - 1, i - 1));
- }
- } else {
- for (int i = from; i < to; ++i) {
- mListMapping.put(i, mListMapping.get(i + 1, i + 1));
- }
- }
- mListMapping.put(to, cursorFrom);
-
- cleanMapping();
- notifyDataSetChanged();
- }
- }
-
- /**
- * On remove, this updates the mapping between Cursor positions
- * and ListView positions. The Cursor is unchanged. Retrieve
- * the current mapping with {@link getCursorPositions()}.
- *
- * @see DragSortListView.RemoveListener#remove(int)
- */
- @Override
- public void remove(int which) {
- int cursorPos = mListMapping.get(which, which);
- if (!mRemovedCursorPositions.contains(cursorPos)) {
- mRemovedCursorPositions.add(cursorPos);
- }
-
- int newCount = getCount();
- for (int i = which; i < newCount; ++i) {
- mListMapping.put(i, mListMapping.get(i + 1, i + 1));
- }
-
- mListMapping.delete(newCount);
-
- cleanMapping();
- notifyDataSetChanged();
- }
-
- /**
- * Does nothing. Just completes DragSortListener interface.
- */
- @Override
- public void drag(int from, int to) {
- // do nothing
- }
-
- /**
- * Remove unnecessary mappings from sparse array.
- */
- private void cleanMapping() {
- ArrayList<Integer> toRemove = new ArrayList<Integer>();
-
- int size = mListMapping.size();
- for (int i = 0; i < size; ++i) {
- if (mListMapping.keyAt(i) == mListMapping.valueAt(i)) {
- toRemove.add(mListMapping.keyAt(i));
- }
- }
-
- size = toRemove.size();
- for (int i = 0; i < size; ++i) {
- mListMapping.delete(toRemove.get(i));
- }
- }
-
- @Override
- public int getCount() {
- return super.getCount() - mRemovedCursorPositions.size();
- }
-
- /**
- * Get the Cursor position mapped to by the provided list position
- * (given all previously handled drag-sort
- * operations).
- *
- * @param position List position
- *
- * @return The mapped-to Cursor position
- */
- public int getCursorPosition(int position) {
- return mListMapping.get(position, position);
- }
-
- /**
- * Get the current order of Cursor positions presented by the
- * list.
- */
- public ArrayList<Integer> getCursorPositions() {
- ArrayList<Integer> result = new ArrayList<Integer>();
-
- for (int i = 0; i < getCount(); ++i) {
- result.add(mListMapping.get(i, i));
- }
-
- return result;
- }
-
- /**
- * Get the list position mapped to by the provided Cursor position.
- * If the provided Cursor position has been removed by a drag-sort,
- * this returns {@link #REMOVED}.
- *
- * @param cursorPosition A Cursor position
- * @return The mapped-to list position or REMOVED
- */
- public int getListPosition(int cursorPosition) {
- if (mRemovedCursorPositions.contains(cursorPosition)) {
- return REMOVED;
- }
-
- int index = mListMapping.indexOfValue(cursorPosition);
- if (index < 0) {
- return cursorPosition;
- } else {
- return mListMapping.keyAt(index);
- }
- }
-
-
-}
diff --git a/library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/DragSortItemView.java b/library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/DragSortItemView.java
deleted file mode 100644
index cef7b82bb..000000000
--- a/library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/DragSortItemView.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package com.mobeta.android.dslv;
-
-import android.content.Context;
-import android.view.Gravity;
-import android.view.View;
-import android.view.View.MeasureSpec;
-import android.view.ViewGroup;
-import android.widget.AbsListView;
-import android.util.Log;
-
-/**
- * Lightweight ViewGroup that wraps list items obtained from user's
- * ListAdapter. ItemView expects a single child that has a definite
- * height (i.e. the child's layout height is not MATCH_PARENT).
- * The width of
- * ItemView will always match the width of its child (that is,
- * the width MeasureSpec given to ItemView is passed directly
- * to the child, and the ItemView measured width is set to the
- * child's measured width). The height of ItemView can be anything;
- * the
- *
- *
- * The purpose of this class is to optimize slide
- * shuffle animations.
- */
-public class DragSortItemView extends ViewGroup {
-
- private int mGravity = Gravity.TOP;
-
- public DragSortItemView(Context context) {
- super(context);
-
- // always init with standard ListView layout params
- setLayoutParams(new AbsListView.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT,
- ViewGroup.LayoutParams.WRAP_CONTENT));
-
- //setClipChildren(true);
- }
-
- public void setGravity(int gravity) {
- mGravity = gravity;
- }
-
- public int getGravity() {
- return mGravity;
- }
-
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- final View child = getChildAt(0);
-
- if (child == null) {
- return;
- }
-
- if (mGravity == Gravity.TOP) {
- child.layout(0, 0, getMeasuredWidth(), child.getMeasuredHeight());
- } else {
- child.layout(0, getMeasuredHeight() - child.getMeasuredHeight(), getMeasuredWidth(), getMeasuredHeight());
- }
- }
-
- /**
- *
- */
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-
- int height = MeasureSpec.getSize(heightMeasureSpec);
- int width = MeasureSpec.getSize(widthMeasureSpec);
-
- int heightMode = MeasureSpec.getMode(heightMeasureSpec);
-
- final View child = getChildAt(0);
- if (child == null) {
- setMeasuredDimension(0, width);
- return;
- }
-
- if (child.isLayoutRequested()) {
- // Always let child be as tall as it wants.
- measureChild(child, widthMeasureSpec,
- MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
- }
-
- if (heightMode == MeasureSpec.UNSPECIFIED) {
- ViewGroup.LayoutParams lp = getLayoutParams();
-
- if (lp.height > 0) {
- height = lp.height;
- } else {
- height = child.getMeasuredHeight();
- }
- }
-
- setMeasuredDimension(width, height);
- }
-
-}
diff --git a/library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/DragSortItemViewCheckable.java b/library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/DragSortItemViewCheckable.java
deleted file mode 100644
index 27d612e01..000000000
--- a/library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/DragSortItemViewCheckable.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package com.mobeta.android.dslv;
-
-import android.content.Context;
-import android.view.Gravity;
-import android.view.View;
-import android.view.View.MeasureSpec;
-import android.view.ViewGroup;
-import android.widget.AbsListView;
-import android.widget.Checkable;
-import android.util.Log;
-
-/**
- * Lightweight ViewGroup that wraps list items obtained from user's
- * ListAdapter. ItemView expects a single child that has a definite
- * height (i.e. the child's layout height is not MATCH_PARENT).
- * The width of
- * ItemView will always match the width of its child (that is,
- * the width MeasureSpec given to ItemView is passed directly
- * to the child, and the ItemView measured width is set to the
- * child's measured width). The height of ItemView can be anything;
- * the
- *
- *
- * The purpose of this class is to optimize slide
- * shuffle animations.
- */
-public class DragSortItemViewCheckable extends DragSortItemView implements Checkable {
-
- public DragSortItemViewCheckable(Context context) {
- super(context);
- }
-
- @Override
- public boolean isChecked() {
- View child = getChildAt(0);
- if (child instanceof Checkable)
- return ((Checkable) child).isChecked();
- else
- return false;
- }
-
- @Override
- public void setChecked(boolean checked) {
- View child = getChildAt(0);
- if (child instanceof Checkable)
- ((Checkable) child).setChecked(checked);
- }
-
- @Override
- public void toggle() {
- View child = getChildAt(0);
- if (child instanceof Checkable)
- ((Checkable) child).toggle();
- }
-}
diff --git a/library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/DragSortListView.java b/library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/DragSortListView.java
deleted file mode 100644
index 4f8ec744d..000000000
--- a/library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/DragSortListView.java
+++ /dev/null
@@ -1,3073 +0,0 @@
-/*
- * DragSortListView.
- *
- * A subclass of the Android ListView component that enables drag
- * and drop re-ordering of list items.
- *
- * Copyright 2012 Carl Bauer
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.mobeta.android.dslv;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.database.DataSetObserver;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Point;
-import android.graphics.drawable.Drawable;
-import android.os.Environment;
-import android.os.SystemClock;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.SparseBooleanArray;
-import android.util.SparseIntArray;
-import android.view.Gravity;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AbsListView;
-import android.widget.BaseAdapter;
-import android.widget.Checkable;
-import android.widget.ListAdapter;
-import android.widget.ListView;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.ArrayList;
-
-/**
- * ListView subclass that mediates drag and drop resorting of items.
- *
- *
- * @author heycosmo
- *
- */
-public class DragSortListView extends ListView {
-
-
- /**
- * The View that floats above the ListView and represents
- * the dragged item.
- */
- private View mFloatView;
-
- /**
- * The float View location. First based on touch location
- * and given deltaX and deltaY. Then restricted by callback
- * to FloatViewManager.onDragFloatView(). Finally restricted
- * by bounds of DSLV.
- */
- private Point mFloatLoc = new Point();
-
- private Point mTouchLoc = new Point();
-
- /**
- * The middle (in the y-direction) of the floating View.
- */
- private int mFloatViewMid;
-
- /**
- * Flag to make sure float View isn't measured twice
- */
- private boolean mFloatViewOnMeasured = false;
-
- /**
- * Watch the Adapter for data changes. Cancel a drag if
- * coincident with a change.
- */
- private DataSetObserver mObserver;
-
- /**
- * Transparency for the floating View (XML attribute).
- */
- private float mFloatAlpha = 1.0f;
- private float mCurrFloatAlpha = 1.0f;
-
- /**
- * While drag-sorting, the current position of the floating
- * View. If dropped, the dragged item will land in this position.
- */
- private int mFloatPos;
-
- /**
- * The first expanded ListView position that helps represent
- * the drop slot tracking the floating View.
- */
- private int mFirstExpPos;
-
- /**
- * The second expanded ListView position that helps represent
- * the drop slot tracking the floating View. This can equal
- * mFirstExpPos if there is no slide shuffle occurring; otherwise
- * it is equal to mFirstExpPos + 1.
- */
- private int mSecondExpPos;
-
- /**
- * Flag set if slide shuffling is enabled.
- */
- private boolean mAnimate = false;
-
- /**
- * The user dragged from this position.
- */
- private int mSrcPos;
-
- /**
- * Offset (in x) within the dragged item at which the user
- * picked it up (or first touched down with the digitalis).
- */
- private int mDragDeltaX;
-
- /**
- * Offset (in y) within the dragged item at which the user
- * picked it up (or first touched down with the digitalis).
- */
- private int mDragDeltaY;
-
-
- /**
- * The difference (in x) between screen coordinates and coordinates
- * in this view.
- */
- private int mOffsetX;
-
- /**
- * The difference (in y) between screen coordinates and coordinates
- * in this view.
- */
- private int mOffsetY;
-
- /**
- * A listener that receives callbacks whenever the floating View
- * hovers over a new position.
- */
- private DragListener mDragListener;
-
- /**
- * A listener that receives a callback when the floating View
- * is dropped.
- */
- private DropListener mDropListener;
-
- /**
- * A listener that receives a callback when the floating View
- * (or more precisely the originally dragged item) is removed
- * by one of the provided gestures.
- */
- private RemoveListener mRemoveListener;
-
- /**
- * Enable/Disable item dragging
- *
- * @attr name dslv:drag_enabled
- */
- private boolean mDragEnabled = true;
-
- /**
- * Drag state enum.
- */
- private final static int IDLE = 0;
- private final static int REMOVING = 1;
- private final static int DROPPING = 2;
- private final static int STOPPED = 3;
- private final static int DRAGGING = 4;
-
- private int mDragState = IDLE;
-
- /**
- * Height in pixels to which the originally dragged item
- * is collapsed during a drag-sort. Currently, this value
- * must be greater than zero.
- */
- private int mItemHeightCollapsed = 1;
-
- /**
- * Height of the floating View. Stored for the purpose of
- * providing the tracking drop slot.
- */
- private int mFloatViewHeight;
-
- /**
- * Convenience member. See above.
- */
- private int mFloatViewHeightHalf;
-
- /**
- * Save the given width spec for use in measuring children
- */
- private int mWidthMeasureSpec = 0;
-
- /**
- * Sample Views ultimately used for calculating the height
- * of ListView items that are off-screen.
- */
- private View[] mSampleViewTypes = new View[1];
-
- /**
- * Drag-scroll encapsulator!
- */
- private DragScroller mDragScroller;
-
- /**
- * Determines the start of the upward drag-scroll region
- * at the top of the ListView. Specified by a fraction
- * of the ListView height, thus screen resolution agnostic.
- */
- private float mDragUpScrollStartFrac = 1.0f / 3.0f;
-
- /**
- * Determines the start of the downward drag-scroll region
- * at the bottom of the ListView. Specified by a fraction
- * of the ListView height, thus screen resolution agnostic.
- */
- private float mDragDownScrollStartFrac = 1.0f / 3.0f;
-
- /**
- * The following are calculated from the above fracs.
- */
- private int mUpScrollStartY;
- private int mDownScrollStartY;
- private float mDownScrollStartYF;
- private float mUpScrollStartYF;
-
- /**
- * Calculated from above above and current ListView height.
- */
- private float mDragUpScrollHeight;
-
- /**
- * Calculated from above above and current ListView height.
- */
- private float mDragDownScrollHeight;
-
- /**
- * Maximum drag-scroll speed in pixels per ms. Only used with
- * default linear drag-scroll profile.
- */
- private float mMaxScrollSpeed = 0.5f;
-
- /**
- * Defines the scroll speed during a drag-scroll. User can
- * provide their own; this default is a simple linear profile
- * where scroll speed increases linearly as the floating View
- * nears the top/bottom of the ListView.
- */
- private DragScrollProfile mScrollProfile = new DragScrollProfile() {
- @Override
- public float getSpeed(float w, long t) {
- return mMaxScrollSpeed * w;
- }
- };
-
- /**
- * Current touch x.
- */
- private int mX;
-
- /**
- * Current touch y.
- */
- private int mY;
-
- /**
- * Last touch x.
- */
- private int mLastX;
-
- /**
- * Last touch y.
- */
- private int mLastY;
-
- /**
- * The touch y-coord at which drag started
- */
- private int mDragStartY;
-
- /**
- * Drag flag bit. Floating View can move in the positive
- * x direction.
- */
- public final static int DRAG_POS_X = 0x1;
-
- /**
- * Drag flag bit. Floating View can move in the negative
- * x direction.
- */
- public final static int DRAG_NEG_X = 0x2;
-
- /**
- * Drag flag bit. Floating View can move in the positive
- * y direction. This is subtle. What this actually means is
- * that, if enabled, the floating View can be dragged below its starting
- * position. Remove in favor of upper-bounding item position?
- */
- public final static int DRAG_POS_Y = 0x4;
-
- /**
- * Drag flag bit. Floating View can move in the negative
- * y direction. This is subtle. What this actually means is
- * that the floating View can be dragged above its starting
- * position. Remove in favor of lower-bounding item position?
- */
- public final static int DRAG_NEG_Y = 0x8;
-
- /**
- * Flags that determine limits on the motion of the
- * floating View. See flags above.
- */
- private int mDragFlags = 0;
-
- /**
- * Last call to an on*TouchEvent was a call to
- * onInterceptTouchEvent.
- */
- private boolean mLastCallWasIntercept = false;
-
- /**
- * A touch event is in progress.
- */
- private boolean mInTouchEvent = false;
-
- /**
- * Let the user customize the floating View.
- */
- private FloatViewManager mFloatViewManager = null;
-
- /**
- * Given to ListView to cancel its action when a drag-sort
- * begins.
- */
- private MotionEvent mCancelEvent;
-
- /**
- * Enum telling where to cancel the ListView action when a
- * drag-sort begins
- */
- private static final int NO_CANCEL = 0;
- private static final int ON_TOUCH_EVENT = 1;
- private static final int ON_INTERCEPT_TOUCH_EVENT = 2;
-
- /**
- * Where to cancel the ListView action when a
- * drag-sort begins
- */
- private int mCancelMethod = NO_CANCEL;
-
- /**
- * Determines when a slide shuffle animation starts. That is,
- * defines how close to the edge of the drop slot the floating
- * View must be to initiate the slide.
- */
- private float mSlideRegionFrac = 0.25f;
-
- /**
- * Number between 0 and 1 indicating the relative location of
- * a sliding item (only used if drag-sort animations
- * are turned on). Nearly 1 means the item is
- * at the top of the slide region (nearly full blank item
- * is directly below).
- */
- private float mSlideFrac = 0.0f;
-
- /**
- * Wraps the user-provided ListAdapter. This is used to wrap each
- * item View given by the user inside another View (currenly
- * a RelativeLayout) which
- * expands and collapses to simulate the item shuffling.
- */
- private AdapterWrapper mAdapterWrapper;
-
- /**
- * Turn on custom debugger.
- */
- private boolean mTrackDragSort = false;
-
- /**
- * Debugging class.
- */
- private DragSortTracker mDragSortTracker;
-
- /**
- * Needed for adjusting item heights from within layoutChildren
- */
- private boolean mBlockLayoutRequests = false;
-
- /**
- * Set to true when a down event happens during drag sort;
- * for example, when drag finish animations are
- * playing.
- */
- private boolean mIgnoreTouchEvent = false;
-
- /**
- * Caches DragSortItemView child heights. Sometimes DSLV has to
- * know the height of an offscreen item. Since ListView virtualizes
- * these, DSLV must get the item from the ListAdapter to obtain
- * its height. That process can be expensive, but often the same
- * offscreen item will be requested many times in a row. Once an
- * offscreen item height is calculated, we cache it in this guy.
- * Actually, we cache the height of the child of the
- * DragSortItemView since the item height changes often during a
- * drag-sort.
- */
- private static final int sCacheSize = 3;
- private HeightCache mChildHeightCache = new HeightCache(sCacheSize);
-
- private RemoveAnimator mRemoveAnimator;
-
- private LiftAnimator mLiftAnimator;
-
- private DropAnimator mDropAnimator;
-
- private boolean mUseRemoveVelocity;
- private float mRemoveVelocityX = 0;
-
- public DragSortListView(Context context, AttributeSet attrs) {
- super(context, attrs);
-
- int defaultDuration = 150;
- int removeAnimDuration = defaultDuration; // ms
- int dropAnimDuration = defaultDuration; // ms
-
- if (attrs != null) {
- TypedArray a = getContext().obtainStyledAttributes(attrs,
- R.styleable.DragSortListView, 0, 0);
-
- mItemHeightCollapsed = Math.max(1, a.getDimensionPixelSize(
- R.styleable.DragSortListView_collapsed_height, 1));
-
- mTrackDragSort = a.getBoolean(
- R.styleable.DragSortListView_track_drag_sort, false);
-
- if (mTrackDragSort) {
- mDragSortTracker = new DragSortTracker();
- }
-
- // alpha between 0 and 255, 0=transparent, 255=opaque
- mFloatAlpha = a.getFloat(R.styleable.DragSortListView_float_alpha, mFloatAlpha);
- mCurrFloatAlpha = mFloatAlpha;
-
- mDragEnabled = a.getBoolean(R.styleable.DragSortListView_drag_enabled, mDragEnabled);
-
- mSlideRegionFrac = Math.max(0.0f,
- Math.min(1.0f, 1.0f - a.getFloat(
- R.styleable.DragSortListView_slide_shuffle_speed,
- 0.75f)));
-
- mAnimate = mSlideRegionFrac > 0.0f;
-
- float frac = a.getFloat(
- R.styleable.DragSortListView_drag_scroll_start,
- mDragUpScrollStartFrac);
-
- setDragScrollStart(frac);
-
- mMaxScrollSpeed = a.getFloat(
- R.styleable.DragSortListView_max_drag_scroll_speed,
- mMaxScrollSpeed);
-
- removeAnimDuration = a.getInt(
- R.styleable.DragSortListView_remove_animation_duration,
- removeAnimDuration);
-
- dropAnimDuration = a.getInt(
- R.styleable.DragSortListView_drop_animation_duration,
- dropAnimDuration);
-
- boolean useDefault = a.getBoolean(
- R.styleable.DragSortListView_use_default_controller,
- true);
-
- if (useDefault) {
- boolean removeEnabled = a.getBoolean(
- R.styleable.DragSortListView_remove_enabled,
- false);
- int removeMode = a.getInt(
- R.styleable.DragSortListView_remove_mode,
- DragSortController.FLING_REMOVE);
- boolean sortEnabled = a.getBoolean(
- R.styleable.DragSortListView_sort_enabled,
- true);
- int dragInitMode = a.getInt(
- R.styleable.DragSortListView_drag_start_mode,
- DragSortController.ON_DOWN);
- int dragHandleId = a.getResourceId(
- R.styleable.DragSortListView_drag_handle_id,
- 0);
- int flingHandleId = a.getResourceId(
- R.styleable.DragSortListView_fling_handle_id,
- 0);
- int clickRemoveId = a.getResourceId(
- R.styleable.DragSortListView_click_remove_id,
- 0);
- int bgColor = a.getColor(
- R.styleable.DragSortListView_float_background_color,
- Color.BLACK);
-
- DragSortController controller = new DragSortController(
- this, dragHandleId, dragInitMode, removeMode,
- clickRemoveId, flingHandleId);
- controller.setRemoveEnabled(removeEnabled);
- controller.setSortEnabled(sortEnabled);
- controller.setBackgroundColor(bgColor);
-
- mFloatViewManager = controller;
- setOnTouchListener(controller);
- }
-
- a.recycle();
- }
-
- mDragScroller = new DragScroller();
-
- float smoothness = 0.5f;
- if (removeAnimDuration > 0) {
- mRemoveAnimator = new RemoveAnimator(smoothness, removeAnimDuration);
- }
- // mLiftAnimator = new LiftAnimator(smoothness, 100);
- if (dropAnimDuration > 0) {
- mDropAnimator = new DropAnimator(smoothness, dropAnimDuration);
- }
-
- mCancelEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_CANCEL, 0f, 0f, 0f, 0f, 0, 0f,
- 0f, 0, 0);
-
- // construct the dataset observer
- mObserver = new DataSetObserver() {
- private void cancel() {
- if (mDragState == DRAGGING) {
- cancelDrag();
- }
- }
-
- @Override
- public void onChanged() {
- cancel();
- }
-
- @Override
- public void onInvalidated() {
- cancel();
- }
- };
- }
-
- /**
- * Usually called from a FloatViewManager. The float alpha
- * will be reset to the xml-defined value every time a drag
- * is stopped.
- */
- public void setFloatAlpha(float alpha) {
- mCurrFloatAlpha = alpha;
- }
-
- public float getFloatAlpha() {
- return mCurrFloatAlpha;
- }
-
- /**
- * Set maximum drag scroll speed in positions/second. Only applies
- * if using default ScrollSpeedProfile.
- *
- * @param max Maximum scroll speed.
- */
- public void setMaxScrollSpeed(float max) {
- mMaxScrollSpeed = max;
- }
-
- /**
- * For each DragSortListView Listener interface implemented by
- * <code>adapter</code>, this method calls the appropriate
- * set*Listener method with <code>adapter</code> as the argument.
- *
- * @param adapter The ListAdapter providing data to back
- * DragSortListView.
- *
- * @see android.widget.ListView#setAdapter(android.widget.ListAdapter)
- */
- @Override
- public void setAdapter(ListAdapter adapter) {
- if (adapter != null) {
- mAdapterWrapper = new AdapterWrapper(adapter);
- adapter.registerDataSetObserver(mObserver);
-
- if (adapter instanceof DropListener) {
- setDropListener((DropListener) adapter);
- }
- if (adapter instanceof DragListener) {
- setDragListener((DragListener) adapter);
- }
- if (adapter instanceof RemoveListener) {
- setRemoveListener((RemoveListener) adapter);
- }
- } else {
- mAdapterWrapper = null;
- }
-
- super.setAdapter(mAdapterWrapper);
- }
-
- /**
- * As opposed to {@link ListView#getAdapter()}, which returns
- * a heavily wrapped ListAdapter (DragSortListView wraps the
- * input ListAdapter {\emph and} ListView wraps the wrapped one).
- *
- * @return The ListAdapter set as the argument of {@link setAdapter()}
- */
- public ListAdapter getInputAdapter() {
- if (mAdapterWrapper == null) {
- return null;
- } else {
- return mAdapterWrapper.getAdapter();
- }
- }
-
- private class AdapterWrapper extends BaseAdapter {
- private ListAdapter mAdapter;
-
- public AdapterWrapper(ListAdapter adapter) {
- super();
- mAdapter = adapter;
-
- mAdapter.registerDataSetObserver(new DataSetObserver() {
- public void onChanged() {
- notifyDataSetChanged();
- }
-
- public void onInvalidated() {
- notifyDataSetInvalidated();
- }
- });
- }
-
- public ListAdapter getAdapter() {
- return mAdapter;
- }
-
- @Override
- public long getItemId(int position) {
- return mAdapter.getItemId(position);
- }
-
- @Override
- public Object getItem(int position) {
- return mAdapter.getItem(position);
- }
-
- @Override
- public int getCount() {
- return mAdapter.getCount();
- }
-
- @Override
- public boolean areAllItemsEnabled() {
- return mAdapter.areAllItemsEnabled();
- }
-
- @Override
- public boolean isEnabled(int position) {
- return mAdapter.isEnabled(position);
- }
-
- @Override
- public int getItemViewType(int position) {
- return mAdapter.getItemViewType(position);
- }
-
- @Override
- public int getViewTypeCount() {
- return mAdapter.getViewTypeCount();
- }
-
- @Override
- public boolean hasStableIds() {
- return mAdapter.hasStableIds();
- }
-
- @Override
- public boolean isEmpty() {
- return mAdapter.isEmpty();
- }
-
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
-
- DragSortItemView v;
- View child;
- // Log.d("mobeta",
- // "getView: position="+position+" convertView="+convertView);
- if (convertView != null) {
- v = (DragSortItemView) convertView;
- View oldChild = v.getChildAt(0);
-
- child = mAdapter.getView(position, oldChild, DragSortListView.this);
- if (child != oldChild) {
- // shouldn't get here if user is reusing convertViews
- // properly
- if (oldChild != null) {
- v.removeViewAt(0);
- }
- v.addView(child);
- }
- } else {
- child = mAdapter.getView(position, null, DragSortListView.this);
- if (child instanceof Checkable) {
- v = new DragSortItemViewCheckable(getContext());
- } else {
- v = new DragSortItemView(getContext());
- }
- v.setLayoutParams(new AbsListView.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT,
- ViewGroup.LayoutParams.WRAP_CONTENT));
- v.addView(child);
- }
-
- // Set the correct item height given drag state; passed
- // View needs to be measured if measurement is required.
- adjustItem(position + getHeaderViewsCount(), v, true);
-
- return v;
- }
- }
-
- private void drawDivider(int expPosition, Canvas canvas) {
-
- final Drawable divider = getDivider();
- final int dividerHeight = getDividerHeight();
- // Log.d("mobeta", "div="+divider+" divH="+dividerHeight);
-
- if (divider != null && dividerHeight != 0) {
- final ViewGroup expItem = (ViewGroup) getChildAt(expPosition
- - getFirstVisiblePosition());
- if (expItem != null) {
- final int l = getPaddingLeft();
- final int r = getWidth() - getPaddingRight();
- final int t;
- final int b;
-
- final int childHeight = expItem.getChildAt(0).getHeight();
-
- if (expPosition > mSrcPos) {
- t = expItem.getTop() + childHeight;
- b = t + dividerHeight;
- } else {
- b = expItem.getBottom() - childHeight;
- t = b - dividerHeight;
- }
- // Log.d("mobeta", "l="+l+" t="+t+" r="+r+" b="+b);
-
- // Have to clip to support ColorDrawable on <= Gingerbread
- canvas.save();
- canvas.clipRect(l, t, r, b);
- divider.setBounds(l, t, r, b);
- divider.draw(canvas);
- canvas.restore();
- }
- }
- }
-
- @Override
- protected void dispatchDraw(Canvas canvas) {
- super.dispatchDraw(canvas);
-
- if (mDragState != IDLE) {
- // draw the divider over the expanded item
- if (mFirstExpPos != mSrcPos) {
- drawDivider(mFirstExpPos, canvas);
- }
- if (mSecondExpPos != mFirstExpPos && mSecondExpPos != mSrcPos) {
- drawDivider(mSecondExpPos, canvas);
- }
- }
-
- if (mFloatView != null) {
- // draw the float view over everything
- final int w = mFloatView.getWidth();
- final int h = mFloatView.getHeight();
-
- int x = mFloatLoc.x;
-
- int width = getWidth();
- if (x < 0)
- x = -x;
- float alphaMod;
- if (x < width) {
- alphaMod = ((float) (width - x)) / ((float) width);
- alphaMod *= alphaMod;
- } else {
- alphaMod = 0;
- }
-
- final int alpha = (int) (255f * mCurrFloatAlpha * alphaMod);
-
- canvas.save();
- // Log.d("mobeta", "clip rect bounds: " + canvas.getClipBounds());
- canvas.translate(mFloatLoc.x, mFloatLoc.y);
- canvas.clipRect(0, 0, w, h);
-
- // Log.d("mobeta", "clip rect bounds: " + canvas.getClipBounds());
- canvas.saveLayerAlpha(0, 0, w, h, alpha, Canvas.ALL_SAVE_FLAG);
- mFloatView.draw(canvas);
- canvas.restore();
- canvas.restore();
- }
- }
-
- private int getItemHeight(int position) {
- View v = getChildAt(position - getFirstVisiblePosition());
-
- if (v != null) {
- // item is onscreen, just get the height of the View
- return v.getHeight();
- } else {
- // item is offscreen. get child height and calculate
- // item height based on current shuffle state
- return calcItemHeight(position, getChildHeight(position));
- }
- }
-
- private void printPosData() {
- Log.d("mobeta", "mSrcPos=" + mSrcPos + " mFirstExpPos=" + mFirstExpPos + " mSecondExpPos="
- + mSecondExpPos);
- }
-
- private class HeightCache {
-
- private SparseIntArray mMap;
- private ArrayList<Integer> mOrder;
- private int mMaxSize;
-
- public HeightCache(int size) {
- mMap = new SparseIntArray(size);
- mOrder = new ArrayList<Integer>(size);
- mMaxSize = size;
- }
-
- /**
- * Add item height at position if doesn't already exist.
- */
- public void add(int position, int height) {
- int currHeight = mMap.get(position, -1);
- if (currHeight != height) {
- if (currHeight == -1) {
- if (mMap.size() == mMaxSize) {
- // remove oldest entry
- mMap.delete(mOrder.remove(0));
- }
- } else {
- // move position to newest slot
- mOrder.remove((Integer) position);
- }
- mMap.put(position, height);
- mOrder.add(position);
- }
- }
-
- public int get(int position) {
- return mMap.get(position, -1);
- }
-
- public void clear() {
- mMap.clear();
- mOrder.clear();
- }
-
- }
-
- /**
- * Get the shuffle edge for item at position when top of
- * item is at y-coord top. Assumes that current item heights
- * are consistent with current float view location and
- * thus expanded positions and slide fraction. i.e. Should not be
- * called between update of expanded positions/slide fraction
- * and layoutChildren.
- *
- * @param position
- * @param top
- * @param height Height of item at position. If -1, this function
- * calculates this height.
- *
- * @return Shuffle line between position-1 and position (for
- * the given view of the list; that is, for when top of item at
- * position has y-coord of given `top`). If
- * floating View (treated as horizontal line) is dropped
- * immediately above this line, it lands in position-1. If
- * dropped immediately below this line, it lands in position.
- */
- private int getShuffleEdge(int position, int top) {
-
- final int numHeaders = getHeaderViewsCount();
- final int numFooters = getFooterViewsCount();
-
- // shuffle edges are defined between items that can be
- // dragged; there are N-1 of them if there are N draggable
- // items.
-
- if (position <= numHeaders || (position >= getCount() - numFooters)) {
- return top;
- }
-
- int divHeight = getDividerHeight();
-
- int edge;
-
- int maxBlankHeight = mFloatViewHeight - mItemHeightCollapsed;
- int childHeight = getChildHeight(position);
- int itemHeight = getItemHeight(position);
-
- // first calculate top of item given that floating View is
- // centered over src position
- int otop = top;
- if (mSecondExpPos <= mSrcPos) {
- // items are expanded on and/or above the source position
-
- if (position == mSecondExpPos && mFirstExpPos != mSecondExpPos) {
- if (position == mSrcPos) {
- otop = top + itemHeight - mFloatViewHeight;
- } else {
- int blankHeight = itemHeight - childHeight;
- otop = top + blankHeight - maxBlankHeight;
- }
- } else if (position > mSecondExpPos && position <= mSrcPos) {
- otop = top - maxBlankHeight;
- }
-
- } else {
- // items are expanded on and/or below the source position
-
- if (position > mSrcPos && position <= mFirstExpPos) {
- otop = top + maxBlankHeight;
- } else if (position == mSecondExpPos && mFirstExpPos != mSecondExpPos) {
- int blankHeight = itemHeight - childHeight;
- otop = top + blankHeight;
- }
- }
-
- // otop is set
- if (position <= mSrcPos) {
- edge = otop + (mFloatViewHeight - divHeight - getChildHeight(position - 1)) / 2;
- } else {
- edge = otop + (childHeight - divHeight - mFloatViewHeight) / 2;
- }
-
- return edge;
- }
-
- private boolean updatePositions() {
-
- final int first = getFirstVisiblePosition();
- int startPos = mFirstExpPos;
- View startView = getChildAt(startPos - first);
-
- if (startView == null) {
- startPos = first + getChildCount() / 2;
- startView = getChildAt(startPos - first);
- }
- int startTop = startView.getTop();
-
- int itemHeight = startView.getHeight();
-
- int edge = getShuffleEdge(startPos, startTop);
- int lastEdge = edge;
-
- int divHeight = getDividerHeight();
-
- // Log.d("mobeta", "float mid="+mFloatViewMid);
-
- int itemPos = startPos;
- int itemTop = startTop;
- if (mFloatViewMid < edge) {
- // scanning up for float position
- // Log.d("mobeta", " edge="+edge);
- while (itemPos >= 0) {
- itemPos--;
- itemHeight = getItemHeight(itemPos);
-
- if (itemPos == 0) {
- edge = itemTop - divHeight - itemHeight;
- break;
- }
-
- itemTop -= itemHeight + divHeight;
- edge = getShuffleEdge(itemPos, itemTop);
- // Log.d("mobeta", " edge="+edge);
-
- if (mFloatViewMid >= edge) {
- break;
- }
-
- lastEdge = edge;
- }
- } else {
- // scanning down for float position
- // Log.d("mobeta", " edge="+edge);
- final int count = getCount();
- while (itemPos < count) {
- if (itemPos == count - 1) {
- edge = itemTop + divHeight + itemHeight;
- break;
- }
-
- itemTop += divHeight + itemHeight;
- itemHeight = getItemHeight(itemPos + 1);
- edge = getShuffleEdge(itemPos + 1, itemTop);
- // Log.d("mobeta", " edge="+edge);
-
- // test for hit
- if (mFloatViewMid < edge) {
- break;
- }
-
- lastEdge = edge;
- itemPos++;
- }
- }
-
- final int numHeaders = getHeaderViewsCount();
- final int numFooters = getFooterViewsCount();
-
- boolean updated = false;
-
- int oldFirstExpPos = mFirstExpPos;
- int oldSecondExpPos = mSecondExpPos;
- float oldSlideFrac = mSlideFrac;
-
- if (mAnimate) {
- int edgeToEdge = Math.abs(edge - lastEdge);
-
- int edgeTop, edgeBottom;
- if (mFloatViewMid < edge) {
- edgeBottom = edge;
- edgeTop = lastEdge;
- } else {
- edgeTop = edge;
- edgeBottom = lastEdge;
- }
- // Log.d("mobeta", "edgeTop="+edgeTop+" edgeBot="+edgeBottom);
-
- int slideRgnHeight = (int) (0.5f * mSlideRegionFrac * edgeToEdge);
- float slideRgnHeightF = (float) slideRgnHeight;
- int slideEdgeTop = edgeTop + slideRgnHeight;
- int slideEdgeBottom = edgeBottom - slideRgnHeight;
-
- // Three regions
- if (mFloatViewMid < slideEdgeTop) {
- mFirstExpPos = itemPos - 1;
- mSecondExpPos = itemPos;
- mSlideFrac = 0.5f * ((float) (slideEdgeTop - mFloatViewMid)) / slideRgnHeightF;
- // Log.d("mobeta",
- // "firstExp="+mFirstExpPos+" secExp="+mSecondExpPos+" slideFrac="+mSlideFrac);
- } else if (mFloatViewMid < slideEdgeBottom) {
- mFirstExpPos = itemPos;
- mSecondExpPos = itemPos;
- } else {
- mFirstExpPos = itemPos;
- mSecondExpPos = itemPos + 1;
- mSlideFrac = 0.5f * (1.0f + ((float) (edgeBottom - mFloatViewMid))
- / slideRgnHeightF);
- // Log.d("mobeta",
- // "firstExp="+mFirstExpPos+" secExp="+mSecondExpPos+" slideFrac="+mSlideFrac);
- }
-
- } else {
- mFirstExpPos = itemPos;
- mSecondExpPos = itemPos;
- }
-
- // correct for headers and footers
- if (mFirstExpPos < numHeaders) {
- itemPos = numHeaders;
- mFirstExpPos = itemPos;
- mSecondExpPos = itemPos;
- } else if (mSecondExpPos >= getCount() - numFooters) {
- itemPos = getCount() - numFooters - 1;
- mFirstExpPos = itemPos;
- mSecondExpPos = itemPos;
- }
-
- if (mFirstExpPos != oldFirstExpPos || mSecondExpPos != oldSecondExpPos
- || mSlideFrac != oldSlideFrac) {
- updated = true;
- }
-
- if (itemPos != mFloatPos) {
- if (mDragListener != null) {
- mDragListener.drag(mFloatPos - numHeaders, itemPos - numHeaders);
- }
-
- mFloatPos = itemPos;
- updated = true;
- }
-
- return updated;
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
-
- if (mTrackDragSort) {
- mDragSortTracker.appendState();
- }
- }
-
- private class SmoothAnimator implements Runnable {
- protected long mStartTime;
-
- private float mDurationF;
-
- private float mAlpha;
- private float mA, mB, mC, mD;
-
- private boolean mCanceled;
-
- public SmoothAnimator(float smoothness, int duration) {
- mAlpha = smoothness;
- mDurationF = (float) duration;
- mA = mD = 1f / (2f * mAlpha * (1f - mAlpha));
- mB = mAlpha / (2f * (mAlpha - 1f));
- mC = 1f / (1f - mAlpha);
- }
-
- public float transform(float frac) {
- if (frac < mAlpha) {
- return mA * frac * frac;
- } else if (frac < 1f - mAlpha) {
- return mB + mC * frac;
- } else {
- return 1f - mD * (frac - 1f) * (frac - 1f);
- }
- }
-
- public void start() {
- mStartTime = SystemClock.uptimeMillis();
- mCanceled = false;
- onStart();
- post(this);
- }
-
- public void cancel() {
- mCanceled = true;
- }
-
- public void onStart() {
- // stub
- }
-
- public void onUpdate(float frac, float smoothFrac) {
- // stub
- }
-
- public void onStop() {
- // stub
- }
-
- @Override
- public void run() {
- if (mCanceled) {
- return;
- }
-
- float fraction = ((float) (SystemClock.uptimeMillis() - mStartTime)) / mDurationF;
-
- if (fraction >= 1f) {
- onUpdate(1f, 1f);
- onStop();
- } else {
- onUpdate(fraction, transform(fraction));
- post(this);
- }
- }
- }
-
- /**
- * Centers floating View under touch point.
- */
- private class LiftAnimator extends SmoothAnimator {
-
- private float mInitDragDeltaY;
- private float mFinalDragDeltaY;
-
- public LiftAnimator(float smoothness, int duration) {
- super(smoothness, duration);
- }
-
- @Override
- public void onStart() {
- mInitDragDeltaY = mDragDeltaY;
- mFinalDragDeltaY = mFloatViewHeightHalf;
- }
-
- @Override
- public void onUpdate(float frac, float smoothFrac) {
- if (mDragState != DRAGGING) {
- cancel();
- } else {
- mDragDeltaY = (int) (smoothFrac * mFinalDragDeltaY + (1f - smoothFrac)
- * mInitDragDeltaY);
- mFloatLoc.y = mY - mDragDeltaY;
- doDragFloatView(true);
- }
- }
- }
-
- /**
- * Centers floating View over drop slot before destroying.
- */
- private class DropAnimator extends SmoothAnimator {
-
- private int mDropPos;
- private int srcPos;
- private float mInitDeltaY;
- private float mInitDeltaX;
-
- public DropAnimator(float smoothness, int duration) {
- super(smoothness, duration);
- }
-
- @Override
- public void onStart() {
- mDropPos = mFloatPos;
- srcPos = mSrcPos;
- mDragState = DROPPING;
- mInitDeltaY = mFloatLoc.y - getTargetY();
- mInitDeltaX = mFloatLoc.x - getPaddingLeft();
- }
-
- private int getTargetY() {
- final int first = getFirstVisiblePosition();
- final int otherAdjust = (mItemHeightCollapsed + getDividerHeight()) / 2;
- View v = getChildAt(mDropPos - first);
- int targetY = -1;
- if (v != null) {
- if (mDropPos == srcPos) {
- targetY = v.getTop();
- } else if (mDropPos < srcPos) {
- // expanded down
- targetY = v.getTop() - otherAdjust;
- } else {
- // expanded up
- targetY = v.getBottom() + otherAdjust - mFloatViewHeight;
- }
- } else {
- // drop position is not on screen?? no animation
- cancel();
- }
-
- return targetY;
- }
-
- @Override
- public void onUpdate(float frac, float smoothFrac) {
- final int targetY = getTargetY();
- final int targetX = getPaddingLeft();
- final float deltaY = mFloatLoc.y - targetY;
- final float deltaX = mFloatLoc.x - targetX;
- final float f = 1f - smoothFrac;
- if (f < Math.abs(deltaY / mInitDeltaY) || f < Math.abs(deltaX / mInitDeltaX)) {
- mFloatLoc.y = targetY + (int) (mInitDeltaY * f);
- mFloatLoc.x = getPaddingLeft() + (int) (mInitDeltaX * f);
- doDragFloatView(true);
- }
- }
-
- @Override
- public void onStop() {
- dropFloatView();
- }
-
- }
-
- /**
- * Collapses expanded items.
- */
- private class RemoveAnimator extends SmoothAnimator {
-
- private float mFloatLocX;
- private float mFirstStartBlank;
- private float mSecondStartBlank;
-
- private int mFirstChildHeight = -1;
- private int mSecondChildHeight = -1;
-
- private int mFirstPos;
- private int mSecondPos;
- private int srcPos;
-
- public RemoveAnimator(float smoothness, int duration) {
- super(smoothness, duration);
- }
-
- @Override
- public void onStart() {
- mFirstChildHeight = -1;
- mSecondChildHeight = -1;
- mFirstPos = mFirstExpPos;
- mSecondPos = mSecondExpPos;
- srcPos = mSrcPos;
- mDragState = REMOVING;
-
- mFloatLocX = mFloatLoc.x;
- if (mUseRemoveVelocity) {
- float minVelocity = 2f * getWidth();
- if (mRemoveVelocityX == 0) {
- mRemoveVelocityX = (mFloatLocX < 0 ? -1 : 1) * minVelocity;
- } else {
- minVelocity *= 2;
- if (mRemoveVelocityX < 0 && mRemoveVelocityX > -minVelocity)
- mRemoveVelocityX = -minVelocity;
- else if (mRemoveVelocityX > 0 && mRemoveVelocityX < minVelocity)
- mRemoveVelocityX = minVelocity;
- }
- } else {
- destroyFloatView();
- }
- }
-
- @Override
- public void onUpdate(float frac, float smoothFrac) {
- float f = 1f - smoothFrac;
-
- final int firstVis = getFirstVisiblePosition();
- View item = getChildAt(mFirstPos - firstVis);
- ViewGroup.LayoutParams lp;
- int blank;
-
- if (mUseRemoveVelocity) {
- float dt = (float) (SystemClock.uptimeMillis() - mStartTime) / 1000;
- if (dt == 0)
- return;
- float dx = mRemoveVelocityX * dt;
- int w = getWidth();
- mRemoveVelocityX += (mRemoveVelocityX > 0 ? 1 : -1) * dt * w;
- mFloatLocX += dx;
- mFloatLoc.x = (int) mFloatLocX;
- if (mFloatLocX < w && mFloatLocX > -w) {
- mStartTime = SystemClock.uptimeMillis();
- doDragFloatView(true);
- return;
- }
- }
-
- if (item != null) {
- if (mFirstChildHeight == -1) {
- mFirstChildHeight = getChildHeight(mFirstPos, item, false);
- mFirstStartBlank = (float) (item.getHeight() - mFirstChildHeight);
- }
- blank = Math.max((int) (f * mFirstStartBlank), 1);
- lp = item.getLayoutParams();
- lp.height = mFirstChildHeight + blank;
- item.setLayoutParams(lp);
- }
- if (mSecondPos != mFirstPos) {
- item = getChildAt(mSecondPos - firstVis);
- if (item != null) {
- if (mSecondChildHeight == -1) {
- mSecondChildHeight = getChildHeight(mSecondPos, item, false);
- mSecondStartBlank = (float) (item.getHeight() - mSecondChildHeight);
- }
- blank = Math.max((int) (f * mSecondStartBlank), 1);
- lp = item.getLayoutParams();
- lp.height = mSecondChildHeight + blank;
- item.setLayoutParams(lp);
- }
- }
- }
-
- @Override
- public void onStop() {
- doRemoveItem();
- }
- }
-
- public void removeItem(int which) {
-
- mUseRemoveVelocity = false;
- removeItem(which, 0);
- }
-
- /**
- * Removes an item from the list and animates the removal.
- *
- * @param which Position to remove (NOTE: headers/footers ignored!
- * this is a position in your input ListAdapter).
- * @param velocityX
- */
- public void removeItem(int which, float velocityX) {
- if (mDragState == IDLE || mDragState == DRAGGING) {
-
- if (mDragState == IDLE) {
- // called from outside drag-sort
- mSrcPos = getHeaderViewsCount() + which;
- mFirstExpPos = mSrcPos;
- mSecondExpPos = mSrcPos;
- mFloatPos = mSrcPos;
- View v = getChildAt(mSrcPos - getFirstVisiblePosition());
- if (v != null) {
- v.setVisibility(View.INVISIBLE);
- }
- }
-
- mDragState = REMOVING;
- mRemoveVelocityX = velocityX;
-
- if (mInTouchEvent) {
- switch (mCancelMethod) {
- case ON_TOUCH_EVENT:
- super.onTouchEvent(mCancelEvent);
- break;
- case ON_INTERCEPT_TOUCH_EVENT:
- super.onInterceptTouchEvent(mCancelEvent);
- break;
- }
- }
-
- if (mRemoveAnimator != null) {
- mRemoveAnimator.start();
- } else {
- doRemoveItem(which);
- }
- }
- }
-
- /**
- * Move an item, bypassing the drag-sort process. Simply calls
- * through to {@link DropListener#drop(int, int)}.
- *
- * @param from Position to move (NOTE: headers/footers ignored!
- * this is a position in your input ListAdapter).
- * @param to Target position (NOTE: headers/footers ignored!
- * this is a position in your input ListAdapter).
- */
- public void moveItem(int from, int to) {
- if (mDropListener != null) {
- final int count = getInputAdapter().getCount();
- if (from >= 0 && from < count && to >= 0 && to < count) {
- mDropListener.drop(from, to);
- }
- }
- }
-
- /**
- * Cancel a drag. Calls {@link #stopDrag(boolean, boolean)} with
- * <code>true</code> as the first argument.
- */
- public void cancelDrag() {
- if (mDragState == DRAGGING) {
- mDragScroller.stopScrolling(true);
- destroyFloatView();
- clearPositions();
- adjustAllItems();
-
- if (mInTouchEvent) {
- mDragState = STOPPED;
- } else {
- mDragState = IDLE;
- }
- }
- }
-
- private void clearPositions() {
- mSrcPos = -1;
- mFirstExpPos = -1;
- mSecondExpPos = -1;
- mFloatPos = -1;
- }
-
- private void dropFloatView() {
- // must set to avoid cancelDrag being called from the
- // DataSetObserver
- mDragState = DROPPING;
-
- if (mDropListener != null && mFloatPos >= 0 && mFloatPos < getCount()) {
- final int numHeaders = getHeaderViewsCount();
- mDropListener.drop(mSrcPos - numHeaders, mFloatPos - numHeaders);
- }
-
- destroyFloatView();
-
- adjustOnReorder();
- clearPositions();
- adjustAllItems();
-
- // now the drag is done
- if (mInTouchEvent) {
- mDragState = STOPPED;
- } else {
- mDragState = IDLE;
- }
- }
-
- private void doRemoveItem() {
- doRemoveItem(mSrcPos - getHeaderViewsCount());
- }
-
- /**
- * Removes dragged item from the list. Calls RemoveListener.
- */
- private void doRemoveItem(int which) {
- // must set to avoid cancelDrag being called from the
- // DataSetObserver
- mDragState = REMOVING;
-
- // end it
- if (mRemoveListener != null) {
- mRemoveListener.remove(which);
- }
-
- destroyFloatView();
-
- adjustOnReorder();
- clearPositions();
-
- // now the drag is done
- if (mInTouchEvent) {
- mDragState = STOPPED;
- } else {
- mDragState = IDLE;
- }
- }
-
- private void adjustOnReorder() {
- final int firstPos = getFirstVisiblePosition();
- // Log.d("mobeta", "first="+firstPos+" src="+mSrcPos);
- if (mSrcPos < firstPos) {
- // collapsed src item is off screen;
- // adjust the scroll after item heights have been fixed
- View v = getChildAt(0);
- int top = 0;
- if (v != null) {
- top = v.getTop();
- }
- // Log.d("mobeta", "top="+top+" fvh="+mFloatViewHeight);
- setSelectionFromTop(firstPos - 1, top - getPaddingTop());
- }
- }
-
- /**
- * Stop a drag in progress. Pass <code>true</code> if you would
- * like to remove the dragged item from the list.
- *
- * @param remove Remove the dragged item from the list. Calls
- * a registered RemoveListener, if one exists. Otherwise, calls
- * the DropListener, if one exists.
- *
- * @return True if the stop was successful. False if there is
- * no floating View.
- */
- public boolean stopDrag(boolean remove) {
- mUseRemoveVelocity = false;
- return stopDrag(remove, 0);
- }
-
- public boolean stopDragWithVelocity(boolean remove, float velocityX) {
-
- mUseRemoveVelocity = true;
- return stopDrag(remove, velocityX);
- }
-
- public boolean stopDrag(boolean remove, float velocityX) {
- if (mFloatView != null) {
- mDragScroller.stopScrolling(true);
-
- if (remove) {
- removeItem(mSrcPos - getHeaderViewsCount(), velocityX);
- } else {
- if (mDropAnimator != null) {
- mDropAnimator.start();
- } else {
- dropFloatView();
- }
- }
-
- if (mTrackDragSort) {
- mDragSortTracker.stopTracking();
- }
-
- return true;
- } else {
- // stop failed
- return false;
- }
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- if (mIgnoreTouchEvent) {
- mIgnoreTouchEvent = false;
- return false;
- }
-
- if (!mDragEnabled) {
- return super.onTouchEvent(ev);
- }
-
- boolean more = false;
-
- boolean lastCallWasIntercept = mLastCallWasIntercept;
- mLastCallWasIntercept = false;
-
- if (!lastCallWasIntercept) {
- saveTouchCoords(ev);
- }
-
- // if (mFloatView != null) {
- if (mDragState == DRAGGING) {
- onDragTouchEvent(ev);
- more = true; // give us more!
- } else {
- // what if float view is null b/c we dropped in middle
- // of drag touch event?
-
- // if (mDragState != STOPPED) {
- if (mDragState == IDLE) {
- if (super.onTouchEvent(ev)) {
- more = true;
- }
- }
-
- int action = ev.getAction() & MotionEvent.ACTION_MASK;
-
- switch (action) {
- case MotionEvent.ACTION_CANCEL:
- case MotionEvent.ACTION_UP:
- doActionUpOrCancel();
- break;
- default:
- if (more) {
- mCancelMethod = ON_TOUCH_EVENT;
- }
- }
- }
-
- return more;
- }
-
- private void doActionUpOrCancel() {
- mCancelMethod = NO_CANCEL;
- mInTouchEvent = false;
- if (mDragState == STOPPED) {
- mDragState = IDLE;
- }
- mCurrFloatAlpha = mFloatAlpha;
- mListViewIntercepted = false;
- mChildHeightCache.clear();
- }
-
- private void saveTouchCoords(MotionEvent ev) {
- int action = ev.getAction() & MotionEvent.ACTION_MASK;
- if (action != MotionEvent.ACTION_DOWN) {
- mLastX = mX;
- mLastY = mY;
- }
- mX = (int) ev.getX();
- mY = (int) ev.getY();
- if (action == MotionEvent.ACTION_DOWN) {
- mLastX = mX;
- mLastY = mY;
- }
- mOffsetX = (int) ev.getRawX() - mX;
- mOffsetY = (int) ev.getRawY() - mY;
- }
-
- public boolean listViewIntercepted() {
- return mListViewIntercepted;
- }
-
- private boolean mListViewIntercepted = false;
-
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- if (!mDragEnabled) {
- return super.onInterceptTouchEvent(ev);
- }
-
- saveTouchCoords(ev);
- mLastCallWasIntercept = true;
-
- int action = ev.getAction() & MotionEvent.ACTION_MASK;
-
- if (action == MotionEvent.ACTION_DOWN) {
- if (mDragState != IDLE) {
- // intercept and ignore
- mIgnoreTouchEvent = true;
- return true;
- }
- mInTouchEvent = true;
- }
-
- boolean intercept = false;
-
- // the following deals with calls to super.onInterceptTouchEvent
- if (mFloatView != null) {
- // super's touch event canceled in startDrag
- intercept = true;
- } else {
- if (super.onInterceptTouchEvent(ev)) {
- mListViewIntercepted = true;
- intercept = true;
- }
-
- switch (action) {
- case MotionEvent.ACTION_CANCEL:
- case MotionEvent.ACTION_UP:
- doActionUpOrCancel();
- break;
- default:
- if (intercept) {
- mCancelMethod = ON_TOUCH_EVENT;
- } else {
- mCancelMethod = ON_INTERCEPT_TOUCH_EVENT;
- }
- }
- }
-
- if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
- mInTouchEvent = false;
- }
-
- return intercept;
- }
-
- /**
- * Set the width of each drag scroll region by specifying
- * a fraction of the ListView height.
- *
- * @param heightFraction Fraction of ListView height. Capped at
- * 0.5f.
- *
- */
- public void setDragScrollStart(float heightFraction) {
- setDragScrollStarts(heightFraction, heightFraction);
- }
-
- /**
- * Set the width of each drag scroll region by specifying
- * a fraction of the ListView height.
- *
- * @param upperFrac Fraction of ListView height for up-scroll bound.
- * Capped at 0.5f.
- * @param lowerFrac Fraction of ListView height for down-scroll bound.
- * Capped at 0.5f.
- *
- */
- public void setDragScrollStarts(float upperFrac, float lowerFrac) {
- if (lowerFrac > 0.5f) {
- mDragDownScrollStartFrac = 0.5f;
- } else {
- mDragDownScrollStartFrac = lowerFrac;
- }
-
- if (upperFrac > 0.5f) {
- mDragUpScrollStartFrac = 0.5f;
- } else {
- mDragUpScrollStartFrac = upperFrac;
- }
-
- if (getHeight() != 0) {
- updateScrollStarts();
- }
- }
-
- private void continueDrag(int x, int y) {
-
- // proposed position
- mFloatLoc.x = x - mDragDeltaX;
- mFloatLoc.y = y - mDragDeltaY;
-
- doDragFloatView(true);
-
- int minY = Math.min(y, mFloatViewMid + mFloatViewHeightHalf);
- int maxY = Math.max(y, mFloatViewMid - mFloatViewHeightHalf);
-
- // get the current scroll direction
- int currentScrollDir = mDragScroller.getScrollDir();
-
- if (minY > mLastY && minY > mDownScrollStartY && currentScrollDir != DragScroller.DOWN) {
- // dragged down, it is below the down scroll start and it is not
- // scrolling up
-
- if (currentScrollDir != DragScroller.STOP) {
- // moved directly from up scroll to down scroll
- mDragScroller.stopScrolling(true);
- }
-
- // start scrolling down
- mDragScroller.startScrolling(DragScroller.DOWN);
- } else if (maxY < mLastY && maxY < mUpScrollStartY && currentScrollDir != DragScroller.UP) {
- // dragged up, it is above the up scroll start and it is not
- // scrolling up
-
- if (currentScrollDir != DragScroller.STOP) {
- // moved directly from down scroll to up scroll
- mDragScroller.stopScrolling(true);
- }
-
- // start scrolling up
- mDragScroller.startScrolling(DragScroller.UP);
- }
- else if (maxY >= mUpScrollStartY && minY <= mDownScrollStartY
- && mDragScroller.isScrolling()) {
- // not in the upper nor in the lower drag-scroll regions but it is
- // still scrolling
-
- mDragScroller.stopScrolling(true);
- }
- }
-
- private void updateScrollStarts() {
- final int padTop = getPaddingTop();
- final int listHeight = getHeight() - padTop - getPaddingBottom();
- float heightF = (float) listHeight;
-
- mUpScrollStartYF = padTop + mDragUpScrollStartFrac * heightF;
- mDownScrollStartYF = padTop + (1.0f - mDragDownScrollStartFrac) * heightF;
-
- mUpScrollStartY = (int) mUpScrollStartYF;
- mDownScrollStartY = (int) mDownScrollStartYF;
-
- mDragUpScrollHeight = mUpScrollStartYF - padTop;
- mDragDownScrollHeight = padTop + listHeight - mDownScrollStartYF;
- }
-
- @Override
- protected void onSizeChanged(int w, int h, int oldw, int oldh) {
- super.onSizeChanged(w, h, oldw, oldh);
- updateScrollStarts();
- }
-
- private void adjustAllItems() {
- final int first = getFirstVisiblePosition();
- final int last = getLastVisiblePosition();
-
- int begin = Math.max(0, getHeaderViewsCount() - first);
- int end = Math.min(last - first, getCount() - 1 - getFooterViewsCount() - first);
-
- for (int i = begin; i <= end; ++i) {
- View v = getChildAt(i);
- if (v != null) {
- adjustItem(first + i, v, false);
- }
- }
- }
-
- private void adjustItem(int position) {
- View v = getChildAt(position - getFirstVisiblePosition());
-
- if (v != null) {
- adjustItem(position, v, false);
- }
- }
-
- /**
- * Sets layout param height, gravity, and visibility on
- * wrapped item.
- */
- private void adjustItem(int position, View v, boolean invalidChildHeight) {
-
- // Adjust item height
- ViewGroup.LayoutParams lp = v.getLayoutParams();
- int height;
- if (position != mSrcPos && position != mFirstExpPos && position != mSecondExpPos) {
- height = ViewGroup.LayoutParams.WRAP_CONTENT;
- } else {
- height = calcItemHeight(position, v, invalidChildHeight);
- }
-
- if (height != lp.height) {
- lp.height = height;
- v.setLayoutParams(lp);
- }
-
- // Adjust item gravity
- if (position == mFirstExpPos || position == mSecondExpPos) {
- if (position < mSrcPos) {
- ((DragSortItemView) v).setGravity(Gravity.BOTTOM);
- } else if (position > mSrcPos) {
- ((DragSortItemView) v).setGravity(Gravity.TOP);
- }
- }
-
- // Finally adjust item visibility
-
- int oldVis = v.getVisibility();
- int vis = View.VISIBLE;
-
- if (position == mSrcPos && mFloatView != null) {
- vis = View.INVISIBLE;
- }
-
- if (vis != oldVis) {
- v.setVisibility(vis);
- }
- }
-
- private int getChildHeight(int position) {
- if (position == mSrcPos) {
- return 0;
- }
-
- View v = getChildAt(position - getFirstVisiblePosition());
-
- if (v != null) {
- // item is onscreen, therefore child height is valid,
- // hence the "true"
- return getChildHeight(position, v, false);
- } else {
- // item is offscreen
- // first check cache for child height at this position
- int childHeight = mChildHeightCache.get(position);
- if (childHeight != -1) {
- // Log.d("mobeta", "found child height in cache!");
- return childHeight;
- }
-
- final ListAdapter adapter = getAdapter();
- int type = adapter.getItemViewType(position);
-
- // There might be a better place for checking for the following
- final int typeCount = adapter.getViewTypeCount();
- if (typeCount != mSampleViewTypes.length) {
- mSampleViewTypes = new View[typeCount];
- }
-
- if (type >= 0) {
- if (mSampleViewTypes[type] == null) {
- v = adapter.getView(position, null, this);
- mSampleViewTypes[type] = v;
- } else {
- v = adapter.getView(position, mSampleViewTypes[type], this);
- }
- } else {
- // type is HEADER_OR_FOOTER or IGNORE
- v = adapter.getView(position, null, this);
- }
-
- // current child height is invalid, hence "true" below
- childHeight = getChildHeight(position, v, true);
-
- // cache it because this could have been expensive
- mChildHeightCache.add(position, childHeight);
-
- return childHeight;
- }
- }
-
- private int getChildHeight(int position, View item, boolean invalidChildHeight) {
- if (position == mSrcPos) {
- return 0;
- }
-
- View child;
- if (position < getHeaderViewsCount() || position >= getCount() - getFooterViewsCount()) {
- child = item;
- } else {
- child = ((ViewGroup) item).getChildAt(0);
- }
-
- ViewGroup.LayoutParams lp = child.getLayoutParams();
-
- if (lp != null) {
- if (lp.height > 0) {
- return lp.height;
- }
- }
-
- int childHeight = child.getHeight();
-
- if (childHeight == 0 || invalidChildHeight) {
- measureItem(child);
- childHeight = child.getMeasuredHeight();
- }
-
- return childHeight;
- }
-
- private int calcItemHeight(int position, View item, boolean invalidChildHeight) {
- return calcItemHeight(position, getChildHeight(position, item, invalidChildHeight));
- }
-
- private int calcItemHeight(int position, int childHeight) {
-
- int divHeight = getDividerHeight();
-
- boolean isSliding = mAnimate && mFirstExpPos != mSecondExpPos;
- int maxNonSrcBlankHeight = mFloatViewHeight - mItemHeightCollapsed;
- int slideHeight = (int) (mSlideFrac * maxNonSrcBlankHeight);
-
- int height;
-
- if (position == mSrcPos) {
- if (mSrcPos == mFirstExpPos) {
- if (isSliding) {
- height = slideHeight + mItemHeightCollapsed;
- } else {
- height = mFloatViewHeight;
- }
- } else if (mSrcPos == mSecondExpPos) {
- // if gets here, we know an item is sliding
- height = mFloatViewHeight - slideHeight;
- } else {
- height = mItemHeightCollapsed;
- }
- } else if (position == mFirstExpPos) {
- if (isSliding) {
- height = childHeight + slideHeight;
- } else {
- height = childHeight + maxNonSrcBlankHeight;
- }
- } else if (position == mSecondExpPos) {
- // we know an item is sliding (b/c 2ndPos != 1stPos)
- height = childHeight + maxNonSrcBlankHeight - slideHeight;
- } else {
- height = childHeight;
- }
-
- return height;
- }
-
- @Override
- public void requestLayout() {
- if (!mBlockLayoutRequests) {
- super.requestLayout();
- }
- }
-
- private int adjustScroll(int movePos, View moveItem, int oldFirstExpPos, int oldSecondExpPos) {
- int adjust = 0;
-
- final int childHeight = getChildHeight(movePos);
-
- int moveHeightBefore = moveItem.getHeight();
- int moveHeightAfter = calcItemHeight(movePos, childHeight);
-
- int moveBlankBefore = moveHeightBefore;
- int moveBlankAfter = moveHeightAfter;
- if (movePos != mSrcPos) {
- moveBlankBefore -= childHeight;
- moveBlankAfter -= childHeight;
- }
-
- int maxBlank = mFloatViewHeight;
- if (mSrcPos != mFirstExpPos && mSrcPos != mSecondExpPos) {
- maxBlank -= mItemHeightCollapsed;
- }
-
- if (movePos <= oldFirstExpPos) {
- if (movePos > mFirstExpPos) {
- adjust += maxBlank - moveBlankAfter;
- }
- } else if (movePos == oldSecondExpPos) {
- if (movePos <= mFirstExpPos) {
- adjust += moveBlankBefore - maxBlank;
- } else if (movePos == mSecondExpPos) {
- adjust += moveHeightBefore - moveHeightAfter;
- } else {
- adjust += moveBlankBefore;
- }
- } else {
- if (movePos <= mFirstExpPos) {
- adjust -= maxBlank;
- } else if (movePos == mSecondExpPos) {
- adjust -= moveBlankAfter;
- }
- }
-
- return adjust;
- }
-
- private void measureItem(View item) {
- ViewGroup.LayoutParams lp = item.getLayoutParams();
- if (lp == null) {
- lp = new AbsListView.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
- item.setLayoutParams(lp);
- }
- int wspec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec, getListPaddingLeft()
- + getListPaddingRight(), lp.width);
- int hspec;
- if (lp.height > 0) {
- hspec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
- } else {
- hspec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
- }
- item.measure(wspec, hspec);
- }
-
- private void measureFloatView() {
- if (mFloatView != null) {
- measureItem(mFloatView);
- mFloatViewHeight = mFloatView.getMeasuredHeight();
- mFloatViewHeightHalf = mFloatViewHeight / 2;
- }
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- // Log.d("mobeta", "onMeasure called");
- if (mFloatView != null) {
- if (mFloatView.isLayoutRequested()) {
- measureFloatView();
- }
- mFloatViewOnMeasured = true; // set to false after layout
- }
- mWidthMeasureSpec = widthMeasureSpec;
- }
-
- @Override
- protected void layoutChildren() {
- super.layoutChildren();
-
- if (mFloatView != null) {
- if (mFloatView.isLayoutRequested() && !mFloatViewOnMeasured) {
- // Have to measure here when usual android measure
- // pass is skipped. This happens during a drag-sort
- // when layoutChildren is called directly.
- measureFloatView();
- }
- mFloatView.layout(0, 0, mFloatView.getMeasuredWidth(), mFloatView.getMeasuredHeight());
- mFloatViewOnMeasured = false;
- }
- }
-
- protected boolean onDragTouchEvent(MotionEvent ev) {
- // we are in a drag
- int action = ev.getAction() & MotionEvent.ACTION_MASK;
-
- switch (ev.getAction() & MotionEvent.ACTION_MASK) {
- case MotionEvent.ACTION_CANCEL:
- if (mDragState == DRAGGING) {
- cancelDrag();
- }
- doActionUpOrCancel();
- break;
- case MotionEvent.ACTION_UP:
- // Log.d("mobeta", "calling stopDrag from onDragTouchEvent");
- if (mDragState == DRAGGING) {
- stopDrag(false);
- }
- doActionUpOrCancel();
- break;
- case MotionEvent.ACTION_MOVE:
- continueDrag((int) ev.getX(), (int) ev.getY());
- break;
- }
-
- return true;
- }
-
- private boolean mFloatViewInvalidated = false;
-
- private void invalidateFloatView() {
- mFloatViewInvalidated = true;
- }
-
- /**
- * Start a drag of item at <code>position</code> using the
- * registered FloatViewManager. Calls through
- * to {@link #startDrag(int,View,int,int,int)} after obtaining
- * the floating View from the FloatViewManager.
- *
- * @param position Item to drag.
- * @param dragFlags Flags that restrict some movements of the
- * floating View. For example, set <code>dragFlags |=
- * ~{@link #DRAG_NEG_X}</code> to allow dragging the floating
- * View in all directions except off the screen to the left.
- * @param deltaX Offset in x of the touch coordinate from the
- * left edge of the floating View (i.e. touch-x minus float View
- * left).
- * @param deltaY Offset in y of the touch coordinate from the
- * top edge of the floating View (i.e. touch-y minus float View
- * top).
- *
- * @return True if the drag was started, false otherwise. This
- * <code>startDrag</code> will fail if we are not currently in
- * a touch event, there is no registered FloatViewManager,
- * or the FloatViewManager returns a null View.
- */
- public boolean startDrag(int position, int dragFlags, int deltaX, int deltaY) {
- if (!mInTouchEvent || mFloatViewManager == null) {
- return false;
- }
-
- View v = mFloatViewManager.onCreateFloatView(position);
-
- if (v == null) {
- return false;
- } else {
- return startDrag(position, v, dragFlags, deltaX, deltaY);
- }
-
- }
-
- /**
- * Start a drag of item at <code>position</code> without using
- * a FloatViewManager.
- *
- * @param position Item to drag.
- * @param floatView Floating View.
- * @param dragFlags Flags that restrict some movements of the
- * floating View. For example, set <code>dragFlags |=
- * ~{@link #DRAG_NEG_X}</code> to allow dragging the floating
- * View in all directions except off the screen to the left.
- * @param deltaX Offset in x of the touch coordinate from the
- * left edge of the floating View (i.e. touch-x minus float View
- * left).
- * @param deltaY Offset in y of the touch coordinate from the
- * top edge of the floating View (i.e. touch-y minus float View
- * top).
- *
- * @return True if the drag was started, false otherwise. This
- * <code>startDrag</code> will fail if we are not currently in
- * a touch event, <code>floatView</code> is null, or there is
- * a drag in progress.
- */
- public boolean startDrag(int position, View floatView, int dragFlags, int deltaX, int deltaY) {
- if (mDragState != IDLE || !mInTouchEvent || mFloatView != null || floatView == null
- || !mDragEnabled) {
- return false;
- }
-
- if (getParent() != null) {
- getParent().requestDisallowInterceptTouchEvent(true);
- }
-
- int pos = position + getHeaderViewsCount();
- mFirstExpPos = pos;
- mSecondExpPos = pos;
- mSrcPos = pos;
- mFloatPos = pos;
-
- // mDragState = dragType;
- mDragState = DRAGGING;
- mDragFlags = 0;
- mDragFlags |= dragFlags;
-
- mFloatView = floatView;
- measureFloatView(); // sets mFloatViewHeight
-
- mDragDeltaX = deltaX;
- mDragDeltaY = deltaY;
- mDragStartY = mY;
-
- // updateFloatView(mX - mDragDeltaX, mY - mDragDeltaY);
- mFloatLoc.x = mX - mDragDeltaX;
- mFloatLoc.y = mY - mDragDeltaY;
-
- // set src item invisible
- final View srcItem = getChildAt(mSrcPos - getFirstVisiblePosition());
-
- if (srcItem != null) {
- srcItem.setVisibility(View.INVISIBLE);
- }
-
- if (mTrackDragSort) {
- mDragSortTracker.startTracking();
- }
-
- // once float view is created, events are no longer passed
- // to ListView
- switch (mCancelMethod) {
- case ON_TOUCH_EVENT:
- super.onTouchEvent(mCancelEvent);
- break;
- case ON_INTERCEPT_TOUCH_EVENT:
- super.onInterceptTouchEvent(mCancelEvent);
- break;
- }
-
- requestLayout();
-
- if (mLiftAnimator != null) {
- mLiftAnimator.start();
- }
-
- return true;
- }
-
- private void doDragFloatView(boolean forceInvalidate) {
- int movePos = getFirstVisiblePosition() + getChildCount() / 2;
- View moveItem = getChildAt(getChildCount() / 2);
-
- if (moveItem == null) {
- return;
- }
-
- doDragFloatView(movePos, moveItem, forceInvalidate);
- }
-
- private void doDragFloatView(int movePos, View moveItem, boolean forceInvalidate) {
- mBlockLayoutRequests = true;
-
- updateFloatView();
-
- int oldFirstExpPos = mFirstExpPos;
- int oldSecondExpPos = mSecondExpPos;
-
- boolean updated = updatePositions();
-
- if (updated) {
- adjustAllItems();
- int scroll = adjustScroll(movePos, moveItem, oldFirstExpPos, oldSecondExpPos);
- // Log.d("mobeta", " adjust scroll="+scroll);
-
- setSelectionFromTop(movePos, moveItem.getTop() + scroll - getPaddingTop());
- layoutChildren();
- }
-
- if (updated || forceInvalidate) {
- invalidate();
- }
-
- mBlockLayoutRequests = false;
- }
-
- /**
- * Sets float View location based on suggested values and
- * constraints set in mDragFlags.
- */
- private void updateFloatView() {
-
- if (mFloatViewManager != null) {
- mTouchLoc.set(mX, mY);
- mFloatViewManager.onDragFloatView(mFloatView, mFloatLoc, mTouchLoc);
- }
-
- final int floatX = mFloatLoc.x;
- final int floatY = mFloatLoc.y;
-
- // restrict x motion
- int padLeft = getPaddingLeft();
- if ((mDragFlags & DRAG_POS_X) == 0 && floatX > padLeft) {
- mFloatLoc.x = padLeft;
- } else if ((mDragFlags & DRAG_NEG_X) == 0 && floatX < padLeft) {
- mFloatLoc.x = padLeft;
- }
-
- // keep floating view from going past bottom of last header view
- final int numHeaders = getHeaderViewsCount();
- final int numFooters = getFooterViewsCount();
- final int firstPos = getFirstVisiblePosition();
- final int lastPos = getLastVisiblePosition();
-
- // Log.d("mobeta",
- // "nHead="+numHeaders+" nFoot="+numFooters+" first="+firstPos+" last="+lastPos);
- int topLimit = getPaddingTop();
- if (firstPos < numHeaders) {
- topLimit = getChildAt(numHeaders - firstPos - 1).getBottom();
- }
- if ((mDragFlags & DRAG_NEG_Y) == 0) {
- if (firstPos <= mSrcPos) {
- topLimit = Math.max(getChildAt(mSrcPos - firstPos).getTop(), topLimit);
- }
- }
- // bottom limit is top of first footer View or
- // bottom of last item in list
- int bottomLimit = getHeight() - getPaddingBottom();
- if (lastPos >= getCount() - numFooters - 1) {
- bottomLimit = getChildAt(getCount() - numFooters - 1 - firstPos).getBottom();
- }
- if ((mDragFlags & DRAG_POS_Y) == 0) {
- if (lastPos >= mSrcPos) {
- bottomLimit = Math.min(getChildAt(mSrcPos - firstPos).getBottom(), bottomLimit);
- }
- }
-
- // Log.d("mobeta", "dragView top=" + (y - mDragDeltaY));
- // Log.d("mobeta", "limit=" + limit);
- // Log.d("mobeta", "mDragDeltaY=" + mDragDeltaY);
-
- if (floatY < topLimit) {
- mFloatLoc.y = topLimit;
- } else if (floatY + mFloatViewHeight > bottomLimit) {
- mFloatLoc.y = bottomLimit - mFloatViewHeight;
- }
-
- // get y-midpoint of floating view (constrained to ListView bounds)
- mFloatViewMid = mFloatLoc.y + mFloatViewHeightHalf;
- }
-
- private void destroyFloatView() {
- if (mFloatView != null) {
- mFloatView.setVisibility(GONE);
- if (mFloatViewManager != null) {
- mFloatViewManager.onDestroyFloatView(mFloatView);
- }
- mFloatView = null;
- invalidate();
- }
- }
-
- /**
- * Interface for customization of the floating View appearance
- * and dragging behavior. Implement
- * your own and pass it to {@link #setFloatViewManager}. If
- * your own is not passed, the default {@link SimpleFloatViewManager}
- * implementation is used.
- */
- public interface FloatViewManager {
- /**
- * Return the floating View for item at <code>position</code>.
- * DragSortListView will measure and layout this View for you,
- * so feel free to just inflate it. You can help DSLV by
- * setting some {@link ViewGroup.LayoutParams} on this View;
- * otherwise it will set some for you (with a width of FILL_PARENT
- * and a height of WRAP_CONTENT).
- *
- * @param position Position of item to drag (NOTE:
- * <code>position</code> excludes header Views; thus, if you
- * want to call {@link ListView#getChildAt(int)}, you will need
- * to add {@link ListView#getHeaderViewsCount()} to the index).
- *
- * @return The View you wish to display as the floating View.
- */
- public View onCreateFloatView(int position);
-
- /**
- * Called whenever the floating View is dragged. Float View
- * properties can be changed here. Also, the upcoming location
- * of the float View can be altered by setting
- * <code>location.x</code> and <code>location.y</code>.
- *
- * @param floatView The floating View.
- * @param location The location (top-left; relative to DSLV
- * top-left) at which the float
- * View would like to appear, given the current touch location
- * and the offset provided in {@link DragSortListView#startDrag}.
- * @param touch The current touch location (relative to DSLV
- * top-left).
- * @param pendingScroll
- */
- public void onDragFloatView(View floatView, Point location, Point touch);
-
- /**
- * Called when the float View is dropped; lets you perform
- * any necessary cleanup. The internal DSLV floating View
- * reference is set to null immediately after this is called.
- *
- * @param floatView The floating View passed to
- * {@link #onCreateFloatView(int)}.
- */
- public void onDestroyFloatView(View floatView);
- }
-
- public void setFloatViewManager(FloatViewManager manager) {
- mFloatViewManager = manager;
- }
-
- public void setDragListener(DragListener l) {
- mDragListener = l;
- }
-
- /**
- * Allows for easy toggling between a DragSortListView
- * and a regular old ListView. If enabled, items are
- * draggable, where the drag init mode determines how
- * items are lifted (see {@link setDragInitMode(int)}).
- * If disabled, items cannot be dragged.
- *
- * @param enabled Set <code>true</code> to enable list
- * item dragging
- */
- public void setDragEnabled(boolean enabled) {
- mDragEnabled = enabled;
- }
-
- public boolean isDragEnabled() {
- return mDragEnabled;
- }
-
- /**
- * This better reorder your ListAdapter! DragSortListView does not do this
- * for you; doesn't make sense to. Make sure
- * {@link BaseAdapter#notifyDataSetChanged()} or something like it is called
- * in your implementation. Furthermore, if you have a choiceMode other than
- * none and the ListAdapter does not return true for
- * {@link ListAdapter#hasStableIds()}, you will need to call
- * {@link #moveCheckState(int, int)} to move the check boxes along with the
- * list items.
- *
- * @param l
- */
- public void setDropListener(DropListener l) {
- mDropListener = l;
- }
-
- /**
- * Probably a no-brainer, but make sure that your remove listener
- * calls {@link BaseAdapter#notifyDataSetChanged()} or something like it.
- * When an item removal occurs, DragSortListView
- * relies on a redraw of all the items to recover invisible views
- * and such. Strictly speaking, if you remove something, your dataset
- * has changed...
- *
- * @param l
- */
- public void setRemoveListener(RemoveListener l) {
- mRemoveListener = l;
- }
-
- public interface DragListener {
- public void drag(int from, int to);
- }
-
- /**
- * Your implementation of this has to reorder your ListAdapter!
- * Make sure to call
- * {@link BaseAdapter#notifyDataSetChanged()} or something like it
- * in your implementation.
- *
- * @author heycosmo
- *
- */
- public interface DropListener {
- public void drop(int from, int to);
- }
-
- /**
- * Make sure to call
- * {@link BaseAdapter#notifyDataSetChanged()} or something like it
- * in your implementation.
- *
- * @author heycosmo
- *
- */
- public interface RemoveListener {
- public void remove(int which);
- }
-
- public interface DragSortListener extends DropListener, DragListener, RemoveListener {
- }
-
- public void setDragSortListener(DragSortListener l) {
- setDropListener(l);
- setDragListener(l);
- setRemoveListener(l);
- }
-
- /**
- * Completely custom scroll speed profile. Default increases linearly
- * with position and is constant in time. Create your own by implementing
- * {@link DragSortListView.DragScrollProfile}.
- *
- * @param ssp
- */
- public void setDragScrollProfile(DragScrollProfile ssp) {
- if (ssp != null) {
- mScrollProfile = ssp;
- }
- }
-
- /**
- * Use this to move the check state of an item from one position to another
- * in a drop operation. If you have a choiceMode which is not none, this
- * method must be called when the order of items changes in an underlying
- * adapter which does not have stable IDs (see
- * {@link ListAdapter#hasStableIds()}). This is because without IDs, the
- * ListView has no way of knowing which items have moved where, and cannot
- * update the check state accordingly.
- * <p>
- * A word of warning about a "feature" in Android that you may run into when
- * dealing with movable list items: for an adapter that <em>does</em> have
- * stable IDs, ListView will attempt to locate each item based on its ID and
- * move the check state from the item's old position to the new position —
- * which is all fine and good (and removes the need for calling this
- * function), except for the half-baked approach. Apparently to save time in
- * the naive algorithm used, ListView will only search for an ID in the
- * close neighborhood of the old position. If the user moves an item too far
- * (specifically, more than 20 rows away), ListView will give up and just
- * force the item to be unchecked. So if there is a reasonable chance that
- * the user will move items more than 20 rows away from the original
- * position, you may wish to use an adapter with unstable IDs and call this
- * method manually instead.
- *
- * @param from
- * @param to
- */
- public void moveCheckState(int from, int to) {
- // This method runs in O(n log n) time (n being the number of list
- // items). The bottleneck is the call to AbsListView.setItemChecked,
- // which is O(log n) because of the binary search involved in calling
- // SparseBooleanArray.put().
- //
- // To improve on the average time, we minimize the number of calls to
- // setItemChecked by only calling it for items that actually have a
- // changed state. This is achieved by building a list containing the
- // start and end of the "runs" of checked items, and then moving the
- // runs. Note that moving an item from A to B is essentially a rotation
- // of the range of items in [A, B]. Let's say we have
- // . . U V X Y Z . .
- // and move U after Z. This is equivalent to a rotation one step to the
- // left within the range you are moving across:
- // . . V X Y Z U . .
- //
- // So, to perform the move we enumerate all the runs within the move
- // range, then rotate each run one step to the left or right (depending
- // on move direction). For example, in the list:
- // X X . X X X . X
- // we have two runs. One begins at the last item of the list and wraps
- // around to the beginning, ending at position 1. The second begins at
- // position 3 and ends at position 5. To rotate a run, regardless of
- // length, we only need to set a check mark at one end of the run, and
- // clear a check mark at the other end:
- // X . X X X . X X
- SparseBooleanArray cip = getCheckedItemPositions();
- int rangeStart = from;
- int rangeEnd = to;
- if (to < from) {
- rangeStart = to;
- rangeEnd = from;
- }
- rangeEnd += 1;
-
- int[] runStart = new int[cip.size()];
- int[] runEnd = new int[cip.size()];
- int runCount = buildRunList(cip, rangeStart, rangeEnd, runStart, runEnd);
- if (runCount == 1 && (runStart[0] == runEnd[0])) {
- // Special case where all items are checked, we can never set any
- // item to false like we do below.
- return;
- }
-
- if (from < to) {
- for (int i = 0; i != runCount; i++) {
- setItemChecked(rotate(runStart[i], -1, rangeStart, rangeEnd), true);
- setItemChecked(rotate(runEnd[i], -1, rangeStart, rangeEnd), false);
- }
-
- } else {
- for (int i = 0; i != runCount; i++) {
- setItemChecked(runStart[i], false);
- setItemChecked(runEnd[i], true);
- }
- }
- }
-
- /**
- * Use this when an item has been deleted, to move the check state of all
- * following items up one step. If you have a choiceMode which is not none,
- * this method must be called when the order of items changes in an
- * underlying adapter which does not have stable IDs (see
- * {@link ListAdapter#hasStableIds()}). This is because without IDs, the
- * ListView has no way of knowing which items have moved where, and cannot
- * update the check state accordingly.
- *
- * See also further comments on {@link #moveCheckState(int, int)}.
- *
- * @param position
- */
- public void removeCheckState(int position) {
- SparseBooleanArray cip = getCheckedItemPositions();
-
- if (cip.size() == 0)
- return;
- int[] runStart = new int[cip.size()];
- int[] runEnd = new int[cip.size()];
- int rangeStart = position;
- int rangeEnd = cip.keyAt(cip.size() - 1) + 1;
- int runCount = buildRunList(cip, rangeStart, rangeEnd, runStart, runEnd);
- for (int i = 0; i != runCount; i++) {
- if (!(runStart[i] == position || (runEnd[i] < runStart[i] && runEnd[i] > position))) {
- // Only set a new check mark in front of this run if it does
- // not contain the deleted position. If it does, we only need
- // to make it one check mark shorter at the end.
- setItemChecked(rotate(runStart[i], -1, rangeStart, rangeEnd), true);
- }
- setItemChecked(rotate(runEnd[i], -1, rangeStart, rangeEnd), false);
- }
- }
-
- private static int buildRunList(SparseBooleanArray cip, int rangeStart,
- int rangeEnd, int[] runStart, int[] runEnd) {
- int runCount = 0;
-
- int i = findFirstSetIndex(cip, rangeStart, rangeEnd);
- if (i == -1)
- return 0;
-
- int position = cip.keyAt(i);
- int currentRunStart = position;
- int currentRunEnd = currentRunStart + 1;
- for (i++; i < cip.size() && (position = cip.keyAt(i)) < rangeEnd; i++) {
- if (!cip.valueAt(i)) // not checked => not interesting
- continue;
- if (position == currentRunEnd) {
- currentRunEnd++;
- } else {
- runStart[runCount] = currentRunStart;
- runEnd[runCount] = currentRunEnd;
- runCount++;
- currentRunStart = position;
- currentRunEnd = position + 1;
- }
- }
-
- if (currentRunEnd == rangeEnd) {
- // rangeStart and rangeEnd are equivalent positions so to be
- // consistent we translate them to the same integer value. That way
- // we can check whether a run covers the entire range by just
- // checking if the start equals the end position.
- currentRunEnd = rangeStart;
- }
- runStart[runCount] = currentRunStart;
- runEnd[runCount] = currentRunEnd;
- runCount++;
-
- if (runCount > 1) {
- if (runStart[0] == rangeStart && runEnd[runCount - 1] == rangeStart) {
- // The last run ends at the end of the range, and the first run
- // starts at the beginning of the range. So they are actually
- // part of the same run, except they wrap around the end of the
- // range. To avoid adjacent runs, we need to merge them.
- runStart[0] = runStart[runCount - 1];
- runCount--;
- }
- }
- return runCount;
- }
-
- private static int rotate(int value, int offset, int lowerBound, int upperBound) {
- int windowSize = upperBound - lowerBound;
-
- value += offset;
- if (value < lowerBound) {
- value += windowSize;
- } else if (value >= upperBound) {
- value -= windowSize;
- }
- return value;
- }
-
- private static int findFirstSetIndex(SparseBooleanArray sba, int rangeStart, int rangeEnd) {
- int size = sba.size();
- int i = insertionIndexForKey(sba, rangeStart);
- while (i < size && sba.keyAt(i) < rangeEnd && !sba.valueAt(i))
- i++;
- if (i == size || sba.keyAt(i) >= rangeEnd)
- return -1;
- return i;
- }
-
- private static int insertionIndexForKey(SparseBooleanArray sba, int key) {
- int low = 0;
- int high = sba.size();
- while (high - low > 0) {
- int middle = (low + high) >> 1;
- if (sba.keyAt(middle) < key)
- low = middle + 1;
- else
- high = middle;
- }
- return low;
- }
-
- /**
- * Interface for controlling
- * scroll speed as a function of touch position and time. Use
- * {@link DragSortListView#setDragScrollProfile(DragScrollProfile)} to
- * set custom profile.
- *
- * @author heycosmo
- *
- */
- public interface DragScrollProfile {
- /**
- * Return a scroll speed in pixels/millisecond. Always return a
- * positive number.
- *
- * @param w Normalized position in scroll region (i.e. w \in [0,1]).
- * Small w typically means slow scrolling.
- * @param t Time (in milliseconds) since start of scroll (handy if you
- * want scroll acceleration).
- * @return Scroll speed at position w and time t in pixels/ms.
- */
- float getSpeed(float w, long t);
- }
-
- private class DragScroller implements Runnable {
-
- private boolean mAbort;
-
- private long mPrevTime;
- private long mCurrTime;
-
- private int dy;
- private float dt;
- private long tStart;
- private int scrollDir;
-
- public final static int STOP = -1;
- public final static int UP = 0;
- public final static int DOWN = 1;
-
- private float mScrollSpeed; // pixels per ms
-
- private boolean mScrolling = false;
-
- private int mLastHeader;
- private int mFirstFooter;
-
- public boolean isScrolling() {
- return mScrolling;
- }
-
- public int getScrollDir() {
- return mScrolling ? scrollDir : STOP;
- }
-
- public DragScroller() {
- }
-
- public void startScrolling(int dir) {
- if (!mScrolling) {
- // Debug.startMethodTracing("dslv-scroll");
- mAbort = false;
- mScrolling = true;
- tStart = SystemClock.uptimeMillis();
- mPrevTime = tStart;
- scrollDir = dir;
- post(this);
- }
- }
-
- public void stopScrolling(boolean now) {
- if (now) {
- DragSortListView.this.removeCallbacks(this);
- mScrolling = false;
- } else {
- mAbort = true;
- }
-
- // Debug.stopMethodTracing();
- }
-
- @Override
- public void run() {
- if (mAbort) {
- mScrolling = false;
- return;
- }
-
- // Log.d("mobeta", "scroll");
-
- final int first = getFirstVisiblePosition();
- final int last = getLastVisiblePosition();
- final int count = getCount();
- final int padTop = getPaddingTop();
- final int listHeight = getHeight() - padTop - getPaddingBottom();
-
- int minY = Math.min(mY, mFloatViewMid + mFloatViewHeightHalf);
- int maxY = Math.max(mY, mFloatViewMid - mFloatViewHeightHalf);
-
- if (scrollDir == UP) {
- View v = getChildAt(0);
- // Log.d("mobeta", "vtop="+v.getTop()+" padtop="+padTop);
- if (v == null) {
- mScrolling = false;
- return;
- } else {
- if (first == 0 && v.getTop() == padTop) {
- mScrolling = false;
- return;
- }
- }
- mScrollSpeed = mScrollProfile.getSpeed((mUpScrollStartYF - maxY)
- / mDragUpScrollHeight, mPrevTime);
- } else {
- View v = getChildAt(last - first);
- if (v == null) {
- mScrolling = false;
- return;
- } else {
- if (last == count - 1 && v.getBottom() <= listHeight + padTop) {
- mScrolling = false;
- return;
- }
- }
- mScrollSpeed = -mScrollProfile.getSpeed((minY - mDownScrollStartYF)
- / mDragDownScrollHeight, mPrevTime);
- }
-
- mCurrTime = SystemClock.uptimeMillis();
- dt = (float) (mCurrTime - mPrevTime);
-
- // dy is change in View position of a list item; i.e. positive dy
- // means user is scrolling up (list item moves down the screen,
- // remember
- // y=0 is at top of View).
- dy = (int) Math.round(mScrollSpeed * dt);
-
- int movePos;
- if (dy >= 0) {
- dy = Math.min(listHeight, dy);
- movePos = first;
- } else {
- dy = Math.max(-listHeight, dy);
- movePos = last;
- }
-
- final View moveItem = getChildAt(movePos - first);
- int top = moveItem.getTop() + dy;
-
- if (movePos == 0 && top > padTop) {
- top = padTop;
- }
-
- // always do scroll
- mBlockLayoutRequests = true;
-
- setSelectionFromTop(movePos, top - padTop);
- DragSortListView.this.layoutChildren();
- invalidate();
-
- mBlockLayoutRequests = false;
-
- // scroll means relative float View movement
- doDragFloatView(movePos, moveItem, false);
-
- mPrevTime = mCurrTime;
- // Log.d("mobeta", " updated prevTime="+mPrevTime);
-
- post(this);
- }
- }
-
- private class DragSortTracker {
- StringBuilder mBuilder = new StringBuilder();
-
- File mFile;
-
- private int mNumInBuffer = 0;
- private int mNumFlushes = 0;
-
- private boolean mTracking = false;
-
- public DragSortTracker() {
- File root = Environment.getExternalStorageDirectory();
- mFile = new File(root, "dslv_state.txt");
-
- if (!mFile.exists()) {
- try {
- mFile.createNewFile();
- Log.d("mobeta", "file created");
- } catch (IOException e) {
- Log.w("mobeta", "Could not create dslv_state.txt");
- Log.d("mobeta", e.getMessage());
- }
- }
-
- }
-
- public void startTracking() {
- mBuilder.append("<DSLVStates>\n");
- mNumFlushes = 0;
- mTracking = true;
- }
-
- public void appendState() {
- if (!mTracking) {
- return;
- }
-
- mBuilder.append("<DSLVState>\n");
- final int children = getChildCount();
- final int first = getFirstVisiblePosition();
- mBuilder.append(" <Positions>");
- for (int i = 0; i < children; ++i) {
- mBuilder.append(first + i).append(",");
- }
- mBuilder.append("</Positions>\n");
-
- mBuilder.append(" <Tops>");
- for (int i = 0; i < children; ++i) {
- mBuilder.append(getChildAt(i).getTop()).append(",");
- }
- mBuilder.append("</Tops>\n");
- mBuilder.append(" <Bottoms>");
- for (int i = 0; i < children; ++i) {
- mBuilder.append(getChildAt(i).getBottom()).append(",");
- }
- mBuilder.append("</Bottoms>\n");
-
- mBuilder.append(" <FirstExpPos>").append(mFirstExpPos).append("</FirstExpPos>\n");
- mBuilder.append(" <FirstExpBlankHeight>")
- .append(getItemHeight(mFirstExpPos) - getChildHeight(mFirstExpPos))
- .append("</FirstExpBlankHeight>\n");
- mBuilder.append(" <SecondExpPos>").append(mSecondExpPos).append("</SecondExpPos>\n");
- mBuilder.append(" <SecondExpBlankHeight>")
- .append(getItemHeight(mSecondExpPos) - getChildHeight(mSecondExpPos))
- .append("</SecondExpBlankHeight>\n");
- mBuilder.append(" <SrcPos>").append(mSrcPos).append("</SrcPos>\n");
- mBuilder.append(" <SrcHeight>").append(mFloatViewHeight + getDividerHeight())
- .append("</SrcHeight>\n");
- mBuilder.append(" <ViewHeight>").append(getHeight()).append("</ViewHeight>\n");
- mBuilder.append(" <LastY>").append(mLastY).append("</LastY>\n");
- mBuilder.append(" <FloatY>").append(mFloatViewMid).append("</FloatY>\n");
- mBuilder.append(" <ShuffleEdges>");
- for (int i = 0; i < children; ++i) {
- mBuilder.append(getShuffleEdge(first + i, getChildAt(i).getTop())).append(",");
- }
- mBuilder.append("</ShuffleEdges>\n");
-
- mBuilder.append("</DSLVState>\n");
- mNumInBuffer++;
-
- if (mNumInBuffer > 1000) {
- flush();
- mNumInBuffer = 0;
- }
- }
-
- public void flush() {
- if (!mTracking) {
- return;
- }
-
- // save to file on sdcard
- try {
- boolean append = true;
- if (mNumFlushes == 0) {
- append = false;
- }
- FileWriter writer = new FileWriter(mFile, append);
-
- writer.write(mBuilder.toString());
- mBuilder.delete(0, mBuilder.length());
-
- writer.flush();
- writer.close();
-
- mNumFlushes++;
- } catch (IOException e) {
- // do nothing
- }
- }
-
- public void stopTracking() {
- if (mTracking) {
- mBuilder.append("</DSLVStates>\n");
- flush();
- mTracking = false;
- }
- }
-
- }
-
-}
diff --git a/library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/ResourceDragSortCursorAdapter.java b/library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/ResourceDragSortCursorAdapter.java
deleted file mode 100644
index f2d08107f..000000000
--- a/library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/ResourceDragSortCursorAdapter.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.mobeta.android.dslv;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.LayoutInflater;
-
-// taken from v4 rev. 10 ResourceCursorAdapter.java
-
-/**
- * Static library support version of the framework's {@link android.widget.ResourceCursorAdapter}.
- * Used to write apps that run on platforms prior to Android 3.0. When running
- * on Android 3.0 or above, this implementation is still used; it does not try
- * to switch to the framework's implementation. See the framework SDK
- * documentation for a class overview.
- */
-public abstract class ResourceDragSortCursorAdapter extends DragSortCursorAdapter {
- private int mLayout;
-
- private int mDropDownLayout;
-
- private LayoutInflater mInflater;
-
- /**
- * Constructor the enables auto-requery.
- *
- * @deprecated This option is discouraged, as it results in Cursor queries
- * being performed on the application's UI thread and thus can cause poor
- * responsiveness or even Application Not Responding errors. As an alternative,
- * use {@link android.app.LoaderManager} with a {@link android.content.CursorLoader}.
- *
- * @param context The context where the ListView associated with this adapter is running
- * @param layout resource identifier of a layout file that defines the views
- * for this list item. Unless you override them later, this will
- * define both the item views and the drop down views.
- */
- @Deprecated
- public ResourceDragSortCursorAdapter(Context context, int layout, Cursor c) {
- super(context, c);
- mLayout = mDropDownLayout = layout;
- mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- }
-
- /**
- * Constructor with default behavior as per
- * {@link CursorAdapter#CursorAdapter(Context, Cursor, boolean)}; it is recommended
- * you not use this, but instead {@link #ResourceCursorAdapter(Context, int, Cursor, int)}.
- * When using this constructor, {@link #FLAG_REGISTER_CONTENT_OBSERVER}
- * will always be set.
- *
- * @param context The context where the ListView associated with this adapter is running
- * @param layout resource identifier of a layout file that defines the views
- * for this list item. Unless you override them later, this will
- * define both the item views and the drop down views.
- * @param c The cursor from which to get the data.
- * @param autoRequery If true the adapter will call requery() on the
- * cursor whenever it changes so the most recent
- * data is always displayed. Using true here is discouraged.
- */
- public ResourceDragSortCursorAdapter(Context context, int layout, Cursor c, boolean autoRequery) {
- super(context, c, autoRequery);
- mLayout = mDropDownLayout = layout;
- mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- }
-
- /**
- * Standard constructor.
- *
- * @param context The context where the ListView associated with this adapter is running
- * @param layout Resource identifier of a layout file that defines the views
- * for this list item. Unless you override them later, this will
- * define both the item views and the drop down views.
- * @param c The cursor from which to get the data.
- * @param flags Flags used to determine the behavior of the adapter,
- * as per {@link CursorAdapter#CursorAdapter(Context, Cursor, int)}.
- */
- public ResourceDragSortCursorAdapter(Context context, int layout, Cursor c, int flags) {
- super(context, c, flags);
- mLayout = mDropDownLayout = layout;
- mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- }
-
- /**
- * Inflates view(s) from the specified XML file.
- *
- * @see android.widget.CursorAdapter#newView(android.content.Context,
- * android.database.Cursor, ViewGroup)
- */
- @Override
- public View newView(Context context, Cursor cursor, ViewGroup parent) {
- return mInflater.inflate(mLayout, parent, false);
- }
-
- @Override
- public View newDropDownView(Context context, Cursor cursor, ViewGroup parent) {
- return mInflater.inflate(mDropDownLayout, parent, false);
- }
-
- /**
- * <p>Sets the layout resource of the item views.</p>
- *
- * @param layout the layout resources used to create item views
- */
- public void setViewResource(int layout) {
- mLayout = layout;
- }
-
- /**
- * <p>Sets the layout resource of the drop down views.</p>
- *
- * @param dropDownLayout the layout resources used to create drop down views
- */
- public void setDropDownViewResource(int dropDownLayout) {
- mDropDownLayout = dropDownLayout;
- }
-}
diff --git a/library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/SimpleDragSortCursorAdapter.java b/library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/SimpleDragSortCursorAdapter.java
deleted file mode 100644
index 7a76ea9d3..000000000
--- a/library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/SimpleDragSortCursorAdapter.java
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.mobeta.android.dslv;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.net.Uri;
-import android.view.View;
-import android.widget.TextView;
-import android.widget.ImageView;
-
-// taken from sdk/sources/android-16/android/widget/SimpleCursorAdapter.java
-
-/**
- * An easy adapter to map columns from a cursor to TextViews or ImageViews
- * defined in an XML file. You can specify which columns you want, which
- * views you want to display the columns, and the XML file that defines
- * the appearance of these views.
- *
- * Binding occurs in two phases. First, if a
- * {@link android.widget.SimpleCursorAdapter.ViewBinder} is available,
- * {@link ViewBinder#setViewValue(android.view.View, android.database.Cursor, int)}
- * is invoked. If the returned value is true, binding has occured. If the
- * returned value is false and the view to bind is a TextView,
- * {@link #setViewText(TextView, String)} is invoked. If the returned value
- * is false and the view to bind is an ImageView,
- * {@link #setViewImage(ImageView, String)} is invoked. If no appropriate
- * binding can be found, an {@link IllegalStateException} is thrown.
- *
- * If this adapter is used with filtering, for instance in an
- * {@link android.widget.AutoCompleteTextView}, you can use the
- * {@link android.widget.SimpleCursorAdapter.CursorToStringConverter} and the
- * {@link android.widget.FilterQueryProvider} interfaces
- * to get control over the filtering process. You can refer to
- * {@link #convertToString(android.database.Cursor)} and
- * {@link #runQueryOnBackgroundThread(CharSequence)} for more information.
- */
-public class SimpleDragSortCursorAdapter extends ResourceDragSortCursorAdapter {
- /**
- * A list of columns containing the data to bind to the UI.
- * This field should be made private, so it is hidden from the SDK.
- * {@hide}
- */
- protected int[] mFrom;
- /**
- * A list of View ids representing the views to which the data must be bound.
- * This field should be made private, so it is hidden from the SDK.
- * {@hide}
- */
- protected int[] mTo;
-
- private int mStringConversionColumn = -1;
- private CursorToStringConverter mCursorToStringConverter;
- private ViewBinder mViewBinder;
-
- String[] mOriginalFrom;
-
- /**
- * Constructor the enables auto-requery.
- *
- * @deprecated This option is discouraged, as it results in Cursor queries
- * being performed on the application's UI thread and thus can cause poor
- * responsiveness or even Application Not Responding errors. As an alternative,
- * use {@link android.app.LoaderManager} with a {@link android.content.CursorLoader}.
- */
- @Deprecated
- public SimpleDragSortCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
- super(context, layout, c);
- mTo = to;
- mOriginalFrom = from;
- findColumns(c, from);
- }
-
- /**
- * Standard constructor.
- *
- * @param context The context where the ListView associated with this
- * SimpleListItemFactory is running
- * @param layout resource identifier of a layout file that defines the views
- * for this list item. The layout file should include at least
- * those named views defined in "to"
- * @param c The database cursor. Can be null if the cursor is not available yet.
- * @param from A list of column names representing the data to bind to the UI. Can be null
- * if the cursor is not available yet.
- * @param to The views that should display column in the "from" parameter.
- * These should all be TextViews. The first N views in this list
- * are given the values of the first N columns in the from
- * parameter. Can be null if the cursor is not available yet.
- * @param flags Flags used to determine the behavior of the adapter,
- * as per {@link CursorAdapter#CursorAdapter(Context, Cursor, int)}.
- */
- public SimpleDragSortCursorAdapter(Context context, int layout,
- Cursor c, String[] from, int[] to, int flags) {
- super(context, layout, c, flags);
- mTo = to;
- mOriginalFrom = from;
- findColumns(c, from);
- }
-
- /**
- * Binds all of the field names passed into the "to" parameter of the
- * constructor with their corresponding cursor columns as specified in the
- * "from" parameter.
- *
- * Binding occurs in two phases. First, if a
- * {@link android.widget.SimpleCursorAdapter.ViewBinder} is available,
- * {@link ViewBinder#setViewValue(android.view.View, android.database.Cursor, int)}
- * is invoked. If the returned value is true, binding has occured. If the
- * returned value is false and the view to bind is a TextView,
- * {@link #setViewText(TextView, String)} is invoked. If the returned value is
- * false and the view to bind is an ImageView,
- * {@link #setViewImage(ImageView, String)} is invoked. If no appropriate
- * binding can be found, an {@link IllegalStateException} is thrown.
- *
- * @throws IllegalStateException if binding cannot occur
- *
- * @see android.widget.CursorAdapter#bindView(android.view.View,
- * android.content.Context, android.database.Cursor)
- * @see #getViewBinder()
- * @see #setViewBinder(android.widget.SimpleCursorAdapter.ViewBinder)
- * @see #setViewImage(ImageView, String)
- * @see #setViewText(TextView, String)
- */
- @Override
- public void bindView(View view, Context context, Cursor cursor) {
- final ViewBinder binder = mViewBinder;
- final int count = mTo.length;
- final int[] from = mFrom;
- final int[] to = mTo;
-
- for (int i = 0; i < count; i++) {
- final View v = view.findViewById(to[i]);
- if (v != null) {
- boolean bound = false;
- if (binder != null) {
- bound = binder.setViewValue(v, cursor, from[i]);
- }
-
- if (!bound) {
- String text = cursor.getString(from[i]);
- if (text == null) {
- text = "";
- }
-
- if (v instanceof TextView) {
- setViewText((TextView) v, text);
- } else if (v instanceof ImageView) {
- setViewImage((ImageView) v, text);
- } else {
- throw new IllegalStateException(v.getClass().getName() + " is not a " +
- " view that can be bounds by this SimpleCursorAdapter");
- }
- }
- }
- }
- }
-
- /**
- * Returns the {@link ViewBinder} used to bind data to views.
- *
- * @return a ViewBinder or null if the binder does not exist
- *
- * @see #bindView(android.view.View, android.content.Context, android.database.Cursor)
- * @see #setViewBinder(android.widget.SimpleCursorAdapter.ViewBinder)
- */
- public ViewBinder getViewBinder() {
- return mViewBinder;
- }
-
- /**
- * Sets the binder used to bind data to views.
- *
- * @param viewBinder the binder used to bind data to views, can be null to
- * remove the existing binder
- *
- * @see #bindView(android.view.View, android.content.Context, android.database.Cursor)
- * @see #getViewBinder()
- */
- public void setViewBinder(ViewBinder viewBinder) {
- mViewBinder = viewBinder;
- }
-
- /**
- * Called by bindView() to set the image for an ImageView but only if
- * there is no existing ViewBinder or if the existing ViewBinder cannot
- * handle binding to an ImageView.
- *
- * By default, the value will be treated as an image resource. If the
- * value cannot be used as an image resource, the value is used as an
- * image Uri.
- *
- * Intended to be overridden by Adapters that need to filter strings
- * retrieved from the database.
- *
- * @param v ImageView to receive an image
- * @param value the value retrieved from the cursor
- */
- public void setViewImage(ImageView v, String value) {
- try {
- v.setImageResource(Integer.parseInt(value));
- } catch (NumberFormatException nfe) {
- v.setImageURI(Uri.parse(value));
- }
- }
-
- /**
- * Called by bindView() to set the text for a TextView but only if
- * there is no existing ViewBinder or if the existing ViewBinder cannot
- * handle binding to a TextView.
- *
- * Intended to be overridden by Adapters that need to filter strings
- * retrieved from the database.
- *
- * @param v TextView to receive text
- * @param text the text to be set for the TextView
- */
- public void setViewText(TextView v, String text) {
- v.setText(text);
- }
-
- /**
- * Return the index of the column used to get a String representation
- * of the Cursor.
- *
- * @return a valid index in the current Cursor or -1
- *
- * @see android.widget.CursorAdapter#convertToString(android.database.Cursor)
- * @see #setStringConversionColumn(int)
- * @see #setCursorToStringConverter(android.widget.SimpleCursorAdapter.CursorToStringConverter)
- * @see #getCursorToStringConverter()
- */
- public int getStringConversionColumn() {
- return mStringConversionColumn;
- }
-
- /**
- * Defines the index of the column in the Cursor used to get a String
- * representation of that Cursor. The column is used to convert the
- * Cursor to a String only when the current CursorToStringConverter
- * is null.
- *
- * @param stringConversionColumn a valid index in the current Cursor or -1 to use the default
- * conversion mechanism
- *
- * @see android.widget.CursorAdapter#convertToString(android.database.Cursor)
- * @see #getStringConversionColumn()
- * @see #setCursorToStringConverter(android.widget.SimpleCursorAdapter.CursorToStringConverter)
- * @see #getCursorToStringConverter()
- */
- public void setStringConversionColumn(int stringConversionColumn) {
- mStringConversionColumn = stringConversionColumn;
- }
-
- /**
- * Returns the converter used to convert the filtering Cursor
- * into a String.
- *
- * @return null if the converter does not exist or an instance of
- * {@link android.widget.SimpleCursorAdapter.CursorToStringConverter}
- *
- * @see #setCursorToStringConverter(android.widget.SimpleCursorAdapter.CursorToStringConverter)
- * @see #getStringConversionColumn()
- * @see #setStringConversionColumn(int)
- * @see android.widget.CursorAdapter#convertToString(android.database.Cursor)
- */
- public CursorToStringConverter getCursorToStringConverter() {
- return mCursorToStringConverter;
- }
-
- /**
- * Sets the converter used to convert the filtering Cursor
- * into a String.
- *
- * @param cursorToStringConverter the Cursor to String converter, or
- * null to remove the converter
- *
- * @see #setCursorToStringConverter(android.widget.SimpleCursorAdapter.CursorToStringConverter)
- * @see #getStringConversionColumn()
- * @see #setStringConversionColumn(int)
- * @see android.widget.CursorAdapter#convertToString(android.database.Cursor)
- */
- public void setCursorToStringConverter(CursorToStringConverter cursorToStringConverter) {
- mCursorToStringConverter = cursorToStringConverter;
- }
-
- /**
- * Returns a CharSequence representation of the specified Cursor as defined
- * by the current CursorToStringConverter. If no CursorToStringConverter
- * has been set, the String conversion column is used instead. If the
- * conversion column is -1, the returned String is empty if the cursor
- * is null or Cursor.toString().
- *
- * @param cursor the Cursor to convert to a CharSequence
- *
- * @return a non-null CharSequence representing the cursor
- */
- @Override
- public CharSequence convertToString(Cursor cursor) {
- if (mCursorToStringConverter != null) {
- return mCursorToStringConverter.convertToString(cursor);
- } else if (mStringConversionColumn > -1) {
- return cursor.getString(mStringConversionColumn);
- }
-
- return super.convertToString(cursor);
- }
-
- /**
- * Create a map from an array of strings to an array of column-id integers in cursor c.
- * If c is null, the array will be discarded.
- *
- * @param c the cursor to find the columns from
- * @param from the Strings naming the columns of interest
- */
- private void findColumns(Cursor c, String[] from) {
- if (c != null) {
- int i;
- int count = from.length;
- if (mFrom == null || mFrom.length != count) {
- mFrom = new int[count];
- }
- for (i = 0; i < count; i++) {
- mFrom[i] = c.getColumnIndexOrThrow(from[i]);
- }
- } else {
- mFrom = null;
- }
- }
-
- @Override
- public Cursor swapCursor(Cursor c) {
- // super.swapCursor() will notify observers before we have
- // a valid mapping, make sure we have a mapping before this
- // happens
- findColumns(c, mOriginalFrom);
- return super.swapCursor(c);
- }
-
- /**
- * Change the cursor and change the column-to-view mappings at the same time.
- *
- * @param c The database cursor. Can be null if the cursor is not available yet.
- * @param from A list of column names representing the data to bind to the UI. Can be null
- * if the cursor is not available yet.
- * @param to The views that should display column in the "from" parameter.
- * These should all be TextViews. The first N views in this list
- * are given the values of the first N columns in the from
- * parameter. Can be null if the cursor is not available yet.
- */
- public void changeCursorAndColumns(Cursor c, String[] from, int[] to) {
- mOriginalFrom = from;
- mTo = to;
- // super.changeCursor() will notify observers before we have
- // a valid mapping, make sure we have a mapping before this
- // happens
- findColumns(c, mOriginalFrom);
- super.changeCursor(c);
- }
-
- /**
- * This class can be used by external clients of SimpleCursorAdapter
- * to bind values fom the Cursor to views.
- *
- * You should use this class to bind values from the Cursor to views
- * that are not directly supported by SimpleCursorAdapter or to
- * change the way binding occurs for views supported by
- * SimpleCursorAdapter.
- *
- * @see SimpleCursorAdapter#bindView(android.view.View, android.content.Context, android.database.Cursor)
- * @see SimpleCursorAdapter#setViewImage(ImageView, String)
- * @see SimpleCursorAdapter#setViewText(TextView, String)
- */
- public static interface ViewBinder {
- /**
- * Binds the Cursor column defined by the specified index to the specified view.
- *
- * When binding is handled by this ViewBinder, this method must return true.
- * If this method returns false, SimpleCursorAdapter will attempts to handle
- * the binding on its own.
- *
- * @param view the view to bind the data to
- * @param cursor the cursor to get the data from
- * @param columnIndex the column at which the data can be found in the cursor
- *
- * @return true if the data was bound to the view, false otherwise
- */
- boolean setViewValue(View view, Cursor cursor, int columnIndex);
- }
-
- /**
- * This class can be used by external clients of SimpleCursorAdapter
- * to define how the Cursor should be converted to a String.
- *
- * @see android.widget.CursorAdapter#convertToString(android.database.Cursor)
- */
- public static interface CursorToStringConverter {
- /**
- * Returns a CharSequence representing the specified Cursor.
- *
- * @param cursor the cursor for which a CharSequence representation
- * is requested
- *
- * @return a non-null CharSequence representing the cursor
- */
- CharSequence convertToString(Cursor cursor);
- }
-
-}
diff --git a/library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/SimpleFloatViewManager.java b/library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/SimpleFloatViewManager.java
deleted file mode 100644
index af1df01c0..000000000
--- a/library/drag-sort-listview/src/main/java/com/mobeta/android/dslv/SimpleFloatViewManager.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package com.mobeta.android.dslv;
-
-import android.graphics.Bitmap;
-import android.graphics.Point;
-import android.graphics.Color;
-import android.widget.ListView;
-import android.widget.ImageView;
-import android.view.View;
-import android.view.ViewGroup;
-import android.util.Log;
-
-/**
- * Simple implementation of the FloatViewManager class. Uses list
- * items as they appear in the ListView to create the floating View.
- */
-public class SimpleFloatViewManager implements DragSortListView.FloatViewManager {
-
- private Bitmap mFloatBitmap;
-
- private ImageView mImageView;
-
- private int mFloatBGColor = Color.BLACK;
-
- private ListView mListView;
-
- public SimpleFloatViewManager(ListView lv) {
- mListView = lv;
- }
-
- public void setBackgroundColor(int color) {
- mFloatBGColor = color;
- }
-
- /**
- * This simple implementation creates a Bitmap copy of the
- * list item currently shown at ListView <code>position</code>.
- */
- @Override
- public View onCreateFloatView(int position) {
- // Guaranteed that this will not be null? I think so. Nope, got
- // a NullPointerException once...
- View v = mListView.getChildAt(position + mListView.getHeaderViewsCount() - mListView.getFirstVisiblePosition());
-
- if (v == null) {
- return null;
- }
-
- v.setPressed(false);
-
- // Create a copy of the drawing cache so that it does not get
- // recycled by the framework when the list tries to clean up memory
- //v.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
- v.setDrawingCacheEnabled(true);
- mFloatBitmap = Bitmap.createBitmap(v.getDrawingCache());
- v.setDrawingCacheEnabled(false);
-
- if (mImageView == null) {
- mImageView = new ImageView(mListView.getContext());
- }
- mImageView.setBackgroundColor(mFloatBGColor);
- mImageView.setPadding(0, 0, 0, 0);
- mImageView.setImageBitmap(mFloatBitmap);
- mImageView.setLayoutParams(new ViewGroup.LayoutParams(v.getWidth(), v.getHeight()));
-
- return mImageView;
- }
-
- /**
- * This does nothing
- */
- @Override
- public void onDragFloatView(View floatView, Point position, Point touch) {
- // do nothing
- }
-
- /**
- * Removes the Bitmap from the ImageView created in
- * onCreateFloatView() and tells the system to recycle it.
- */
- @Override
- public void onDestroyFloatView(View floatView) {
- ((ImageView) floatView).setImageDrawable(null);
-
- mFloatBitmap.recycle();
- mFloatBitmap = null;
- }
-
-}
-
diff --git a/library/drag-sort-listview/src/main/res/values/dslv_attrs.xml b/library/drag-sort-listview/src/main/res/values/dslv_attrs.xml
deleted file mode 100644
index 8c779c9bf..000000000
--- a/library/drag-sort-listview/src/main/res/values/dslv_attrs.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<resources>
- <declare-styleable name="DragSortListView">
- <attr name="collapsed_height" format="dimension" />
- <attr name="drag_scroll_start" format="float" />
- <attr name="max_drag_scroll_speed" format="float" />
- <attr name="float_background_color" format="color" />
- <attr name="remove_mode">
- <enum name="clickRemove" value="0" />
- <enum name="flingRemove" value="1" />
- </attr>
- <attr name="track_drag_sort" format="boolean"/>
- <attr name="float_alpha" format="float"/>
- <attr name="slide_shuffle_speed" format="float"/>
- <attr name="remove_animation_duration" format="integer"/>
- <attr name="drop_animation_duration" format="integer"/>
- <attr name="drag_enabled" format="boolean" />
- <attr name="sort_enabled" format="boolean" />
- <attr name="remove_enabled" format="boolean" />
- <attr name="drag_start_mode">
- <enum name="onDown" value="0" />
- <enum name="onMove" value="1" />
- <enum name="onLongPress" value="2"/>
- </attr>
- <attr name="drag_handle_id" format="integer" />
- <attr name="fling_handle_id" format="integer" />
- <attr name="click_remove_id" format="integer" />
- <attr name="use_default_controller" format="boolean" />
- </declare-styleable>
-</resources>
diff --git a/settings.gradle b/settings.gradle
index b2a4011c3..f8f9b77af 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,2 +1,2 @@
-include ':app', ':core'
-include ':library:drag-sort-listview'
+include ':app'
+include ':core'