Keep showing popupWindow when back button of keybo

2019-08-01 18:02发布

问题:

I am working on an Android application and I've designed a popupWindow to show some view by replacing a soft keyboard in an activity. The popupWindow contains a searchView. When I click on a button, it shows the popupWindow and the soft keyboard gets hidden. Now when the searchView in the popupWindow gets focus, I call the method:

popupWindow.setFocusable(true)

To show keyboard so that users can start typing in searchView. When the searchView is in focus and the soft keyboard is open, then pressing the back key closes both the searchView and the popupWindow as well.

To solve this issue, I created a custom searchView and overrode the method dispatchKeyEventPreIme in this as below.

public class CustomSearchView extends SearchView {

    Context context;
    AppConstant mAppConst;

    public CustomSearchView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
    }


    @Override
    public boolean dispatchKeyEventPreIme(KeyEvent event) {

       if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
           clearFocus();
        }
        return super.dispatchKeyEventPreIme(event);
    }
}

I have cleared the focus from the searchView when the back button is pressed, but I don't know how can I prevent the popupWindow from closing.

回答1:

Here's what I tried and it worked!

In onCreate():

private PopupWindow popupWindow;

someButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        final LayoutInflater inflater = (LayoutInflater) appContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View popupView = inflater.inflate(R.layout.popupwindow_view, null, false);

        popupWindow = new PopupWindow(popupView, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT);
        popupWindow.setBackgroundDrawable(new BitmapDrawable());
        popupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
        popupWindow.setOutsideTouchable(false);

        CustomSearchView searchView = (CustomSearchView) popupView.findViewById(R.id.customSearchView);
        popupWindow.showAsDropDown(someButton, 50, -30);
    }
});

Make sure to have this in your Activity:

@Override
public void onBackPressed() {
    if (popupWindow != null && popupWindow.isShowing()) {
        Toast.makeText(context, "Activity Back Pressed - PopupWindow showing!", Toast.LENGTH_SHORT).show();
    } else {
        super.onBackPressed();
}

My XML Layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.package.name.CustomSearchView
        android:layout_width="match_parent"
        android:id="@+id/customSearchView"
        android:background="@android:color/black"
        android:layout_height="match_parent"></com.package.name.CustomSearchView>

</LinearLayout>

CustomSearchView.java

public class CustomSearchView extends SearchView {

    Context context;

    public CustomSearchView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
    }

    @Override
    public boolean dispatchKeyEventPreIme(KeyEvent event) {
       if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
           clearFocus();
           Toast.makeText(context, "CustomSearchView Back Pressed", Toast.LENGTH_SHORT).show();
           return false;
       } else {
           return super.dispatchKeyEventPreIme(event);
       }
    }
}

When I do this implementation, CustomSearchView's dispatchKeyEventPreIme does not called BUT Activity's OnBackPressed() does get called.

As you see, I put a Toast when back button gets pressed and it calls each time. Try it out. It doesn't close the PopupWindow.



回答2:

Do this in your Activity. If popupWindow is showing, back button won't do anything.

@Override
public void onBackPressed() {
    if (popupWindow != null && popupWindow.isShowing()) {
        // do nothing
    } else {
        super.onBackPressed();
    }
}

You can also use this feature so when clicked outside of popupWindow, it won't close.

popupWindow.setOutsideTouchable(false);

/// UPDATE

Try changing this:

@Override
public boolean dispatchKeyEventPreIme(KeyEvent event) {
    if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
       clearFocus();
       return false;
    } else {
       return super.dispatchKeyEventPreIme(event);
    }
}