在ImageView中使用Rebound API

时间:2014-09-23 07:32:43

标签: android facebook spring animation

我目前需要像Facebook一样制作ChatHeads。按照我发现的教程,我可以从Service启动ChatHead。但是,当我从Facebook添加Rebound API以使其流畅时,我创建了一个自定义视图,如以下帖子:Adding natural dragging effect to ImageView same as Facebook Messanger chat heads using Rebound library; 但它似乎阻止了每一个背景触摸。我只能拖动ChatHead而不能触及其他任何东西。如何创建一个仍然流畅的ChatHead,也可以与背景交互(与Facebook一样)?任何帮助表示赞赏。

先谢谢

BTW,这是我的看法

class ChatHeadView extends View implements SpringListener, SpringSystemListener {

private Spring xSpring;
private Spring ySpring;
private SpringSystem springSystem;
private final SpringConfig COASTING;
private float x;
private float y;
private boolean dragging;
private float radius = 100;
private float downX;
private float downY;
private float lastX;
private float lastY;
private VelocityTracker velocityTracker;
private float centerX;
private float centerY;
int screenWidth, screenHeight;

private Paint mPaint = new Paint();
private Bitmap mBitmap = BitmapFactory.decodeResource(getResources(),
        R.drawable.ic_launcher);

public ChatHeadView(Context context, int width, int height) {
    super(context);
    springSystem = SpringSystem.create();
    springSystem.addListener(this);

    COASTING = SpringConfig.fromOrigamiTensionAndFriction(0, 0.5);
    COASTING.tension = 0;

    xSpring = springSystem.createSpring();
    ySpring = springSystem.createSpring();
    xSpring.addListener(this);
    ySpring.addListener(this);

    getViewTreeObserver().addOnGlobalLayoutListener(
            new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    centerX = getWidth() / 2f;
                    centerY = getHeight() / 2f;

                    xSpring.setCurrentValue(centerX).setAtRest();
                    ySpring.setCurrentValue(centerY).setAtRest();
                    getViewTreeObserver()
                            .removeOnGlobalLayoutListener(this);

                }
            });

    screenWidth = width;
    screenHeight = height;

}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    canvas.drawBitmap(mBitmap, x - mBitmap.getWidth() / 2,
            y - mBitmap.getHeight(), mPaint);
}

@SuppressLint("Recycle")
@Override
public boolean onTouchEvent(MotionEvent event) {
    float touchX = event.getRawX();
    float touchY = event.getRawY();
    boolean ret = false;

    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        downX = touchX;
        downY = touchY;
        lastX = downX;
        lastY = downY;
        velocityTracker = VelocityTracker.obtain();
        velocityTracker.addMovement(event);
        if (downX > x - radius && downX < x + radius && downY > y - radius
                && downY < y + radius) {
            dragging = true;
            ret = true;
        }
        break;
    case MotionEvent.ACTION_MOVE:
        if (!dragging) {
            break;
        }
        velocityTracker.addMovement(event);
        float offsetX = lastX - touchX;
        float offsetY = lastY - touchY;
        xSpring.setCurrentValue(xSpring.getCurrentValue() - offsetX)
                .setAtRest();
        ySpring.setCurrentValue(ySpring.getCurrentValue() - offsetY)
                .setAtRest();
        checkConstraints();
        ret = true;
        break;
    case MotionEvent.ACTION_UP:
    case MotionEvent.ACTION_CANCEL:
        if (!dragging) {
            break;
        }
        velocityTracker.addMovement(event);
        velocityTracker.computeCurrentVelocity(1000);
        dragging = false;
        ySpring.setSpringConfig(COASTING);
        xSpring.setSpringConfig(COASTING);
        downX = 0;
        downY = 0;
        xSpring.setVelocity(velocityTracker.getXVelocity());
        ySpring.setVelocity(velocityTracker.getYVelocity());
        ret = true;
    }

    lastX = touchX;
    lastY = touchY;
    return ret;
}

@Override
public void onSpringUpdate(Spring s) {
    x = (float) xSpring.getCurrentValue();
    y = (float) ySpring.getCurrentValue();
    invalidate();
}

@Override
public void onSpringActivate(Spring s) {
}

@Override
public void onSpringAtRest(Spring s) {
}

@Override
public void onSpringEndStateChange(Spring s) {
}

@Override
public void onBeforeIntegrate(BaseSpringSystem springSystem) {

}

@Override
public void onAfterIntegrate(BaseSpringSystem springSystem) {
    checkConstraints();
}

private void checkConstraints() {
    if (x + radius >= screenWidth) {
        xSpring.setVelocity(-xSpring.getVelocity());
        xSpring.setCurrentValue(xSpring.getCurrentValue()
                - (x + radius - screenWidth), false);
    }
    if (x - radius <= 0) {
        xSpring.setVelocity(-xSpring.getVelocity());
        xSpring.setCurrentValue(xSpring.getCurrentValue() - (x - radius),
                false);
    }
    if (y + radius >= screenHeight) {
        ySpring.setVelocity(-ySpring.getVelocity());
        ySpring.setCurrentValue(ySpring.getCurrentValue()
                - (y + radius - screenHeight), false);
    }
    if (y - radius <= 0) {
        ySpring.setVelocity(-ySpring.getVelocity());
        ySpring.setCurrentValue(ySpring.getCurrentValue() - (y - radius),
                false);
    }

}

}

这是我用WindowManager添加View的地方:

windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
screenWidth = size.x;
screenHeight = size.y;
chatHeadView = new ChatHeadView(this, screenWidth, screenHeight);

final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
    WindowManager.LayoutParams.WRAP_CONTENT,
    WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_PHONE,
    WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
          | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, PixelFormat.TRANSLUCENT);

windowManager.addView(chatHeadView, params);

1 个答案:

答案 0 :(得分:0)

在文档WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL

  

窗口标志:即使此窗口是可聚焦的(其未设置FLAG_NOT_FOCUSABLE),也允许将窗口外的任何指针事件发送到其后面的窗口。否则它将消耗所有指针事件本身,无论它们是否在窗口内。

它说的是你的问题。

而是尝试 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 标志。 你可以在视图上获得TouchEvent,它不会消耗其他事件。