弹出窗口关闭外部触摸不工作

时间:2015-03-20 11:34:40

标签: android android-popupwindow

请先检查我到目前为止所做的尝试,然后再进行重复投票 我试图在外部触摸时关闭弹出窗口。我已经尝试了所有可用的解决方案,但它不起作用。

第一次尝试:

pwindo.setBackgroundDrawable(new BitmapDrawable());
            pwindo.setFocusable(true);
            pwindo.setOutsideTouchable(true);

第二次尝试:

pwindo.setBackgroundDrawable(new ColorDrawable());
            pwindo.setFocusable(true);
            pwindo.setOutsideTouchable(true);

第3次尝试:

pwindo.setBackgroundDrawable(new ColorDrawable());
            pwindo.setFocusable(true);
            pwindo.setOutsideTouchable(false);

第四次尝试:

        pwindo.setFocusable(true);
        pwindo.setOutsideTouchable(false);  

第五次尝试:

        pwindo.setOutsideTouchable(true);  
第六次尝试:

        pwindo.setOutsideTouchable(false);  

第7次尝试:

        pwindo.setFocusable(true);  

什么都没有用。

已更新

public void addFlyout()
{
    try {
        LayoutInflater inflater = TabActivity.this.getLayoutInflater();
        Display display = getWindowManager().getDefaultDisplay();
        Method mGetRawH = Display.class.getMethod("getRawHeight");
        Method mGetRawW = Display.class.getMethod("getRawWidth");
        int rawHeight = (Integer) mGetRawH.invoke(display);
        View view = inflater.inflate(R.layout.flyout_list_layout,
                (ViewGroup) findViewById(R.id.flyoutLayoutList));
        Dialog dialog = new Dialog(TabActivity.this);
        pwindo = new PopupWindow(view, 340, rawHeight- actionBar.getHeight(), true);
        pwindo.showAtLocation(view, Gravity.RIGHT | Gravity.TOP, 0, actionBar.getHeight());
        pwindo.setBackgroundDrawable(new ColorDrawable(Color.RED));
       // pwindo.setTouchable(true);
        pwindo.setOutsideTouchable(true);
        pwindo.setTouchInterceptor(new View.OnTouchListener() {
            @Override public boolean onTouch(View v, MotionEvent event)
            {

                if (event.getAction() == MotionEvent.ACTION_OUTSIDE)
                {
                    pwindo.dismiss();
                    //Log.e(TAG, "some event happened outside window: action outside");
                    return true;
                }
               // Log.e(TAG, "some event happened outside window");
                return false;
            }
        });

        listFlyout = (ListView) view.findViewById(R.id.list_slideList);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(TabActivity.this, R.layout.drawer_item, R.id.content, tabs);
        listFlyout.setAdapter(adapter);
    }
    catch (Exception ex)
    {
        ex.printStackTrace();
    }
} 

并且

@Override
    public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
        // When the given tab is selected, switch to the corresponding page in
        // the ViewPager.
        try {
            if(tab.getPosition() == 4)
            {
                addFlyout();
            }
            else
            mViewPager.setCurrentItem(tab.getPosition());
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
    }

4 个答案:

答案 0 :(得分:5)

PopupWindow上设置背景可确保通过其界限外的点击可以禁用它。

showAtLocation(...)

public void showAtLocation(IBinder token, int gravity, int x, int y) {
    ....

    preparePopup(p);

    ....
}

preparePopup(...)检查是否设置了背景。如果是,则您传递的内容视图(在构造函数中)将添加到自定义FrameLayout。然后在此自定义FrameLayout上设置背景:

if (mBackground != null) {
    ....

    // when a background is available, we embed the content view
    // within another view that owns the background drawable
    PopupViewContainer popupViewContainer = new PopupViewContainer(mContext);
    PopupViewContainer.LayoutParams listParams = new PopupViewContainer.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, height
        );
    popupViewContainer.setBackground(mBackground);
    popupViewContainer.addView(mContentView, listParams);

    ....
} else {
    ....
}

由于您在 setBackgroundDrawable(...)后呼叫showAtLocation(...) preparePopup(...)未将内容视图置于PopupViewContainer内。

PopupViewContainer也会覆盖onTouchEvent(...)以提供被解雇时被解雇的外部&#39;行为:

@Override
public boolean onTouchEvent(MotionEvent event) {
    final int x = (int) event.getX();
    final int y = (int) event.getY();

    if ((event.getAction() == MotionEvent.ACTION_DOWN)
            && ((x < 0) || (x >= getWidth()) || (y < 0) || (y >= getHeight()))) {
        dismiss();
        return true;
    } else if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
        dismiss();
        return true;
    } else {
        return super.onTouchEvent(event);
    }
}

显然,您需要的只是提供背景,并在致电showAtLocation(...)之前提供。

答案 1 :(得分:3)

如果您在dialog.setCanceledOnTouchOutside(true);之外触摸,可以使用Dialog关闭Dialog

类似的东西:

Dialog dialog = new Dialog(context)
dialog.setCanceledOnTouchOutside(true);

对于弹出窗口:

popupWindow.setOutsideTouchable(true); 
popupWindow.setTouchable(true); 
popupWindow.setBackgroundDrawable(new BitmapDrawable());
popupWindow.setTouchInterceptor(new OnTouchListener() { @Override 
        public boolean onTouch(View v, MotionEvent event) { 
           if(AppContext.isDebugMode()) {
                    Log.d("POPUP_WINDOW", "v: "+v.getTag() + " | event: "+event.getAction()); 
                    popupWindow.dismiss(); 
                    return true; 
           } 
        });
}

答案 2 :(得分:3)

尝试使用以下代码。

 LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    // Inflate the view from a predefined XML layout
    View layout = inflater.inflate(R.layout.test, (ViewGroup) findViewById(R.id.linearLayout));

    pw = new PopupWindow(layout, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, true);

    pw.setOutsideTouchable(true);
    pw.setBackgroundDrawable(new ShapeDrawable());
    pw.setTouchInterceptor(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // here I want to close the pw when clicking outside it but
            // at all this is just an example of how it works and you can
            // implement the onTouch() or the onKey() you want
            if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
                pw.dismiss();
                return true;
            }
            return false;
        }

    });

    pw.showAtLocation(layout, Gravity.CENTER, 0, 0);

答案 3 :(得分:0)

有效:

popup.setFocusable(false);
popup.setTouchable(true);
popup.setOutsideTouchable(false);
popup.setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));