如何从popupwindow向其子列表视图发送touchevent

时间:2016-08-29 05:54:34

标签: android listview android-popupwindow android-touch-event

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

为了让用户继续输入,我必须在弹出窗口中setFocusable(false);。这个问题是,由于窗口不可聚焦,因此无法点击任何建议。如果我使其可聚焦,则用户将无法继续键入,因为焦点将从编辑文本移除到弹出窗口。因此我必须在弹出窗口中设置一个touchlistener并以编程方式执行单击。

如何拦截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;
    }
  }

1 个答案:

答案 0 :(得分:0)

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

我所做的就是投降并使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);

 }