Форум программистов, компьютерный форум CyberForum.ru

Программирование Android

Войти
Регистрация
Восстановить пароль
 
_Night_Scream_
57 / 69 / 7
Регистрация: 08.08.2013
Сообщений: 560
#1

DragAndDrop free on Layout - Android

13.10.2015, 18:56. Просмотров 408. Ответов 7
Метки нет (Все метки)

Привет, честно искал, но того, что нужно, не нашел.

Я хочу перетаскивать view элементы по экрану, свободно, те примеры что нашел рассказывают как получить событие при перетаскивании элемента из одного laytout в другой.

Значит есть например ImageView. Нарыл в гугле.
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
img = (ImageView) findViewById(R.id.imgView);
 
img.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            ClipData.Item item = new ClipData.Item((CharSequence) v.getTag());
            String[] mimeTypes = { ClipDescription.MIMETYPE_TEXT_PLAIN };
            ClipData dragData = new ClipData(v.getTag().toString(), mimeTypes, item);
 
            // Instantiates the drag shadow builder.
            View.DragShadowBuilder myShadow = new View.DragShadowBuilder(img);
 
            // Starts the drag
            v.startDrag(dragData, // the data to be dragged
                    myShadow, // the drag shadow builder
                    null, // no need to use local data
                    0 // flags (not currently used, set to 0)
            );
            return true;
        }
    });
Из всего этого понимаю только создание тени и v.startDrag, остальное для меня магия, поясните если кто понимает.
дальше....
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// Set the drag event listener for the View
    img.setOnDragListener(new View.OnDragListener() {
        @Override
        public boolean onDrag(View v, DragEvent event) {
            switch (event.getAction()) {
                case DragEvent.ACTION_DRAG_STARTED:
                    layoutParams = (RelativeLayout.LayoutParams) v.getLayoutParams();
                    RelativeLayout.LayoutParams.WRAP_CONTENT);
                    x = (int) event.getX();
                    y = (int) event.getY();
                    Log.d(msg, "Action is DragEvent.ACTION_DRAG_STARTED " + x + " " + y);
                    break;
                case DragEvent.ACTION_DRAG_ENTERED:
                    Log.d(msg, "Action is DragEvent.ACTION_DRAG_ENTERED");
                    x = (int) event.getX();
                    y = (int) event.getY();
                    break;
                case DragEvent.ACTION_DRAG_EXITED:
                    Log.d(msg, "Action is DragEvent.ACTION_DRAG_EXITED");
                    x = (int) event.getX();
                    y = (int) event.getY();
                    break;
                case DragEvent.ACTION_DRAG_LOCATION:
                    Log.d(msg, "Action is DragEvent.ACTION_DRAG_LOCATION");
                    break;
                case DragEvent.ACTION_DRAG_ENDED:
                    if (dropEventNotHandled(event)) {
                        layoutParams.setMargins(x, y, 0, 0);
                        Log.d(msg, "end " + v.getX() + " " + v.getY());
                        v.setLayoutParams(layoutParams);
                    }
 
                    break;
                case DragEvent.ACTION_DROP:
                    x= (int) event.getX();
                    y= (int) event.getY();
                    Log.d(msg, "ACTION_DROP event " );
 
                    break;
                default:
                    break;
            }
            return true;
        }
    });
 private boolean dropEventNotHandled(DragEvent dragEvent) {
        return !dragEvent.getResult();
    }
Тут вижу когда происходит то или иное событие, знаю когда пользователь отпустил view, но где он его отпустил координаты получить не могу, на стаке есть не один такой вопрос, но ответа нет.

Еще вопрос, насколько я понял реализовать можно мою задачу только на RelativeLayout. Это так?
И перемещение view осуществлять через setMargins?
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
YuraAAA
1565 / 1307 / 269
Регистрация: 25.10.2009
Сообщений: 3,424
Записей в блоге: 2
13.10.2015, 19:22     DragAndDrop free on Layout #2
Цитата Сообщение от _Night_Scream_ Посмотреть сообщение
case DragEvent.ACTION_DROP:
* * * * * * * * * * x= (int) event.getX();
* * * * * * * * * * y= (int) event.getY();
* * * * * * * * * * Log.d(msg, "ACTION_DROP event " );
break;
мб это?
_Night_Scream_
57 / 69 / 7
Регистрация: 08.08.2013
Сообщений: 560
14.10.2015, 21:26  [ТС]     DragAndDrop free on Layout #3
YuraAAA, да, отсюда брать, спасибо.

Но появилась другая проблема.
При отпускании картинка становится намного ниже, чем были координаты пальца.
Вот весь код.

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class MainActivity extends AppCompatActivity implements View.OnTouchListener, View.OnDragListener {
    String LOGCAT = "scream";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.ImgDrop).setOnTouchListener(this);
        findViewById(R.id.ImgDrop).getRootView().setOnDragListener(this);
    }
 
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
            View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
            view.startDrag(null, shadowBuilder, view, 0);
            view.setVisibility(View.INVISIBLE);
            return true;
        } else {
            return false;
        }
    }
 
    public boolean onDrag(View v, DragEvent event) {
        switch (event.getAction()) {
            case DragEvent.ACTION_DROP:
 
                float X = event.getX();
                float Y = event.getY();
 
                Log.d(LOGCAT, "X " + (int) X + " Y " + (int) Y);
                View view = (View) event.getLocalState();
                Log.d(LOGCAT, "View x: " + view.getX() + "  y: " + view.getY() + " | выстота " + view.getHeight() + " ширина " + view.getWidth());//ширина и высота 144
                view.setX(X - view.getHeight()/2);
                view.setY(Y - view.getHeight()/2);
 
                view.setVisibility(View.VISIBLE);
                break;
            default:
                break;
        }
        return true;
    }
}
Добавлено через 13 часов 41 минуту
Никак не получается отцентровать image, что не так?

Добавлено через 11 часов 23 минуты
Млять 68 просмотров, а толку....
В гугле еще нашел такое.

Java
1
view.setY(Y - (float) (view.getHeight() * 1.5 / 2));
Но всеравно не то. В чем причина?
Valakin
430 / 96 / 15
Регистрация: 21.02.2015
Сообщений: 729
15.10.2015, 08:21     DragAndDrop free on Layout #4
Пиши какие получил координаты пальца, размеры экрана.
_Night_Scream_
57 / 69 / 7
Регистрация: 08.08.2013
Сообщений: 560
15.10.2015, 12:33  [ТС]     DragAndDrop free on Layout #5
Valakin, я включил в настройках телефона "Для разработчиков" пункт "Отображать касания"
Вот мои испытания.
На скринах буду двигать всегда слево направо.

Весь код.
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import android.graphics.Point;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Display;
import android.view.DragEvent;
import android.view.MotionEvent;
import android.view.View;
 
public class MainActivity extends AppCompatActivity implements View.OnTouchListener, View.OnDragListener {
    String LOGCAT = "scream";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.ImgDrop).setOnTouchListener(this);
        findViewById(R.id.ImgDrop).getRootView().setOnDragListener(this);
    }
 
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
            View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
            view.startDrag(null, shadowBuilder, view, 0);
            view.setVisibility(View.INVISIBLE);
            return true;
        } else {
            return false;
        }
    }
 
    public boolean onDrag(View v, DragEvent event) {
        switch (event.getAction()) {
            case DragEvent.ACTION_DRAG_STARTED:
 
                Display display = getWindowManager().getDefaultDisplay();
                Point size = new Point();
                display.getSize(size);
                int width = size.x;
                int height = size.y;
 
                int x = (int)event.getX();
                int y = (int)event.getY();
                Log.d(LOGCAT,"Старт. Касание x: " + x + " y: " + y);
                Log.d(LOGCAT,"Размер экрана. ширина: " + width + " высота: " + height);
                break;
 
            case DragEvent.ACTION_DROP:
                float X = event.getX();
                float Y = event.getY();
                Log.d(LOGCAT, "Отпустил: X: " + (int) X + " Y: " + (int) Y);
 
                View view = (View) event.getLocalState();
                view.setX(X);
                view.setY(Y);
 
                view.setVisibility(View.VISIBLE);
 
                Log.d(LOGCAT, "Картинка: X: " + view.getX() + " Y: " + view.getY());
                break;
            default:
                break;
        }
        return true;
    }
}
Дальше буду менять только метод onDrag и код события case DragEvent.ACTION_DROP.

Значит с этим кодом

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
case DragEvent.ACTION_DROP:
                float X = event.getX();
                float Y = event.getY();
                Log.d(LOGCAT, "Отпустил: X: " + (int) X + " Y: " + (int) Y);
 
                View view = (View) event.getLocalState();
                view.setX(X);
                view.setY(Y);
 
                view.setVisibility(View.VISIBLE);
 
                Log.d(LOGCAT, "Картинка: X: " + view.getX() + " Y: " + view.getY());
                break;
я ожидаю появление картинки от X вправо, от Y вниз, ну всегда считал что левый верхний угол будет.
Вот что получается (скрин 1).
Тоесть по оси Y картинка установилась в координата отпускания + высота картинки

Log получается такой
10-15 12:13:20.252 D/scream﹕ Старт. Касание x: 62 y: 230
10-15 12:13:20.253 D/scream﹕ Размер экрана. ширина: 1280 высота: 720
10-15 12:13:21.440 D/scream﹕ Отпустил: X: 529 Y: 314
10-15 12:13:21.444 D/scream﹕ Картинка: X: 529.58624 Y: 314.5631

На самом деле картинка появилась ниже по Y чем 314.

Теперь чтобы найти центр картинки судя по логу выше нужно сделать так:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
 case DragEvent.ACTION_DROP:
                float X = event.getX();
                float Y = event.getY();
                Log.d(LOGCAT, "Отпустил: X: " + (int) X + " Y: " + (int) Y);
 
                View view = (View) event.getLocalState();
                view.setX(X - (view.getHeight() / 2));
                view.setY(Y - view.getHeight() - (view.getHeight() / 2));
 
                view.setVisibility(View.VISIBLE);
 
                Log.d(LOGCAT, "Картинка: X: " + view.getX() + " Y: " + view.getY());
                break;
Получается 2й скрин.
Логи:
10-15 12:29:02.355 D/scream﹕ Старт. Касание x: 58 y: 224
10-15 12:29:02.355 D/scream﹕ Размер экрана. ширина: 1280 высота: 720
10-15 12:29:03.391 D/scream﹕ Отпустил: X: 383 Y: 353
10-15 12:29:03.393 D/scream﹕ Картинка: X: 311.70023 Y: 137.50903

Центр по Y удалось получить только координата отпускания по Y минус полторы высоты картинки

А если взять картинку с другими данными, не изменится ли поведение?
Да и вообще почему картинка появляется ниже на одну высоту этой картинки?
Миниатюры
DragAndDrop free on Layout   DragAndDrop free on Layout  
_Night_Scream_
57 / 69 / 7
Регистрация: 08.08.2013
Сообщений: 560
15.10.2015, 20:23  [ТС]     DragAndDrop free on Layout #6
Как я понял всё изза action bara вверху.
Как мне работать именно с layout под баром?
Valakin
430 / 96 / 15
Регистрация: 21.02.2015
Сообщений: 729
16.10.2015, 09:06     DragAndDrop free on Layout #7
Сообщение было отмечено автором темы, экспертом или модератором как ответ
сам недавно с этим сталкивался, пытался один лейаут
установить в середину другого

пишут что высоту можно узнать как ActionBar.getHeight()
http://stackoverflow.com/questions/1...tionbar-height
значит надо ее или вычесть из y или прибавить( не помню куда там координатные смотрят)
картинка всегда квадратная будет?
если нет то не логично что
view.setX(X - (view.getHeight() / 2));
где то должен быть getWidth
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.10.2015, 09:40     DragAndDrop free on Layout
Еще ссылки по теме:

Android Перерисовка layout
Квадратный Layout Android
Android переходы layout
Layout Android
Лупа на layout Android

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
_Night_Scream_
57 / 69 / 7
Регистрация: 08.08.2013
Сообщений: 560
16.10.2015, 09:40  [ТС]     DragAndDrop free on Layout #8
Valakin, картинка абсолютно может быть произвольной длины и ширины...
view.setX(X - (view.getHeight() / 2)); блин, как я опечатался так..... пздц
Ну конечно view.setX(X - (view.getWidth() / 2)); всё, я себя сам разочаровал.
Yandex
Объявления
16.10.2015, 09:40     DragAndDrop free on Layout
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru