Saturday, December 29, 2018

Kéo view nổi trên màn hình điện thoại




Có những khi ta cần làm một ứng dụng có view luôn nổi trên màn hình, người dùng có thể kéo lê đến bất cứ vị trí nào trên màn hình cũng được.
Hãy tạo một service, khai báo vào trong Manifest.
Trên đầu service, khai báo biến.
TextView mView;
private WindowManager wm;
int vimoix = 0;
int vimoiy = 0;
WindowManager.LayoutParams myParams;
SharedPreferences prefs;
Bên trong onCreare(), copy vào các dòng sau.
mView = new TextView(this);
mView.setText("Đây là chữ ví dụ");
         mView.setTextColor(Color.parseColor("#ffffff"));
         mView.setGravity(Gravity.CENTER);
         mView.setTextSize((float) 13.7);
         mView.setTypeface(null, Typeface.BOLD);
wm = (WindowManager) getSystemService(WINDOW_SERVICE);
prefs = PreferenceManager.getDefaultSharedPreferences(this);
         int vn = prefs.getInt("vi", 0);
         int vn2 = prefs.getInt("vi2", 0);
myParams = new WindowManager.LayoutParams(
                  LayoutParams.WRAP_CONTENT,
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                        | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                       
                /* | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON */,
                PixelFormat.RGBA_8888);
         myParams.gravity = Gravity.TOP | Gravity.CENTER_VERTICAL;
         myParams.x = vn;
         myParams.y = vn2;
myParams.setTitle("Load Average");
wm.addView(mView, myParams);
try {
    mView.setOnTouchListener(new View.OnTouchListener() {
    WindowManager.LayoutParams paramsT = myParams;
    private int initialX;
    private int initialY;
    private float initialTouchX;
    private float initialTouchY;
    private long touchStartTime = 0;
    int dem = 0;
    long duration;
    static final int MAX_DURATION = 500;

    @Override
    public boolean onTouch(View v, MotionEvent event) {
                     
    switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
    touchStartTime = System.currentTimeMillis();
    dem = dem + 1;
    initialX = myParams.x;
    initialY = myParams.y;
    initialTouchX = event.getRawX();
    initialTouchY = event.getRawY();
                           
    break;
case MotionEvent.ACTION_UP:
long time = System.currentTimeMillis() - touchStartTime;
duration = duration + time;
if (dem == 2) {
if (duration <= MAX_DURATION) {
if (event.getX() < mView.getWidth()
                                            &event.getY() > 0) {
Intent dialogIntent = new Intent(
                                   getApplicationContext(),
                                            MainActivity.class);
dialogIntent
                          .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                   startActivity(dialogIntent);
}
}
dem = 0;
duration = 0;
break;
}

case MotionEvent.ACTION_MOVE:
myParams.x = initialX + (int) (event.getRawX() - initialTouchX);
myParams.y = initialY + (int) (event.getRawY() - initialTouchY);
wm.updateViewLayout(v, myParams);
vimoix = myParams.x;
vimoiy = myParams.y;

final SharedPreferences.Editor edit = prefs.edit();
         edit.putInt("vi", vimoix);
    edit.putInt("vi2", vimoiy);
    edit.commit();
    break;
}
return false;
}
});
} catch (Exception e) {
e.printStackTrace();
}

Thêm đoạn hủy service.
@Override
    public void onDestroy() {
         super.onDestroy();
        
         if (mView != null) {
             ((WindowManager) getSystemService(WINDOW_SERVICE))
                      .removeView(mView);
             mView = null;
         }
         SharedPreferences prefs = PreferenceManager
                 .getDefaultSharedPreferences(this);
         final SharedPreferences.Editor edit = prefs.edit();
         edit.putInt("vi", vimoix);
         edit.putInt("vi2", vimoiy);
         edit.commit();
    }
View của ta có thể kéo đi đến bất cứ chỗ nào trên màn hình, khi nó dừng ở đâu ta lấy vị trí đó lưu vào SharedPreferences nên nếu thoát rồi mở lại thì vị trí sẽ vẫn được duy trì. Trong ACTION_UP ta đặt biến đếm để nếu chạm 2 lần sẽ mở ra một class mới, ở đây là MainActivity. Bạn cũng có thể sửa thành 1 để chỉ chạm một lần là mở.
Muốn view hiện được ra ngoài màn hình khóa, hãy đổi dòng LayoutParams.WRAP_CONTENT thứ 5 trong chỗ myParams = new WindowManager.LayoutParams thành LayoutParams.TYPE_SYSTEM_ERROR. Nếu chỉ cần hiện ra ngoài không cần kéo lê, có thể dùng LayoutParams.TYPE_SYSTEM_OVERLAY.

No comments:

Post a Comment