【发布时间】:2016-09-05 14:42:42
【问题描述】:
我有一个很奇怪的情况。我正在使用上下文操作模式来选择ListView 的多个项目。流程如下:
用户通过长按选择列表项 --> 使用操作项“操作”来选择他想要执行的操作 --> 此操作项创建一个带有 4 个列表项的AlertDialog(称为 dialog1),其中第三项调用另一个AlertDialog(称为dialog2),其中包括用于某些数据输入的EditText,然后调用一个方法来执行它。
稍后用户点击返回按钮或主页按钮退出操作模式。 问题是 dialog2 交替出现,就像用户第一次选择列表项,选择“操作”操作项并选择调用 dialog2 的第三项。现在 dialog2 将按预期显示。稍后用户点击返回按钮退出操作模式。 第二次用户执行 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;
}
});
}
【问题讨论】:
标签: android listview android-actionbar android-alertdialog