J2J.RU - cовременная система продвижения сайтов
Меню сайта

Категории раздела

Наш опрос
Какой у Вас Андроид
Всего ответов: 192

Файлы
Новые Популярные Лучшие


Теги
Android (34)
uCoz (8)
mobile (3)
sistem (3)
xml (3)
google (2)
html (2)
Oboi (2)
opera (2)
Rest (2)
soap (2)
action (1)
ajax (1)
App2SD (1)
apps (1)
CSS (1)
Ddms (1)
editor (1)
gmail (1)
gobook (1)
java (1)
legend (1)
Lite (1)
live (1)
mp3 (1)
mrtm (1)
Muse (1)
ninja (1)
pdf (1)
php (1)
Root (1)
sensor (1)
shazam (1)
sql (1)
thread (1)
touch (1)
UI (1)
Widget (1)
Worms (1)
Xplore (1)
Zirco (1)

RSS
  
Новостная лента.

Форумная лента.

Файловая лента.  

Главная » Статьи » Программинг » Программирование [ Добавить статью ]

Технология Drag and Drop в Android

Недавно у меня появилась идея заняться разработкой игры для андроид. Для начала  я решил написать шахматы. Мне казалось технология Drag and Drop отлично подойдет для реализации механизма перемещения фигур. Для непосвященных отмечу, что метод drag and drop заключается в возможности перетаскивания одних графических объектов на другие и выполнения того или иного действия после отпускания. Простейший пример - удаление ярлыка с рабочего стола вашего ПК перетаскиванием его в корзину. "Кинув" ярлык в корзину, мы говорим системе, что хотим заставить взаимодействовать эти два объекта. Система получает наш сигнал и решает, какое действие ей стоит предпринять. Drag and drop получила широкое распространение благодаря своей интуитивной ясности. Этот подход подкреплен нашим опытом взаимодействия с объектами реального мира и прекрасно работает в виртуальной среде. Что же касается шахмат, с помощью drag and drop технологически проще определить клетку, куда пользователь перетащил фигуру, поскольку не нужно вычислять номер клетки по координатам точки отпускания. Эту работу возьмет на себя виртуальная машина.

Цели использования технологии Drag n Drop

Использование технологии drag and drop позволяет мне малой кровью решить три задачи:

  1. Визуализация хода. Когда пользователь касается фигуры и начинает ее перемещение по экрану, фигура заменяется более мелким рисунком. Таким образом, пользователь понимает что фигура захвачена.
  2. Я ограничил область перемещения фигуры размерами доски.
  3. Если пользователь отпустил фигуру в неправильном месте, она должна вернуться в первоначальное положение.


Задачи обозначены, приступим к их реализации.

Подмена ImageView при касании


Все мои фигуры представляют собой объекты ImageView. К сожалению, оказалось что реализация Drag & Drop в Android не позволяет "прямо из коробки" осуществлять подмену изображения объекта при его касании. Тем не менее, эта задача вполне решаема средствами API. Нам понадобится выполнить ряд несложных действий:

  1. Создать объект  DragShadowBuilder.
  2. Вызвать метод startDrag.
  3. Спрятать наш ImageView, который отображает фигуру, вызвав метод setVisibility с параметром View.INVISIBLE. В результате на экране останется только объект DragShadowBuilder, что будет сигналом пользователю о захвате фигуры.


Эти действия необходимо реализовать в обработчике OnTouchListner объекта  ImageView. Для этого переопределим метод onTouch:

@Override
 public boolean onTouch(View view, MotionEvent motionEvent) {
 if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
 ClipData clipData = ClipData.newPlainText("", "");
 View.DragShadowBuilder dsb = new View.DragShadowBuilder(view);
 view.startDrag(clipData, dsb, view, 0);
 view.setVisibility(View.INVISIBLE);
 return true;
 } else {
 return false;
 }
 }

Все очень просто. Итак, с подменой изображения разобрались, перейдем к следующей задаче.

Ограничение области перетаскивания для функции drag drop

Ограничение области перетаскивания связано с одной проблемой. Дело в том, что если отпустить фигуру за пределами доски, события drop не случится, поскольку пользователь отпустил объект на пустом месте, и объекту не с чем взаимодействовать. В результате фигура не вернется в свое первоначальное состояние и так и останется навсегда спрятанной. Я убил уйму времени на чтение документации, но так и не нашел способа ограничить область перетаскивания объектов. Озарение пришло внезапно. Мне совсем не нужно ограничивать область, мне нужно узнать правильно ли пользователь отпустил фигуру или нет.

Определение правильности отпускания
Ответы на свои вопросы я нашел в разделе "handling drag end events" на сайте Android Developers. Вот несколько ключевых моментов:

  1. Когда пользователь завершает перетаскивание в обработчике DragListeners генерируется событие  ACTION_DRAG_ENDED.
  2. В DragListener можно получить более подробную информацию об операции drag, вызвав метод DragEvent.getResult().
  3. Если DragListener возвращает true в ответ на событие ACTION_DROP, вызов getResult также вернет true, в противном случае - false.


Таким образом, мне нужно перехватить событие ACTION_DRAG_ENDED и вызывать метод getResult. Если он вернет false, значит пользователь утащил фигуру за пределы доски, и мне нужно перевести ImageView в видимый режим.

@Override
 public boolean onDrag(View view, DragEvent dragEvent) {
 int dragAction = dragEvent.getAction();
 View dragView = (View) dragEvent.getLocalState();
 if (dragAction == DragEvent.ACTION_DRAG_EXITED) {
 containsDragable = false;
 } else if (dragAction == DragEvent.ACTION_DRAG_ENTERED) {
 containsDragable = true;
 } else if (dragAction == DragEvent.ACTION_DRAG_ENDED) {
 if (dropEventNotHandled(dragEvent)) {
 dragView.setVisibility(View.VISIBLE);
 }
 } else if (dragAction == DragEvent.ACTION_DROP && containsDragable) {
 checkForValidMove((ChessBoardSquareLayoutView) view, dragView);
 dragView.setVisibility(View.VISIBLE);
 }
 return true;
 }
 
 private boolean dropEventNotHandled(DragEvent dragEvent) {
 return !dragEvent.getResult();
 }

Теперь пользователь может где угодно отпускать фигуру, и ничего страшного не произойдет. 

Определение допустимых ходов


Последняя часть статьи посвящена проверке допустимости хода, который пытается сделать пользователь. Прежде чем подробно приступить к обсуждению этой темы, сделаю небольшую ремарку, объясняющую структуру моего приложения. Шахматная доска представлена как  TableLayout, а каждая клетка является потомком LinearLayout  и имеет OnDragListener.

Кроме того, каждый OnDragListener ссылается на объект "посредника" (mediator), который заботится о взаимодействии игровых объектов и запоминает положение текущей клетки.

Когда пользователь тащит фигуру над клеткой, возможны следующие действия:

  1. Использование события ACTION_DRAG_ENTERED для установки переменной  ‘containsDraggable’ в true.
  2. Использование события ACTION_DRAG_EXITED  для установки переменной  ‘containsDraggable’ в false.
  3. Использование события ACTION_DROP для запроса посредника о допустимости установки фигуры в эту клетку.


Ниже приведен код, реализующий описанную логику

@Override
 public boolean onDrag(View view, DragEvent dragEvent) {
 int dragAction = dragEvent.getAction();
 View dragView = (View) dragEvent.getLocalState();
 if (dragAction == DragEvent.ACTION_DRAG_EXITED) {
 containsDragable = false;
 } else if (dragAction == DragEvent.ACTION_DRAG_ENTERED) {
 containsDragable = true;
 } else if (dragAction == DragEvent.ACTION_DRAG_ENDED) {
 if (dropEventNotHandled(dragEvent)) {
 dragView.setVisibility(View.VISIBLE);
 }
 } else if (dragAction == DragEvent.ACTION_DROP && containsDragable) {
 checkForValidMove((ChessBoardSquareLayoutView) view, dragView);
 dragView.setVisibility(View.VISIBLE);
 }
 return true;
 }

Как видите, не зависимо от того допустим ли ход или нет, ImageView переводится в видимое состояние. Я хотел, чтобы пользователь видел, как перемещается фигура. Ранее я упоминал, что клетка является потомком  LayoutView. Это сделано для того чтобы проще перемещать ImageView от клетки к клетке. Ниже приводится код метода checkForValidMove, который показывает, как происходит перемещение ImageView.

private void checkForValidMove(ChessBoardSquareLayoutView view, View dragView) {
 if (mediator.isValidMove(view)) {
 ViewGroup owner = (ViewGroup) dragView.getParent();
 owner.removeView(dragView);
 view.addView(dragView);
 view.setGravity(Gravity.CENTER);
 view.showAsLanded();
 mediator.handleMove(view);
 }
 }

Надеюсь, эта статья поможет Вам при разработке собственных проектов.



Источник:  Bill Bejeckat "Android Drag and Drop"
Перевод: Александр Ледков

Категория: Программирование | Добавил: Virus (29.11.2012)

Похожие темы на пост "Технология Drag and Drop в Android"

Схожие темы выбранные по тегам : Android, программирование, технология, Drag and Drop
  
Просмотров: 2383 | Рейтинг: 0.0/0

Дорогие пользователи и гости сайта!!! Пожалуйста, если вам не сложно, оставте комментарий или ваше мнение о портале в Гостевой книге. Ваше мнение очень важно для нас и очень поможет в поиске дальнейшего пути развития сайта. С уважением, Администрация сайта AndroBum!



Так же рекомендуем:
Всего комментариев: 0
Информация:
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.

[ Регистрация | Вход ]
Поиск

Мини-чат

Block title
Virus
файлов: 69
Постов: 38
Комментов: 1005
Репутация: 0
Ранг:

droid
файлов: 3
Постов: 0
Комментов: 0
Репутация: 100
Ранг:

Serge
файлов: 1
Постов: 0
Комментов: 0
Репутация: 0
Ранг:

Sergey
файлов: 1
Постов: 0
Комментов: 0
Репутация: 0
Ранг:

Аватар не установлен! Blackfoxxx
файлов: 0
Постов: 0
Комментов: 0
Репутация: 0
Ранг:


Друзья сайта
  • Официальный блог
  • скрипты, шаблоны, html, css
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz

  • Статистика Сайта
    Статистика сайта как на сайте

    Пользователей всего: +0
    Материалов всего [?]: +
    Онлайн всего: 1
    Гостей: 1
    Пользователей: 0
    Гости сайта Пользователи

    Яндекс.Метрика




    Пользователи онлайн:


    Flag Counter



    Все материалы размещенные на сайте принадлежат их владельцам.
    Copyright dodomo.do.am © 2010-2012