当 PopUpMenu 和编辑文本存在时 "Recent Apps" 中的应用无响应

Non responding app in "Recent Apps" when PopUpMenu and Edit Text Present

上下文

我正在使用弹出窗口允许用户快速重命名 activity 中的卡片视图。

我通过使用 ViewSwitcherTextView(原始名称)替换为 EditText(新名称)来做到这一点。

问题

当出现 EditTextPopUpWindow 确认并且用户按下 "RECENT APPS" 时,由于某种原因您无法返回应用程序。 即。当你点击它时,它没有反应。

诊断

我认为这是 Window Focus 的问题。我已经尝试从 ET EditText.clearFocus() 关闭所有 PopUps onPause,不走运。

有没有办法使用 onFocusChangeListener 来解决这个问题?

代码(我尽量删除了多余的项目)

TheHubActivity.java

public class TheHubActivity extends AppCompatActivity implements RecyclerViewAdapter.onCardClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        // KEYBOARD
        imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);

        recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        //... Set up recycle view

        rvContent = new ArrayList<>();
    }

    @Override
    public void onCardLongClick(Flow longClickedFlow, int cardPosition, View cardViewClicked) {
        showLongClickPopUpMenu(longClickedFlow,cardPosition, cardViewClicked);
    }

    private void showLongClickPopUpMenu(final Flow longClickedFlow, final int cardPosition, final View cardViewClicked) {

        LayoutInflater layoutInflater = (LayoutInflater) this
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View layout = layoutInflater.inflate(R.layout.popup_window_longclick, null);

        LinearLayout viewGroup = (LinearLayout)  layout.findViewById(R.id.popup_longclick);

        // Creating the PopupWindow
        final PopupWindow popup = new PopupWindow(layout, RecyclerView.LayoutParams.WRAP_CONTENT,
                RecyclerView.LayoutParams.WRAP_CONTENT);


        popup.setFocusable(true);

        // Getting a reference to Close button, and close the popup when clicked.
        ImageView delete = (ImageView) layout.findViewById(R.id.popup_delete_item);

        delete.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                /*.... Delete current Flow from internal file and UI */
                popup.dismiss();
            }
        });

        ImageView edit = (ImageView) layout.findViewById(R.id.popup_edit_item);

        edit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                popup.dismiss();
                renameFlow(cardPosition, cardViewClicked);
            }
        });

        // Displaying the popup at the specified location, + offsets.
        popup.showAsDropDown(cardViewClicked, cardViewClicked.getMeasuredWidth(),popupDisplayHeight, Gravity.TOP);

        longClickPopup = popup;
    }

    private void renameFlow(final int cardPosition, final View cardViewClicked) {
        final ViewSwitcher switcher = (ViewSwitcher) cardViewClicked.findViewById(R.id.rename_switcher);
        final EditText rename = (EditText) switcher.findViewById(R.id.item_flow_rename);

        rename.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (rename.hasFocus()) {
                    showEditPopupWindow(rename, cardViewClicked, switcher, cardPosition);
                } else {
                    imm.hideSoftInputFromWindow(rename.getWindowToken(), 0);
                }

            }
        });

        switcher.showNext();

        rename.requestFocus();
        imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, InputMethodManager.HIDE_IMPLICIT_ONLY);
        /* Forces keyboard */


    }

    private void showEditPopupWindow(final EditText newName, View cardViewClicked, final ViewSwitcher switcher, final int cardPosition) {
        LayoutInflater layoutInflater = (LayoutInflater) this
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View layout = layoutInflater.inflate(R.layout.popup_window_editing, null);

        LinearLayout viewGroup = (LinearLayout)  layout.findViewById(R.id.popup_editing);

        // Creating the PopupWindow
        final PopupWindow popup = new PopupWindow(layout, RecyclerView.LayoutParams.WRAP_CONTENT,
                RecyclerView.LayoutParams.WRAP_CONTENT);

        popup.setFocusable(false); // So that user can edit text

        // Getting a reference to Close button, and close the popup when clicked.
        ImageView confirmEdit = (ImageView) layout.findViewById(R.id.popup_confirm_item_changes);

        confirmEdit.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                /* .. Changes name of cardview through edit text */
                    switcher.showNext();
                    popup.dismiss();
                    newName.clearFocus();
                }

            }
        });

        ImageView cancelEdit = (ImageView) layout.findViewById(R.id.popup_cancel_item_changes);

        cancelEdit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                switcher.showNext();
                popup.dismiss();
            }
        });

        popup.showAsDropDown(cardViewClicked, cardViewClicked.getMeasuredWidth(),popupDisplayHeight, Gravity.TOP);
        editingPopup = popup;
    }


    @Override
    protected void onPause() {
        dismissPopups();
        super.onPause();
    }

    private void dismissPopups() {
        if (longClickPopup!=null && longClickPopup.isShowing()) {
            longClickPopup.dismiss();
        }

        if (editingPopup!=null && editingPopup.isShowing()) {
            editingPopup.dismiss();
        }
    }
}

视觉型人士

我解决了这个问题...而且它出奇地大并且与 Focus/PopUps 完全无关(我猜是隧道视觉)。

在我的清单中,我使用了 android:launchMode="singleTop",当 TheHubActivity 被发送到最近的应用程序时,它会产生奇怪的行为,因为这是我的入口 activity。从 Developer Docs singleTop functions like so:

Similarly, a new instance of a "singleTop" activity may also be created to handle a new intent. However, if the target task already has an existing instance of the activity at the top of its stack, that instance will receive the new intent (in an onNewIntent() call); a new instance is not created. In other circumstances — for example, if an existing instance of the "singleTop" activity is in the target task, but not at the top of the stack, or if it's at the top of a stack, but not in the target task — a new instance would be created and pushed on the stack.

<activity
            android:name=".TheHubActivity"
            android:label="@string/app_name"
            ~~~~~~android:launchMode="singleTop"~~~~~~~~
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>