Перетащите кнопку на Android. Помощь - PullRequest
1 голос
/ 07 февраля 2011

Я пытаюсь перетащить кнопку, проблема в том, что когда я использую getX () в событии движения, он работает, но кнопка начинает дрожать. Когда я вызываю метод getRawX (), он не дрожит, но прыгает как минимум на 80 пикселей прямо перед началом перетаскивания.

как мне это удалось, я выложу свой код здесь:

    public class MyButton extends Button {

private final static int START_DRAGGING = 0;
private final static int STOP_DRAGGING = 1;

private int status;
private LinearLayout parentLayout;

public MyButton(Context context) {
    super(context);

}

public MyButton(Context context, AttributeSet attrs) {
    super(context, attrs);

}

public MyButton(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);

}

@Override
public boolean onTouchEvent(MotionEvent event) {


    // Log.i("teste", "Button width: " + btWidth + ", Height : "+ btHeight);

    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        status = START_DRAGGING;
        Log.i("teste", "Coordenada on ACTION_DOWN: " + (int) event.getRawX());
        break;
    case MotionEvent.ACTION_UP:
        status = STOP_DRAGGING;
        Log.i("teste", "Coordenada on ACTION_UP: " + (int) event.getRawX());
        break;
    case MotionEvent.ACTION_MOVE:
        if(status == START_DRAGGING){
            parentLayout.setPadding((int)event.getRawX(), 0,0,0);
            parentLayout.invalidate();
            Log.i("teste", "Coordenada on ACTION_MOVE: " + (int) event.getRawX());
        }                           
        break;

    }

    return true;
}

}

Ответы [ 2 ]

3 голосов
/ 07 февраля 2011

event.getX() возвращает координаты касания относительно вашего вида (кнопка), event.getRawX() возвращает координаты касания относительно дисплея, поэтому я думаю, что первый способ является правильным, если вы установите отступ для кнопка вместо макета. Но у вас все равно будет проблема «прыжка», потому что вы должны касаться кнопки, а не ее края, и при первом движении край будет помещен под ваш палец.

Я бы попробовал использовать GestureDetector, его OnGestureListener имеет метод onScroll(), который дает вам расстояние прокрутки (он запоминает последнюю позицию и дает относительное движение), так что вы можете добавить это значение для отступа, то есть вы перетаскиваете 10px => добавляете 10px отступа.

пример кода:

private GestureDetector gd =
            new GestureDetector(getContext(), new SimpleOnGestureListener() {
    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2,
                                            float distanceX, float distanceY) {
        setPadding((int)(getPaddingLeft()+distanceX),0,0,0);
    }
    @Override
    public boolean onDown(MotionEvent e) {
        return true; // else no event will be handled
    }

Я бы также добавил несколько проверок для предотвращения отрицательных или чрезмерных заполнений.

2 голосов
/ 12 февраля 2011

Я тоже работал над тем, чтобы касаться и двигать объекты. Я начал делать что-то похожее: меняя верхний и левый отступы. Довольно быстро, когда я добавил больше подвижных объектов на экран, все стало немного запутанным. Я касался одной точки на экране, и что-то еще начинало двигаться. То, что происходило, было то, что на экране было несколько перекрывающихся видов. Только вид сверху будет получать сенсорные события.

Я нашел пост, в котором предлагалось взглянуть на код запуска Android и посмотреть, как они перетаскивают. Я думаю, что их подход действительно хорош. Вы должны добавить ViewGroup для хранения ваших подвижных объектов, но это работает. Границы представлений совпадают с тем, что вы видите на экране, и вы не получите сюрпризов. События переходят в ожидаемый вами вид.

Если окажется, что у вас будет более одного подвижного объекта, вы можете взглянуть на мою запись в блоге: " Перемещение просмотров в Android " Больше объяснений об Android Launcher и исходном коде там.

...