0

I'm using a PopupWindow to show some suggestions when user type on an edittext. inside the popup window, i have a listview which shows the suggestions. i couldn’t use ListpopupWindow because it was covering the keyboard thus the user can't be able to continue typing while the popup is showing.

In order for the user to continue typing, i have to setFocusable(false); on my popupwindow. the issue with this is that one cannot click on any suggestion since the window is not focusable. and if i make it focusable, the user won't be able to continue typing since focus will be removed from edit text to popup window. therefore i have to set a touchlistener to the popupwindow and perform the click programmatically.

How can i intercept PopupWindow touchevent and perform a click on listview item? I tried using the code snippet below but it never worked

  public void initPopupWindow(int type) {

    mPopupWindow = new PopupWindow(popupView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
      mPopupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);

  mPopupWindow.setFocusable(false);
  mPopupWindow.setOutsideTouchable(true);
  mPopupWindow.setTouchInterceptor(new PopupTouchInterceptor());

  View view1 = LayoutInflater.from(context).inflate(R.layout.search_listview,null);
  mDropDownList = (CustomListView)view1.findViewById(R.id.searchListView);
  serchAdapter = new SearchAdapter(context,realm);
  mDropDownList.setAdapter(serchAdapter);
  mDropDownList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
      searchableEditText.setText(serchAdapter.getItem(position).toString());
      mPopupWindow.dismiss();
    }
  });
  mPopupWindow.setContentView(view1);



 }

   private class PopupTouchInterceptor implements View.OnTouchListener {
    public boolean onTouch(View v, MotionEvent event) {
      final int action = event.getAction();
      boolean consumed = false;
      boolean handledEvent = true;
      boolean clearPressedItem = false;
      final int actionMasked = event.getActionMasked();

      if (action == MotionEvent.ACTION_DOWN) {
        consumed = true;
        mActivePointerId = event.getPointerId(0);

      } else if (action == MotionEvent.ACTION_UP) {
        consumed = true;

      }else if(action == MotionEvent.ACTION_OUTSIDE){
        consumed = true;

      }else if(action == MotionEvent.ACTION_MOVE){

        consumed = true;


        final int activeIndex = event.findPointerIndex(mActivePointerId);

        final int x = (int) event.getX(activeIndex);
        final int y = (int) event.getY(activeIndex);
        final int position = mDropDownList.pointToPosition(x, y);

        final View child = mDropDownList.getChildAt(position - mDropDownList.getFirstVisiblePosition());
        handledEvent = true;
        child.performClick();

      }
      return consumed;
    }
  }
Edijae Crusar
  • 3,473
  • 3
  • 37
  • 74

1 Answers1

1

I found a way to achieve what I want.

What I did was surrender and make PopupWindow focusable in order to enable it's embedded ListView to receive touch events:

popupWindow.setFocusable(true);

As this effectively makes the ListView also the receiver of keyboard events I made an OnKeyListener that forwards the events to the EditText:

listview.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                mEditor.dispatchKeyEvent(event);
                return false;
            }
        });

For clearance here is the complete modified code from the question:

public void initPopupWindow(int type) {

    mPopupWindow = new PopupWindow(popupView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
      mPopupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);

  mPopupWindow.setFocusable(true);
  mPopupWindow.setOutsideTouchable(true);



View view1 = LayoutInflater.from(context).inflate(R.layout.search_listview,null);
  listview = (ListView)view1.findViewById(R.id.searchListView);
  serchAdapter = new SearchAdapter(context,realm);
  listview.setAdapter(serchAdapter);
  listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
      searchableEditText.setText(serchAdapter.getItem(position).toString());
      mPopupWindow.dismiss();
    }
  });



listview.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                mEditor.dispatchKeyEvent(event);
                return false;
            }
        });
  mPopupWindow.setContentView(view1);

 }
Edijae Crusar
  • 3,473
  • 3
  • 37
  • 74