TranslateAnimation移动视图,但没有动画

jst*_*rdo 2 android android-layout translate-animation android-windowmanager

我正在开发一个浮动,类似于facebook中的chatHead或OneNote中的浮动.

一旦我创建了它,我需要能够通过触摸图标来移动它,但当我停止拖动并释放手指时,我希望图标返回到屏幕的左边缘.

通过使用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;
        }
    });
Run Code Online (Sandbox Code Playgroud)

trackerHead是一个ImageView,通过WindowManager添加到屏幕上.

收到MotionEvent.ACTION_UP时,我希望图标顺利返回到屏幕的左边缘.

在视觉上,当我拖动图标,然后松开手指时,图标保持在相同的位置.当我再次触摸它时,图标在左边缘快速出现,这是"params.x = initialX"的明显原因.指令.

有什么帮助吗?谢谢Jaime

tim*_*tim 5

我实现了类似的功能.我从AndroidMagnet的泡泡中获得了一些灵感,但我根据您的要求进行了调整.

//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); 
}
Run Code Online (Sandbox Code Playgroud)

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这里重要的是stickToLeftWall功能.它会让你的ImageView始终在X轴上返回0.但是,如果您愿意,可以获取screenWidth设备并计算ImageView应捕捉的最近墙.

我建议你看看提供的Github代码.