С Новым годом! Форум программистов, компьютерный форум, киберфорум
Программирование Android
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
91 / 86 / 12
Регистрация: 08.08.2013
Сообщений: 667

DragAndDrop free on Layout

13.10.2015, 18:56. Показов 1518. Ответов 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?
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
13.10.2015, 18:56
Ответы с готовыми решениями:

Анимированный дизайн смены Layout или просто выдвигаемый layout
Ну, думаю тут и так всё понятно. Я просто не знаю, какие ключевые слова вводить в гугл, всё что попадается это Drawer А мне нужнен просто...

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

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

7
 Аватар для YuraAAA
1605 / 1337 / 291
Регистрация: 25.10.2009
Сообщений: 3,487
Записей в блоге: 2
13.10.2015, 19:22
Цитата Сообщение от _Night_Scream_ Посмотреть сообщение
case DragEvent.ACTION_DROP:
* * * * * * * * * * x= (int) event.getX();
* * * * * * * * * * y= (int) event.getY();
* * * * * * * * * * Log.d(msg, "ACTION_DROP event " );
break;
мб это?
1
91 / 86 / 12
Регистрация: 08.08.2013
Сообщений: 667
14.10.2015, 21:26  [ТС]
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));
Но всеравно не то. В чем причина?
0
 Аватар для Valakin
435 / 101 / 15
Регистрация: 21.02.2015
Сообщений: 845
15.10.2015, 08:21
Пиши какие получил координаты пальца, размеры экрана.
0
91 / 86 / 12
Регистрация: 08.08.2013
Сообщений: 667
15.10.2015, 12:33  [ТС]
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  
0
91 / 86 / 12
Регистрация: 08.08.2013
Сообщений: 667
15.10.2015, 20:23  [ТС]
Как я понял всё изза action bara вверху.
Как мне работать именно с layout под баром?
0
 Аватар для Valakin
435 / 101 / 15
Регистрация: 21.02.2015
Сообщений: 845
16.10.2015, 09:06
Лучший ответ Сообщение было отмечено _Night_Scream_ как решение

Решение

сам недавно с этим сталкивался, пытался один лейаут
установить в середину другого

пишут что высоту можно узнать как ActionBar.getHeight()
http://stackoverflow.com/quest... bar-height
значит надо ее или вычесть из y или прибавить( не помню куда там координатные смотрят)
картинка всегда квадратная будет?
если нет то не логично что
view.setX(X - (view.getHeight() / 2));
где то должен быть getWidth
1
91 / 86 / 12
Регистрация: 08.08.2013
Сообщений: 667
16.10.2015, 09:40  [ТС]
Valakin, картинка абсолютно может быть произвольной длины и ширины...
view.setX(X - (view.getHeight() / 2)); блин, как я опечатался так..... пздц
Ну конечно view.setX(X - (view.getWidth() / 2)); всё, я себя сам разочаровал.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
16.10.2015, 09:40
Помогаю со студенческими работами здесь

Использование Layout в другом Layout
Нужно в одной форме использовать 2 вида Layout, причем один должен быть вложен в другой, это реально?

DragAndDrop
Как работает технология Drag_and_Drop ? Покажите на примере как происходит движение объекта в некую область. Просто хочу понять как это...

DragAndDrop
Здравствуйте. Как сделать так,что бы из одного ListBox в другой можно было перетаскивать только слова в которых только большие буквы,а в...

Осуществление DragandDrop
Доброго времени суток. У меня возникла следующая проблема при осуществлении DragAndDrop. Вот код: unit Unit1; interface ...

Позиционирование DRAGANDDROP
Доброго времени суток всем! Не могу додуматься как спозиционировать картинки друг за другом, они все сваливаются у меня в одну кучу, а надо...


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru