上下文操作模式中的警报对话奇怪的问题

时间:2016-09-04 05:36:46

标签: android listview android-actionbar android-alertdialog

我有一个非常奇怪的情况。我正在使用上下文操作模式来选择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;
                }
            });
}

1 个答案:

答案 0 :(得分:0)

好的,所以我自己想出了问题。事实证明,罪魁祸首是我使用SparseBooleanArray来选择客户,我错了。

在我的代码中是:

SparseBooleanArray selectedIds = adapter.getSelectedIds();

所以,我用一种新的实现技术删除了这个SparseBooleanArray。我使用ArrayList<ClientMode> selectedItems将所有选定的模型存储在Adapter类中。

另外,我创建了一个名为clearSelections的简单方法,在其中调用selectedItems.clear()方法。我根据我的应用要求在onDestroyActionMode上调用此方法。

我如何找到这个? 我只是在System.out.printlnonCreate周围放置了一堆sendAction语句,以找出罪魁祸首。