【问题标题】:How to dispatch touchevent from popupwindow to its child listview如何将触摸事件从弹出窗口分派到其子列表视图
【发布时间】:2016-08-29 05:54:34
【问题描述】:

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

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

如何拦截 PopupWindow touchevent 并单击 listview 项目?我尝试使用下面的代码 sn-p 但它从来没有工作过

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

【问题讨论】:

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


    【解决方案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);
    
     }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-24
      • 1970-01-01
      • 1970-01-01
      • 2012-01-08
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      • 2012-10-31
      相关资源
      最近更新 更多