gpt4 book ai didi

drag-and-drop - Android 4.0.x 在同一 ListView 中的项目掉落时挂起或重新启动

转载 作者:行者123 更新时间:2023-12-05 01:17:15 25 4
gpt4 key购买 nike

目的

我已经按照 Android 3.0 拖放框架实现了“从 ListView 重新排序项目”范例。

问题

出现在 android 4.0.3 和 4.0.4 上。未在其他版本上测试。

将 ListView 的一个项目拖放到 ListView 的最后一个项目之后。阴影框被清除,ListView 失效。这是名义上的行为,90% 的时间都会发生。

但对于剩下的 10%,发生的情况是:

  • NB:下面列出的所有效果都在 onDrag(View, DragEvent) 返回 ACTION_DRAG_ENDED 之后看到,也就是说整个拖放过程似乎在问题发生之前就已完成。
  • 阴影框只显示了 10 秒就消失了。在 ACTION_DRAG_ENDEDonDrag(View, DragEvent) 处理程序中调用 view.invalidate() 将纠正该问题,但不会解决挂起或重启问题(见下文)
  • logcat 中的一些异常痕迹:

I/ViewRootImpl( 954): Reporting drop result: true I/InputQueue-JNI( 210): Sending finished signal for input channel 'drag (client)' since it is being unregistered while an input message is still in progress. I/InputQueue-JNI( 210): Ignoring finish signal on channel that is no longer registered. W/WindowManager( 210): Drag is in progress but there is no drag window handle. I/ViewRootImpl( 954): Reporting drop result: true

  • 在某些设备上,Android 挂起或重新启动。这取决于设备,但效果始终相同。

源代码

import android.annotation.SuppressLint;
import android.app.ListActivity;
import android.content.ClipData;
import android.content.ClipDescription;
import android.os.Bundle;
import android.view.DragEvent;
import android.view.View;
import android.view.View.DragShadowBuilder;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class TestReorderActivity extends ListActivity {

@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

ListView listView = getListView();
String[] listeStrings = { "France", "United States", "Russia" };
listView.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, listeStrings));

listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {

@Override
public boolean onItemLongClick(AdapterView<?> adapter, View view,
int id, long position) {
ClipData data = ClipData.newPlainText(" ",
Long.toString(position));

DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(
view);
if (view.startDrag(data, shadowBuilder/*
* new
* MyDragShadowBuilder(view)
*/, view, 0)) {
return true;
}

return false;
}

});

listView.setOnDragListener(new ListView.OnDragListener() {

@Override
public boolean onDrag(View view, DragEvent event) {
final int action = event.getAction();

switch (action) {
case DragEvent.ACTION_DRAG_STARTED:

if (event.getClipDescription().hasMimeType(
ClipDescription.MIMETYPE_TEXT_PLAIN)) {
// accept drag
return true;
} else {
// reject drag
return false;
}

case DragEvent.ACTION_DRAG_ENTERED:
// entered drag
return true;

case DragEvent.ACTION_DRAG_LOCATION:
// location is returned as event.getX() and event.getY()
return true;

case DragEvent.ACTION_DRAG_EXITED:
// cancel drag.
return true;

case DragEvent.ACTION_DROP:
// item dropped
processDrop(event);
return true;

case DragEvent.ACTION_DRAG_ENDED:
default: // unknown case
return true;
}
}

private boolean processDrop(DragEvent event) {
ClipData data = event.getClipData();
if ((data != null) && (data.getItemCount() > 0)) {
ClipData.Item item = data.getItemAt(0);
CharSequence value = item.getText();
long position = Long.valueOf(value.toString());

int x = (int) event.getX();
int y = (int) event.getY();

ListView listView = getListView();

int newPosition = listView.pointToPosition(x, y);
if (newPosition > ListView.INVALID_POSITION) {

swap(position, newPosition);
return true;
}
}

return false;
}

});

}

// swap(long, long) here
}

最佳答案

原因是:你的屏幕上传action_move太懒了。

在正常情况下,即使您的手指没有在屏幕上移动, Action 移动也会非常频繁地上传。但有些手机屏幕不那么敏感。

您可以修改手机的阈值。它需要内核支持。

关于drag-and-drop - Android 4.0.x 在同一 ListView 中的项目掉落时挂起或重新启动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12314251/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com