我有一个类可以拖动和重新排列列表项,但我如何在ListActivity或任何其他活动中使用它。我是这个东西的新手,任何帮助将不胜感激。这是代码请帮助。
package com.iconasystems.christo.dynamiclistview;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.ListView;
import java.util.ArrayList;
import static android.widget.AdapterView.OnItemLongClickListener;
/**
* Created by Christo on 8/14/2014.
*/
public class DynamicList extends ListView {
private final int SMOOTH_SCROLL_AMOUNT_AT_EDGE = 15;
private final int MOVE_DURATION = 150;
private final int LINE_THICKNESS = 15;
public ArrayList<String> mArrayList;
private int mLastEventY = -1;
private int mDownY = -1;
private int mDownX = -1;
private int mTotalOffset = 0;
private boolean mCellIsMobile = false;
private boolean mIsMobileScrolling = false;
private int mSmoothScrollAmountAtEdge = 0;
private final int INVALID_ID = -1;
private long mAboveItemId = INVALID_ID;
private long mMobileItemId = INVALID_ID;
private long mBelowItemId = INVALID_ID;
private BitmapDrawable mHoverCell;
private Rect mHoverCellCurrentBounds;
private Rect mHoverCellOriginalBounds;
private final int INVALID_POINTER_ID = -1;
private int mActivePointerId = INVALID_POINTER_ID;
private boolean mIsWaitingForScrollFinish = false;
private int mScrollState = OnScrollListener.SCROLL_STATE_IDLE;
public DynamicList(Context context) {
super(context);
}
public DynamicList(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
public DynamicList(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public void init(Context context) {
setOnItemClickListener((OnItemClickListener) mOnItemLongClickListener);
setOnScrollListener(mScrollListener);
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
mSmoothScrollAmountAtEdge = (int) (SMOOTH_SCROLL_AMOUNT_AT_EDGE / metrics.density);
}
private OnItemLongClickListener mOnItemLongClickListener =
new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
mTotalOffset = 0;
position = pointToPosition(mDownX, mDownY);
int itemNum = position - getFirstVisiblePosition();
View selectedView = getChildAt(itemNum);
mMobileItemId = getAdapter().getItemId(position);
mHoverCell = getAndAddHoverView(selectedView);
selectedView.setVisibility(INVISIBLE);
mCellIsMobile = true;
updateNeighbourViewsForID(mMobileItemId);
return true;
}
};
private BitmapDrawable getAndAddHoverView(View v) {
int w = v.getWidth();
int h = v.getHeight();
int top = v.getTop();
int left = v.getLeft();
Bitmap b = getBitmapWithBorder(v);
BitmapDrawable drawable = new BitmapDrawable(getResources(), b);
mHoverCellOriginalBounds = new Rect(left, top, left + w, top + h);
mHoverCellCurrentBounds = new Rect(mHoverCellOriginalBounds);
drawable.setBounds(mHoverCellOriginalBounds);
return drawable;
}
private Bitmap getBitmapWithBorder(View v) {
Bitmap bitmap = getBitmapFromView(v);
Canvas can = new Canvas(bitmap);
Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(LINE_THICKNESS);
paint.setColor(Color.BLACK);
can.drawBitmap(bitmap, 0, 0, null);
can.drawRect(rect, paint);
return bitmap;
}
private Bitmap getBitmapFromView(View v) {
Bitmap bitmap = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
v.draw(canvas);
return bitmap;
}
private void updateNeighbourViewsForID(long itemID) {
int position = getPositionForID(itemID);
ArrayAdapter adapter = ((ArrayAdapter) getAdapter());
mAboveItemId = adapter.getItemId(position - 1);
mBelowItemId = adapter.getItemId(position + 1);
}
public View getViewForID(long itemID) {
int firstVisiblePosition = getFirstVisiblePosition();
ArrayAdapter adapter = ((ArrayAdapter) getAdapter());
for (int i = 0; i < getChildCount(); i++) {
View v = getChildAt(i);
int position = firstVisiblePosition + 1;
long id = adapter.getItemId(position);
if (id == itemID) {
return v;
}
}
return null;
}
public int getPositionForID(long itemID) {
View v = getViewForID(itemID);
if (v == null) {
return -1;
} else {
return getPositionForView(v);
}
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
if (mHoverCell != null) {
mHoverCell.draw(canvas);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
mDownX = (int) event.getX();
mDownY = (int) event.getY();
mActivePointerId = event.getPointerId(0);
break;
case MotionEvent.ACTION_MOVE:
if (mActivePointerId == INVALID_POINTER_ID) {
break;
}
int pointerIndex = event.findPointerIndex(mActivePointerId);
mLastEventY = (int) event.getY(pointerIndex);
int deltaY = mLastEventY - mDownY;
if (mCellIsMobile) {
mHoverCellCurrentBounds.offsetTo(mHoverCellOriginalBounds.left,
mHoverCellOriginalBounds.top + deltaY + mTotalOffset);
mHoverCell.setBounds(mHoverCellCurrentBounds);
invalidate();
handleCellSwitch();
mIsMobileScrolling = false;
handleMobileCellScroll();
}
break;
case MotionEvent.ACTION_UP:
touchEventsEnded();
break;
}
return false;
}
private void handleCellSwitch() {
final int deltaY = mLastEventY - mDownY;
int deltaYTotal = mHoverCellOriginalBounds.top + mTotalOffset + deltaY;
View belowView = getViewForID(mBelowItemId);
View mobileView = getViewForID(mMobileItemId);
View aboveView = getViewForID(mAboveItemId);
boolean isBelow = (belowView != null) && (deltaYTotal > belowView.getTop());
boolean isAbove = (aboveView != null) && (deltaYTotal < aboveView.getTop());
if (isBelow || isAbove) {
final long switchItemID = isBelow ? mAboveItemId : mAboveItemId;
View switchView = isBelow ? belowView : aboveView;
final int originalItem = getPositionForView(mobileView);
if (switchView == null) {
updateNeighbourViewsForID(mMobileItemId);
return;
}
swapElements(mArrayList, originalItem, getPositionForView(switchView));
((BaseAdapter) getAdapter()).notifyDataSetChanged();
mDownY = mLastEventY;
final int switchViewStartTop = switchView.getTop();
mobileView.setVisibility(View.VISIBLE);
switchView.setVisibility(View.INVISIBLE);
updateNeighbourViewsForID(mMobileItemId);
final ViewTreeObserver observer = getViewTreeObserver();
observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
observer.removeOnPreDrawListener(this);
View switchView = getViewForID(switchItemID);
mTotalOffset += deltaY;
int switchViewNewTop = switchView.getTop();
int delta = switchViewStartTop - switchViewNewTop;
switchView.setTranslationY(delta);
ObjectAnimator animator = ObjectAnimator.ofFloat(switchView,
View.TRANSLATION_Y, 0);
animator.setDuration(MOVE_DURATION);
animator.start();
return true;
}
});
}
}
private void swapElements(ArrayList arrayList, int indexOne, int indexTwo) {
Object temp = arrayList.get(indexOne);
arrayList.set(indexOne, arrayList.get(indexTwo));
arrayList.set(indexTwo, temp);
}
private void touchEventsEnded() {
final View mobileView = getViewForID(mMobileItemId);
if (mCellIsMobile || mIsWaitingForScrollFinish) {
mCellIsMobile = false;
mIsWaitingForScrollFinish = false;
mIsMobileScrolling = false;
mActivePointerId = INVALID_POINTER_ID;
if (mScrollState != OnScrollListener.SCROLL_STATE_IDLE) {
mIsWaitingForScrollFinish = true;
return;
}
mHoverCellCurrentBounds.offsetTo(mHoverCellOriginalBounds.left, mobileView.getTop());
ObjectAnimator hoverViewAnimator = ObjectAnimator.ofObject(mHoverCell, "bounds",
sBoundEvaluator, mHoverCellCurrentBounds);
hoverViewAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
invalidate();
}
});
hoverViewAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
setEnabled(false);
}
@Override
public void onAnimationEnd(Animator animation) {
mAboveItemId = INVALID_ID;
mMobileItemId = INVALID_ID;
mBelowItemId = INVALID_ID;
mobileView.setVisibility(VISIBLE);
mHoverCell = null;
setEnabled(true);
invalidate();
}
});
hoverViewAnimator.start();
} else {
touchEventsCancelled();
}
}
private void touchEventsCancelled() {
View mobileView = getViewForID(mMobileItemId);
if (mCellIsMobile) {
mAboveItemId = INVALID_ID;
mMobileItemId = INVALID_ID;
mBelowItemId = INVALID_ID;
mobileView.setVisibility(VISIBLE);
mHoverCell = null;
invalidate();
}
mCellIsMobile = false;
mIsMobileScrolling = false;
mActivePointerId = INVALID_POINTER_ID;
}
private final static TypeEvaluator<Rect> sBoundEvaluator = new TypeEvaluator<Rect>() {
@Override
public Rect evaluate(float fraction, Rect startValue, Rect endValue) {
return new Rect(interpolate(startValue.left, endValue.left, fraction),
interpolate(startValue.top, endValue.top, fraction),
interpolate(startValue.right, endValue.right, fraction),
interpolate(startValue.bottom, endValue.bottom, fraction));
}
public int interpolate(int start, int end, float fraction) {
return (int) (start + fraction * (end - start));
}
};
private void handleMobileCellScroll() {
mIsMobileScrolling = handleMobileCellScroll(mHoverCellCurrentBounds);
}
public boolean handleMobileCellScroll(Rect r) {
int offset = computeVerticalScrollOffset();
int height = getHeight();
int extent = computeVerticalScrollExtent();
int range = computeHorizontalScrollRange();
int hoverViewTop = r.top;
int hoverHeight = r.height();
if (hoverViewTop <= 0 && offset > 0) {
smoothScrollBy(-mSmoothScrollAmountAtEdge, 0);
return true;
}
if (hoverViewTop + hoverHeight >= height && (offset + extent) < range) {
smoothScrollBy(mSmoothScrollAmountAtEdge, 0);
return true;
}
return false;
}
public void setArrayList(ArrayList<String> arrayList) {
mArrayList = arrayList;
}
private OnScrollListener mScrollListener = new OnScrollListener() {
private int mPreviousFirstVisibleItem = -1;
private int mPreviousVisibleItemCount = -1;
private int mCurrentFirstVisibleItem;
private int mCurrentVisibleItemCount;
private int mCurrentScrollState;
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
mCurrentScrollState = scrollState;
mScrollState = scrollState;
isScrollCompleted();
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
mCurrentFirstVisibleItem = firstVisibleItem;
mCurrentVisibleItemCount = visibleItemCount;
mPreviousFirstVisibleItem = (mPreviousFirstVisibleItem == -1) ? mCurrentFirstVisibleItem
: mPreviousFirstVisibleItem;
mPreviousVisibleItemCount = (mPreviousVisibleItemCount == -1) ? mPreviousVisibleItemCount
: mPreviousVisibleItemCount;
checkAndHandleFirstVisibleCellChange();
checkAndHandleLastVisibleCellChange();
mPreviousVisibleItemCount = mCurrentFirstVisibleItem;
mPreviousVisibleItemCount = mCurrentVisibleItemCount;
}
private void isScrollCompleted() {
if (mCurrentVisibleItemCount > 0 && mCurrentScrollState == SCROLL_STATE_IDLE) {
if (mCellIsMobile && mIsMobileScrolling) {
handleMobileCellScroll();
} else if (mIsWaitingForScrollFinish) {
touchEventsEnded();
}
}
}
public void checkAndHandleFirstVisibleCellChange() {
if (mCurrentFirstVisibleItem != mPreviousFirstVisibleItem) {
if (mCellIsMobile && mMobileItemId != INVALID_ID) {
updateNeighbourViewsForID(mMobileItemId);
handleCellSwitch();
}
}
}
public void checkAndHandleLastVisibleCellChange() {
int currentLastVisibleItem = mCurrentFirstVisibleItem + mCurrentVisibleItemCount;
int previousVisibleLastItem = mPreviousFirstVisibleItem + mPreviousVisibleItemCount;
if (currentLastVisibleItem != previousVisibleLastItem) {
if (mCellIsMobile && mMobileItemId != INVALID_ID) {
updateNeighbourViewsForID(mMobileItemId);
handleCellSwitch();
}
}
}
};
}
答案 0 :(得分:0)
在您的init方法中,您尝试将OnItemLongClickListener
投射到OnItemClickListener
。点击和长按是不同的。请改为setOnItemLongClickListener
。