0

当用户在编辑文本上键入时,我使用 PopupWindow 来显示一些建议。在弹出窗口中,我有一个显示建议的列表视图。我无法使用 ListpopupWindow,因为它覆盖了键盘,因此用户无法在弹出窗口显示时继续输入。

为了让用户继续输入,我必须 setFocusable(false);在我的弹出窗口上。这样做的问题是,由于窗口不可聚焦,因此无法单击任何建议。如果我让它成为焦点,用户将无法继续输入,因为焦点将从编辑文本移到弹出窗口。因此我必须为弹出窗口设置一个触摸监听器并以编程方式执行点击。

如何拦截 PopupWindow touchevent 并单击 listview 项目?我尝试使用下面的代码片段,但它从未奏效

  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;
    }
  }
4

1 回答 1

1

我找到了一种方法来实现我想要的。

我所做的是投降并使 PopupWindow 成为焦点,以使其嵌入的 ListView 能够接收触摸事件:

popupWindow.setFocusable(true);

因为这有效地使 ListView 也成为键盘事件的接收者,所以我创建了一个 OnKeyListener,将事件转发到 EditText:

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

为了清除这里是问题的完整修改代码:

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);

 }
于 2016-08-30T11:40:20.187 回答