我目前需要像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);
答案 0 :(得分:0)
在文档WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
中窗口标志:即使此窗口是可聚焦的(其未设置FLAG_NOT_FOCUSABLE),也允许将窗口外的任何指针事件发送到其后面的窗口。否则它将消耗所有指针事件本身,无论它们是否在窗口内。
它说的是你的问题。
而是尝试 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 标志。 你可以在视图上获得TouchEvent,它不会消耗其他事件。