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

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

Войти
Регистрация
Восстановить пароль
 
_Night_Scream_
75 / 74 / 8
Регистрация: 08.08.2013
Сообщений: 584
#1

DragAndDrop free on Layout - Программирование Android

13.10.2015, 18:56. Просмотров 415. Ответов 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)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.10.2015, 18:56     DragAndDrop free on Layout
Посмотрите здесь:

At android.widget.LinearLayout.setChildFrame Layout в Layout-те - Программирование Android
Нужен совет бывалых. У меня есть активити которое запускается с мейн активити, на нем лежит Layout (горизонтальный) в котором 2й...

Не хочет работать в layout, но включается в layout-land - Программирование Android
доброе утро ! пишу первое приложение. обычный мейн.хмель выглядит вот так : <?xml version="1.0" encoding="utf-8"?> <LinearLayout...

TextViews и Layout - Программирование Android
Здравствуйте! Имеется много генерируемых TextView. Как их можно поставить друг за дугом, что бы получился текст, как в обчной статье? ...

Лупа на layout - Программирование Android
Привет. В браузере наверняка все видели "лупу" когда не можете попасть по ссылке, браузер вам увеличивает эту область чтобы вы могли...

переходы layout - Программирование Android
У меня подключен такой инклюдик <include layout="@layout/content_main" /> Я показываю там layout, но как мне кодом показать...

Layout передача данных - Программирование Android
Каким способом можно передать данные из дочернего Layout в родительский? Умею только передавать данные в дочерний Layout через Intent. ...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
YuraAAA
1567 / 1309 / 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_
75 / 74 / 8
Регистрация: 08.08.2013
Сообщений: 584
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_
75 / 74 / 8
Регистрация: 08.08.2013
Сообщений: 584
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_
75 / 74 / 8
Регистрация: 08.08.2013
Сообщений: 584
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
Еще ссылки по теме:

Activity & Layout - Программирование Android
ДОбрый день! У меня есть Layout1 - это главный экран. Я создал Layout2 с некоторой информацией и разместил на нем кнопку. Нужно ли мне при...

Рисование в отдельном Layout - Программирование Android
Как по нажатию на кнопку нарисовать линию (допустим) в отдельном каком-то layout.

Смена фона layout - Программирование Android
Мне необходимо реализовать смену фона layout. Например существует два layout в main_activity, id которых lay1 и lay2 . Как мне сделать так...

Constraint Layout не работает - Программирование Android
С новым годом, добрый день!) Возникла проблема с использованием Constraint Layout. Изначально использовал Relative Layout. Потом узнал...


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

Или воспользуйтесь поиском по форуму:
_Night_Scream_
75 / 74 / 8
Регистрация: 08.08.2013
Сообщений: 584
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