Android: как перетащить (переместить) PopupWindow?
Я хочу, чтобы иметь возможность перемещать PopupWindow на сенсорное перетаскивание. Я не хочу, чтобы пользовательский интерфейс обновлялся после выпуска сенсорного экрана. Я хочу, чтобы PopupWindow следил за моим прикосновением.
Это то, что я делаю:
mView = mLayoutInflater.inflate(R.layout.popup,
null);
mPopupWindow = new PopupWindow(mView,
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, false);
mPopupWindow.showAtLocation(parentView, Gravity.CENTER, -5, 30);
mView.setOnTouchListener(new OnTouchListener() {
private int dx = 0;
private int dy = 0;
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
dx = (int) motionEvent.getX();
dy = (int) motionEvent.getY();
break;
case MotionEvent.ACTION_MOVE:
int x = (int) motionEvent.getX();
int y = (int) motionEvent.getY();
int left = (x - dx);
int top = (y - dy);
Log.d("test", "x: " + left + " y: " + top);
mPopupWindow.update(left, top, -1, -1);
break;
}
return true;
}
});
Что происходит, когда я перетаскиваю всплывающее окно, оно мерцает взад и вперед в исходном месте и там, где находится мой палец.
Мерцающий Logcat Результат:
x: -44 y: 4
x: -43 y: 37
x: -46 y: 4
x: -46 y: 38
x: -48 y: 4
x: -47 y: 38
x: -50 y: 4
Но если я удалю (закомментирую) "mPopupWindow.update(left, top, -1, -1);", он вернет правильный результат. (Но очевидно, что пользовательский интерфейс не будет обновляться):
x: -33 y: 0
x: -37 y: 0
x: -41 y: 0
x: -43 y: 3
x: -46 y: 3
x: -50 y: 3
x: -54 y: 4
x: -57 y: 4
Как правильно переместить PopupWindow?
3 ответа
В eclipse, глядя на информацию о getX(), он говорит: getX(int) для первого указателя указателя. Я предполагаю, что это должно использоваться только при установке первых x и y для ACTION.DOWN. При использовании ACTION.MOVE, getRawX() и getRawY(), eclipse говорит: исходное местоположение события на экране. Используя его таким образом, всплывающее окно не будет мерцать и останется на своем месте после перемещения, пока не будет закрыто.
Обновленный код:
case MotionEvent.ACTION_DOWN:
dx = (int) event.getX();
dy = (int) event.getY();
break;
case MotionEvent.ACTION_MOVE:
xp = (int) event.getRawX();
yp = (int) event.getRawY();
sides = (xp - dx);
topBot = (yp - dy);
popup.update(sides, topBot, -1, -1, true);
break;
Попробуй это:
mView = mLayoutInflater.inflate(R.layout.popup,
null);
mPopupWindow = new PopupWindow(mView,
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, false);
mPopupWindow.showAtLocation(parentView, Gravity.CENTER, mPosX, mPosY);
mView.setOnTouchListener(new OnTouchListener() {
private int dx = 0;
private int dy = 0;
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
dx = mPosX - motionEvent.getRawX();
dy = mPosY - motionEvent.getRawY();
break;
case MotionEvent.ACTION_MOVE:
mPosX = (int) (motionEvent.getRawX() + dx);
mPosY = (int) (motionEvent.getRawY() + dy);
pop.update(mPosX, mPosY, -1, -1);
break;
}
return true;
}
});
Попробуйте getRawX() и getRawY() вместо getX() и getX(). Он все еще слегка подпрыгивает, когда вы снова к нему прикасаетесь, но гораздо плавнее при движении. Если у вас есть лучшее решение, пожалуйста, сообщите нам.