2

Я разрабатываю floatie, аналогичный chatHead в facebook или floatie в OneNote.TranslateAnimation перемещает представление, но без анимации

Как только я его создал, мне нужно будет перенести его, коснувшись значка, но когда я перестаю перетаскивать и отпустите палец, я хочу, чтобы значок вернулся к левому краю экрана.

Использование TranslateAnimation работает, но без анимации. Значок появляется на левом краю, когда я снова касаюсь значка.

Это соответствующий код:

trackerHead.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 = params.x; 
        initialY = params.y; 
        initialTouchX = event.getRawX(); 
        initialTouchY = event.getRawY(); 
        return true; 
       case MotionEvent.ACTION_UP: 
        TranslateAnimation animation = new TranslateAnimation(
          TranslateAnimation.ABSOLUTE, params.x, 
          TranslateAnimation.ABSOLUTE, initialX, 
          TranslateAnimation.ABSOLUTE, params.y, 
          TranslateAnimation.ABSOLUTE, params.y); 
        animation.setDuration(4000); 
        animation.setRepeatCount(1); 
        animation.setInterpolator(new AccelerateInterpolator()); 
        trackerHead.startAnimation(animation); 
        params.x = initialX; 
        return true; 
       case MotionEvent.ACTION_MOVE: 
        params.x = initialX + (int) (event.getRawX() - initialTouchX); 
        params.y = initialY + (int) (event.getRawY() - initialTouchY); 
        windowManager.updateViewLayout(trackerHead, params); 
        return true; 
      } 
      return false; 
     } 
    }); 

где trackerHead является ImageView, который добавляется к экрану с помощью среднего WindowManager.

Когда принимается MotionEvent.ACTION_UP, я хочу, чтобы значок плавно возвращался к левому краю экрана.

Визуально, когда я перетаскиваю значок, а затем отпустите палец, значок остается в том же положении. Когда я снова касаюсь его, значок появляется быстро на левом краю, что является очевидной причиной «params.x = initialX;» инструкция.

Любая помощь, пожалуйста? Спасибо Jaime

+0

У меня также есть решение с Animators вместо MoveAnimator, если вы хотите. – tim

ответ

5

Я реализовал аналогичную функцию. Я получил некоторое вдохновение от bubbles for Android и Magnet, но я скорректировал его по вашему запросу.

//your imageView 
private ImageView trackerHead; 
private boolean isBeingDragged; 
private WindowManager.LayoutParams params = new WindowManager.LayoutParams(
       WindowManager.LayoutParams.WRAP_CONTENT, 
       WindowManager.LayoutParams.WRAP_CONTENT, 
       WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, 
       WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | 
         WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, 
       PixelFormat.TRANSLUCENT 
     ); 

//Constructor or entry for your WindowManager service 
public void onCreate() { 
    super.onCreate(); 

    windowManager = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE); 
    animator = new MoveAnimator(); 
    this.trackerHead.setOnTouchListener(this); 
    windowManager.addView(trackerHead, params); 
} 

@Override 
public boolean onTouch(View view, MotionEvent event) { 
    float x = event.getRaw X(); 
    float y = event.getRawY(); 

    switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      animator.stop(); 
      isBeingDragged = true; 
      break; 
     case MotionEvent.ACTION_UP: 
      isBeingDragged = false; 
      stickToLeftWall(); 
      break; 
     case MotionEvent.ACTION_MOVE: 
      if (isBeingDragged) { 
       move(x - lastXPose, y - lastYPose); 
      } 
      break; 
    } 

    lastXPose = x; 
    lastYPose = y; 

    return false; 
} 

private void stickToLeftWall() { 
    animator.start(this, 0); 
} 

Класс MoveAnimator может быть помещен как внутренний класс.

class MoveAnimator implements Runnable { 

    private Handler handler = new Handler(Looper.getMainLooper()); 
    private float destinationX; 
    private float destinationY; 
    private long startingTime; 

    private void start(float x, float y) { 
     this.destinationX = x; 
     this.destinationY = y; 
     startingTime = System.currentTimeMillis(); 
     handler.post(this); 
    } 

    @Override 
    public void run() { 
     if (trackerHead != null && trackerHead.getParent() != null) { 
      float progress = Math.min(1, (System.currentTimeMillis() - startingTime)/400f); 
      float deltaX = (destinationX - mLayoutParams.x) * progress; 
      float deltaY = (destinationY - mLayoutParams.y) * progress; 
      move(deltaX, deltaY); 
      if (progress < 1) { 
       handler.post(this); 
      } 
     } 
    } 

    private void stop() { 
     handler.removeCallbacks(this); 
    } 
} 

Важным моментом здесь является stickToLeftWall функция. Это позволит вашему ImageView всегда возвращаться к 0 по оси X. Однако, если вам нравится, вы можете получить screenWidth своего устройства и рассчитать ближайшую стену, на которую должен щелкнуть ImageView.

Предлагаю вам ознакомиться с предоставленным кодом Github.

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