Android使用WindowManager显示浮动视图,点击外部消失并且事件可以传递。

3

Android中使用WindowManager时遇到了一个问题,就是在Activity之上有一个浮动视图。这个浮动视图和Activity属于两个不同的应用程序,因此无法更改该Activity。

如何实现这一效果:

点击浮动视图之外的屏幕,浮动视图会消失,并且点击事件将传递给Activity。例如,空白处有一个按钮,点击按钮下方,浮动视图消失,按钮可点击;或者有一个EditText,单击后浮动视图消失,可以输入EditText。

请告诉我如何进行监听或拦截事件,或者给我另一种解决方法。

1个回答

0
首先为您使用的视图的根视图定义一个id。
private final String TAG = "MOVING POPUP"; 
private WindowManager.LayoutParams params;
private WindowManager.LayoutParams paramsF;
private View mView;
private boolean isViewVisible = false;
private WindowManager windowManager;

private long pressStartTime;
private float pressedX;
private float pressedY;
private boolean stayedWithinClickDistance;
/**
 * Max allowed duration for a "click", in milliseconds.
 */
private static final int MAX_CLICK_DURATION = 1000;

/**
 * Max allowed distance to move during a "click", in DP.
 */
private static final int MAX_CLICK_DISTANCE = 15;

private void createView() 
{
    windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
    LayoutInflater inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    mView = inflater.inflate(R.layout.dialog_book_text_selection_main, null, false);
    View mdismiss = mView.findViewById(R.id.btnApply);
    View llRoot = mView.findViewById(R.id.llRoot);
    try 
    {
        mView.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v) 
            {
                removeView();
            }
        });

        mdismiss.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v) 
            {
                removeView();
            }
        });

        llRoot.setOnTouchListener(new View.OnTouchListener() {
            private int initialX;
            private int initialY;
            private float initialTouchX;
            private float initialTouchY;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:

                        initialX = paramsF.x;
                        initialY = paramsF.y;
                        initialTouchX = event.getRawX();
                        initialTouchY = event.getRawY();

                        pressStartTime = System.currentTimeMillis();
                        pressedX = event.getX();
                        pressedY = event.getY();
                        stayedWithinClickDistance = true;

                        break;
                    case MotionEvent.ACTION_UP:

                        long pressDuration = System.currentTimeMillis() - pressStartTime;
                        if (pressDuration < MAX_CLICK_DURATION && stayedWithinClickDistance) 
{
perform your on click event here
                           }

                    case MotionEvent.ACTION_POINTER_UP:
                        break;
                    case MotionEvent.ACTION_MOVE:

                        if (stayedWithinClickDistance && distance(pressedX, pressedY, event.getX(), event.getY()) > MAX_CLICK_DISTANCE) {
                            stayedWithinClickDistance = false;
                        }

                        paramsF.x = initialX + (int) (event.getRawX() - initialTouchX);
                        paramsF.y = initialY + (int) (event.getRawY() - initialTouchY);
                        windowManager.updateViewLayout(mView, paramsF);

                        break;
                }
                return true;
            }
        });
    } catch (Exception e) {
        e.printStackTrace();
        Log.e(TAG, "ON TOUCH ERROR--->" + e.getMessage());
    }

    setViewPosition();
    addView();
}

private float distance(float x1, float y1, float x2, float y2) {
    float dx = x1 - x2;
    float dy = y1 - y2;
    float distanceInPx = (float) Math.sqrt(dx * dx + dy * dy);
    return pxToDp(distanceInPx);
}

private float pxToDp(float px) {
    return px / activity.getResources().getDisplayMetrics().density;
}

private void addView() 
{
    if (mView != null && !isViewVisible) 
    {
        isViewVisible = true;
        setViewPosition();
        windowManager.addView(mView, params);
    }
}

private void removeView()
{
    try {
        if (mView != null && isViewVisible)
        {
            windowManager.removeView(mView);
            isViewVisible = false;
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private void setViewPosition() 
{
    params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG,
            WindowManager.LayoutParams.FLAG_FULLSCREEN,
            PixelFormat.TRANSLUCENT);

    params.gravity = Gravity.CENTER;
    params.x = 0;
    params.y = 0;

    paramsF = params;
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
    if (keyCode == KeyEvent.KEYCODE_BACK)
    {
        if (isViewVisible)
        {
            removeView();
            return true;
        }
    }
    return super.onKeyDown(keyCode, event);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接