您好我正在尝试拖放ListView。它很棒。但我失去了点击和滚动的能力。我如何保留这两个?我认为长按该项目而不是正常按下时会发生拖放。这是我的onTouch,它位于MyListView中,扩展了ListView
@Override
public boolean onTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
final int x = (int) ev.getX();
final int y = (int) ev.getY();
if (action == MotionEvent.ACTION_DOWN && x < this.getWidth()/4) {
this._dragMode = true;
}
if (!this._isDragNDrop)
return super.onTouchEvent(ev);
switch (action) {
case MotionEvent.ACTION_DOWN:
this._startPosition = pointToPosition(x,y);
if (this._startPosition != INVALID_POSITION) {
int mItemPosition = this._startPosition - getFirstVisiblePosition();
this._dragPointOffset = y - getChildAt(mItemPosition).getTop();
this._dragPointOffset -= ((int)ev.getRawY()) - y;
startDrag(mItemPosition,y);
drag(x,y);
}
break;
case MotionEvent.ACTION_MOVE:
drag(x,y);
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
default:
this._dragMode = false;
//_isDragNDrop = false;
this._endPosition = pointToPosition(x,y);
stopDrag(this._startPosition - getFirstVisiblePosition());
if (this._dropListener != null && this._startPosition != INVALID_POSITION && this._endPosition != INVALID_POSITION)
this._dropListener.onDrop(this._startPosition, this._endPosition);
break;
}
return true;
}
答案 0 :(得分:5)
我刚刚在我的应用程序中实现了拖放列表视图,通过长按项目开始拖动。
源代码在GitHub上:DraggableListView,我有一个blog post来描述它。希望它可以帮到你。
答案 1 :(得分:3)
我正在实施类似的东西。 希望这会帮助别人,因为我还在解决问题。
...
thumb.setOnDragListener(new Drag());
...
public class Drag implements OnDragListener{
public static int PositionOfDraggedItem = -1;
public int PositionOfItemDraggedOver = -1;
public Drag() {}
@Override
public boolean onDrag(View v, DragEvent event)
{
final int action = event.getAction();
boolean state = true;
View root = v.getRootView();
ListView List = (ListView) root.findViewById(android.R.id.list);
Object holder = v.getTag() instanceof OrderHolder? (OrderHolder)v.getTag() : v.getTag();
String BookId = holder instanceof OrderHolder? String.valueOf(((OrderHolder)holder).id) : (String)holder;
switch(action)
{
case DragEvent.ACTION_DRAG_STARTED:
break;
case DragEvent.ACTION_DRAG_ENTERED:
if( PositionOfDraggedItem != -1 )
{
if( this.PositionOfItemDraggedOver != PositionOfDraggedItem )
{
if( v.getBackground() != null )
v.setBackgroundDrawable(v.getContext().getResources().getDrawable(drawable.row_ovr));
}
}
break;
case DragEvent.ACTION_DRAG_LOCATION:
/**
* Set the item being
* here, as it will not
* provide location data
* anywhere else
*/
if( PositionOfDraggedItem == -1 )
PositionOfDraggedItem = List.getPositionForView(v);
/**
* Set the view thats
* being dragged over
*/
this.PositionOfItemDraggedOver = List.getPositionForView(v);
int PositionOfLastVisibleView = List.getLastVisiblePosition();
int PositionOfFirstVisibleView = List.getFirstVisiblePosition();
if( this.PositionOfItemDraggedOver != -1 && ( this.PositionOfItemDraggedOver != PositionOfDraggedItem ) ){
if( this.PositionOfItemDraggedOver == PositionOfLastVisibleView-1 || this.PositionOfItemDraggedOver == PositionOfLastVisibleView || this.PositionOfItemDraggedOver == PositionOfLastVisibleView+1 ){
List.smoothScrollToPosition(PositionOfLastVisibleView+1);
}else if( this.PositionOfItemDraggedOver == PositionOfFirstVisibleView-1 || this.PositionOfItemDraggedOver == PositionOfFirstVisibleView+1 || this.PositionOfItemDraggedOver == PositionOfFirstVisibleView ){
List.smoothScrollToPosition(PositionOfFirstVisibleView-1);
}
}
break;
case DragEvent.ACTION_DRAG_EXITED:
if( v.getBackground() != null )
v.setBackgroundDrawable(v.getContext().getResources().getDrawable(drawable.row));
break;
case DragEvent.ACTION_DROP:
if(event != null)
{
ClipData data = event.getClipData();
if( data != null && data.getItemCount() > 0 )
{
if( !data.getItemAt(0).getText().toString().equalsIgnoreCase(BookId) )
{
if( v.getBackground() != null )
v.setBackgroundDrawable(v.getContext().getResources().getDrawable(drawable.row));
/**
* Ordering info for
* book being dragged
*/
String oShelfOrder = BookManager.item(v.getContext().getContentResolver(), dbhelper.BOOKS_SHELFORDER,
booksprovider.GetUri(dbhelper.BOOKS), Long.parseLong(data.getItemAt(0).getText().toString()));
String oBookOrder = BookManager.item(v.getContext().getContentResolver(), dbhelper.BOOKS_BOOKSORDER,
booksprovider.GetUri(dbhelper.BOOKS), Long.parseLong(data.getItemAt(0).getText().toString()));
/**
* Ordering info
* for book being dragged
* to
*/
String dShelfOrder = BookManager.item(v.getContext().getContentResolver(), dbhelper.BOOKS_SHELFORDER,
booksprovider.GetUri(dbhelper.BOOKS), Long.parseLong(BookId));
String dBookOrder = BookManager.item(v.getContext().getContentResolver(), dbhelper.BOOKS_BOOKSORDER,
booksprovider.GetUri(dbhelper.BOOKS), Long.parseLong(BookId));
/**
* Update book being dragged
*/
ContentValues args = new ContentValues();
args.put(dbhelper.BOOKS_SHELFORDER, dShelfOrder);
args.put(dbhelper.BOOKS_BOOKSORDER, dBookOrder);
BookManager.updateBook(v.getContext().getContentResolver(), data.getItemAt(0).getText().toString(), args);
/**
* Update book being dragged to
*/
ContentValues values = new ContentValues();
values.put(dbhelper.BOOKS_SHELFORDER, oShelfOrder);
values.put(dbhelper.BOOKS_BOOKSORDER, oBookOrder);
BookManager.updateBook(v.getContext().getContentResolver(), BookId, values);
if( v.getContext() instanceof OrderBooks ){
((OrderBooks)v.getContext()).adapter.refresh();
((OrderBooks)v.getContext()).adapter.notifyDataSetChanged();
PositionOfDraggedItem = -1;
}
}
}
}
break;
case DragEvent.ACTION_DRAG_ENDED:
if( event != null && event.getResult())
{
v.invalidate();
}
break;
}
return state;
}
}
暂时没有处理过,更新以反映最新的变化。
答案 2 :(得分:2)
请查看此question以获取更多帮助。我还有一个名为DragSortListView的组件,我花了很长时间精炼。你可以在这里找到它:
我可以帮助您将长按启动的拖动整合到我上面的回购中。
答案 3 :(得分:0)
我实施了这个适合我的解决方案。以下方法在我的Activity中,当dragEvent为ACTION_DRAG_ENTERED时,在我的dragEventListener中调用它。我声明的一些属性:
//first visible item (getFirstVisiblePosition() does not work for me)
int firstVisible;
//number of scrolls
int nbrScroll;
//my listview to scroll
ListView mListView;
//the adapter of my listview
SimpleAdapter mAdapter;
...
public void scrollDrag(int position) {
//this is the position of the item in my listview
//to scroll down
//test if the item entered is the last visible
if (position == mListView.getLastVisiblePosition()
&& id < mListView.getCount()) {
mAdapter.notifyDataSetChanged();
mRightDrawerList.post(new Runnable() {
@Override
public void run() {
//scroll down
mListView.smoothScrollToPosition(mListView
.getLastVisiblePosition() + 1);
firstVisible++;
}
});
//to scroll up
//test if the item entered is the first visible
} else if (position == firstVisible && position !=0) {
mAdapter.notifyDataSetChanged();
mListView.post(new Runnable() {
@Override
public void run() {
//scroll up
mListView.smoothScrollToPosition(firstVisible-1);
firstVisible --;
}
});
}
}
希望它会对某人有所帮助。
答案 4 :(得分:0)
在科特林:
holder.mView.setOnDragListener { v, event ->
when (event.action) {
DragEvent.ACTION_DRAG_ENTERED -> {
...
}
DragEvent.ACTION_DRAG_EXITED, DragEvent.ACTION_DRAG_ENDED -> {
...
val y = calculateY(holder.mView)
val minY = calculateY(scroll_view) + 200
val scrollBounds = Rect()
scroll_view.getHitRect(scrollBounds) //TODO: calculate only once
val maxY = minY + scrollBounds.height() - 400
if (y < minY) {
scroll_view?.post {
scroll_view.smoothScrollBy(0, -200)
}
} else if (y > maxY) {
scroll_view?.post {
scroll_view.smoothScrollBy(0, +200)
}
}
}
}
}
答案 5 :(得分:-1)
他们我在rickey的代码中做了一些改动,它为我工作。
if (PositionOfItemDraggedOver == PositionOfLastVisibleView)
order_item_list_lv.smoothScrollToPosition(PositionOfLastVisibleView + 1);
if (PositionOfItemDraggedOver == PositionOfFirstVisibleView)
order_item_list_lv.smoothScrollToPosition(PositionOfFirstVisibleView - 1);