2013-08-29 2 views
2

Я хочу создать оповещение системы с функцией перетаскивания, которая всегда находится поверх всего приложения. Я создал окно системного предупреждения, но не смог выполнить функцию перетаскивания. Пожалуйста, помогите найти правильное решение.Как создать системное предупреждение Draggabble в Android?

ответ

6

вы можете использовать WindowManager, чтобы добавить поплавок с указанным WindowManager.LayoutParams и переопределить 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; 
} 

}

И тогда вы можете добавить этот вид поплавка к 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); 

} 
Смежные вопросы