我有一个非常奇怪的情况。我正在使用上下文操作模式来选择ListView
的多个项目。流程如下:
用户长按它们选择列表项 - >使用操作项“操作”来选择他想要做的事情 - >此操作项会创建一个包含4个列表项的AlertDialog
(称之为 dialog1 ),其中第3个项目调用另一个AlertDialog
(称之为 dialog2 )包括EditText
用于某些数据输入,稍后调用方法来执行它。
稍后用户点击后退按钮或主页按钮退出操作模式。 问题是 dialog2 会像第一次用户选择列表项一样显示,选择“操作”操作项并选择调用 dialog2 的第3项。现在 dialog2 将按预期显示。稍后,用户点击“返回”按钮退出“操作模式”。 SECOND TIME用户执行相同的步骤 dialog2 不会出现。
logcat在两种情况下都显示此错误:
09-04 10:53:12.096 6299-6299 / com.project.pcmanager W / InputEventReceiver:尝试完成输入事件但输入 事件接收者已被处理。
一些代码:
public void sendAction(final Context context, final EventModel model, int position) {
JSONObject object = new JSONObject();
String[] operations = getResources().getStringArray(R.array.operations);
// null set before is modified here
model.setEventTitle(operations[position]);
final String ip = model.getEventIP();
switch (position) {
case 0:
try {
object.put("command", "power_off");
notifyUser();
LogUtils.addEntry(model.toString());
execCommand(ip,object);
} catch (JSONException e) {
e.printStackTrace();
}
break;
case 1:
try {
object.put("command", "reboot");
notifyUser();
LogUtils.addEntry(model.toString());
execCommand(ip,object);
} catch (JSONException e) {
e.printStackTrace();
}
break;
case 2:
//Show AlertDialog with EditText on it for command input
final EditText txtCommand = new EditText(context);
// Set some properties to EditText
txtCommand.setPadding(16, 16, 16, 16);
txtCommand.setMinHeight(150);
txtCommand.setHint("Ex: ping google.com");
txtCommand.setSingleLine();
new AlertDialog.Builder(context)
.setTitle("Run a task")
.setView(txtCommand)
.setCancelable(false)
.setPositiveButton("Run",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
String command = txtCommand.getText().toString();
if (command.length() > 0) {
JSONObject object = new JSONObject();
try {
object.put("run", command);
object.put("ip", ip);
notifyUser();
LogUtils.addEntry(model.toString());
performRemoteExec(object);
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Toast.makeText(context, "Please provide a command first!", Toast.LENGTH_SHORT).show();
}
}
}).setNeutralButton("Cancel", null).show();
break;
case 3:
notifyUser();
LogUtils.addEntry(model.toString());
getScreenshot(ip);
break;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
listView.setAdapter(adapter);
listView.setEmptyView(emptyView);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
@Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
//Change the title bar with the items selected
mode.setTitle(listView.getCheckedItemCount() + " selected");
//select the clicked item
adapter.toggleSelection(position);
}
/**
* Called when action mode is first created.
* The menu supplied will be used to generate action buttons for the action mode.
* @param mode ActionMode being created
* @param menu Menu used to populate action buttons
* @return true if the action mode should be created,
* false if entering this mode should be aborted.
*/
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
onContextMode = true;
mode.getMenuInflater().inflate(R.menu.menu_client_select_main, menu);
return true;
}
/**
* Called to refresh an action mode's action menu whenever it is invalidated.
* @return true if the menu or action mode was updated, false otherwise.
*/
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
/**
* Called to report a user click on an action button.
* @return true if this callback handled the event,
* false if the standard MenuItem invocation should continue.
*/
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
int id = item.getItemId();
if (id == R.id.menu_operations) {
final AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setItems(R.array.operations, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
SparseBooleanArray selectedIds = adapter.getSelectedIds();
// traverse the array to find chosen clients
for (int i = 0; i < selectedIds.size(); i++) {
if (selectedIds.get(i)) {
ClientModel item = adapter.getItem(i);
String ip = item.getClientIP();
String os = item.getOSType();
// null will be treated soon
EventModel model = new EventModel(ip, null, os);
sendAction(builder.getContext(),model, which);
}
}
}
});
builder.show();
}
return true;
}
/**
* Called when an action mode is about to be exited and destroyed.
*/
@Override
public void onDestroyActionMode(ActionMode mode) {
onContextMode = false;
}
});
}
答案 0 :(得分:0)
好的,所以我自己想出了问题。事实证明,罪魁祸首是我使用SparseBooleanArray
来选择客户,我错了。
在我的代码中是:
SparseBooleanArray selectedIds = adapter.getSelectedIds();
所以,我用一种新的实现技术删除了这个SparseBooleanArray。我使用ArrayList<ClientMode> selectedItems
将所有选定的模型存储在Adapter类中。
另外,我创建了一个名为clearSelections
的简单方法,在其中调用selectedItems.clear()
方法。我根据我的应用要求在onDestroyActionMode
上调用此方法。
我如何找到这个?
我只是在System.out.println
和onCreate
周围放置了一堆sendAction
语句,以找出罪魁祸首。