我想创建具有拖放功能的系统警报,该功能始终位于所有应用程序的顶部。我创建了系统警报窗口,但无法提供拖放功能。请帮助找到正确的解决方案。

最佳答案

您可以使用 WindowManager 添加具有指定 WindowManager.LayoutParams 的 float View ,并覆盖 float View 的 onTouchEvent
这是代码:

public class FloatView extends View {
private WindowManager wm;
private WindowManager.LayoutParams params;

Activity mActivity;
DisplayMetrics metrics;

float x;
float y;
float touchX;
float touchY;

public FloatView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    mActivity = (Activity) context;
    wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    params = new WindowManager.LayoutParams();
    metrics = new DisplayMetrics();
    wm.getDefaultDisplay().getMetrics(metrics);

}

public FloatView(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public FloatView(Context context) {
    this(context, null);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    x = event.getRawX();
    y = event.getRawY();
    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        touchX = event.getX();
        touchY = event.getY();

        break;
    case MotionEvent.ACTION_MOVE:
        updateViewPostion();
        break;
    case MotionEvent.ACTION_CANCEL:
    case MotionEvent.ACTION_UP:
        animateToEdge();
        touchX = touchY = 0;
        break;
    default:
        break;
    }

    return super.onTouchEvent(event);
}

private void animateToEdge() {
    int currentX = (int) (x - touchX);
    ValueAnimator ani;
    if (currentX > metrics.widthPixels / 2) {
        ani = ValueAnimator.ofInt(currentX, metrics.widthPixels - getMeasuredWidth());
    } else {
        ani = ValueAnimator.ofInt(currentX, 0);

    }
    params.y = Math.min(Math.max(0, (int) (y - touchY)),
            metrics.heightPixels - getMeasuredHeight());

    ani.addUpdateListener(new AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            params.x = (Integer) animation.getAnimatedValue();
            wm.updateViewLayout(FloatView.this, params);
        }
    });
    ani.setDuration(200l);
    ani.setInterpolator(new AccelerateDecelerateInterpolator());
    ani.start();

}

private void updateViewPostion() {

    params.x = Math.min(Math.max(0, (int) (x - touchX)), metrics.widthPixels - getMeasuredWidth());
    params.y = Math.min(Math.max(0, (int) (y - touchY)),
            metrics.heightPixels - getMeasuredHeight());

    wm.updateViewLayout(this, params);
}

public WindowManager.LayoutParams getWindowManagerLayoutParams() {
    return params;
}

}

然后你可以在你的 Activity 中将此 float View 添加到 WindowManager 中:
private void showFloatView() {
    FloatView mFloatView = new FloatView(this);
    mFloatView.setBackgroundResource(R.drawable.btn_facebook);
    WindowManager wm = getWindowManager();
    WindowManager.LayoutParams params = mFloatView.getWindowManagerLayoutParams();
    params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
    params.format=1;

    params.flags = params.flags | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;

    params.alpha = 1.0f;

    params.gravity=Gravity.LEFT|Gravity.TOP;
    params.x=0;
    params.y=0;

    params.width=WindowManager.LayoutParams.WRAP_CONTENT;
    params.height=WindowManager.LayoutParams.WRAP_CONTENT;
    wm.addView(mFloatView, params);

}

关于android - 如何在 Android 中创建 Draggable 系统警报?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18503050/

10-13 04:36