Pull to refresh

Введение в Gestures

Reading time4 min
Views17K
или толкование жестов :)



Сейчас мы на боевом примере поработаем с жестами в среде Android. Приложение будет клиентом сайта Astronomy Picture of the Day by NASA. На этом сайте ребята каждый день выкладывают какую-нибудь замечательную картинку, связанную с астрономией. Жестами мы будем ходить вперед/назад и вызывать диалог выбора даты. А чтобы было еще интересней — напишем его для Honeycomb.

Статья состоит из двух частей: первая — покажет, как создавать жесты с помощью приложения Gestures Builder и выгружать их из эмулятора в отдельный бинарный файл. Во второй части, мы загрузим его в наше приложение и начнем использовать.

Создание жестов


Пакет android.gesture появился в API версии 1.6 и призван существенно облегчить обработку жестов и уменьшить количество кода, который будут писать программисты. Вместе с тем, в эмуляторе версии 1.6 и выше появилось предустановленное приложение Gestures Builder, с его помощью мы можем создавать набор подготовленных жестов и добавлять их в виде бинарного ресурса в своё приложение. Для этого мы сделаем эмулятор с вмонтированным образом SD карты, куда будет сохранятся файл с жестами (без карты Gestures Builder скажет, что ему некуда записывать жесты)

Шаг 1. Создадим img образ SD карты с помощью mksdcard. Эту утилиту можно найти в папке <путь куда установлен android-sdk>\tools. Файл с жестами будет весить немного, но эмулятор android имеет ограничение на минимальный размер карты что-то около 8-9 мегабайт. Поэтому мы создадим с запасом и каким-нибудь ровным размером, например, 64 мб. Пишем:

mksdcard -l mySdCard 64M gestures.img

Шаг 2. Сделаем эмулятор запустим его с образом gestures.img. Действуем как на картинке:



Чтобы запустить эмулятор с образом зайдем в <путь куда установлен android-sdk>\tools и выполним:

emulator -avd avd30 -sdcard gestures.img

Шаг 3. Эмулятор запущен и нам нужно сделать свои жесты. Для этого откроем Gestures Builder нажмем Add gesture и перед нами откроется редактор жеста. Отрисуем слева направо жест с нажатой левой клавишей мыши и вверху дадим ему имя — prev. Done. Затем по аналогии (в другую сторону) создаем жест next и в качестве последнего, напишем что-то похожее на латинскую D и назовем date. На картинках ниже — как мы это делаем (кликабельно):







Шаг 4. У запущенного эмулятора мы забираем бинарный ресурс с жестами, выполнив в директории tools:

adb pull /sdcard/gestures gestures

После чего файл gestures должен появиться. Мы положим его в свой проект по пути res\raw\gestures.

Использование жестов


Наше приложение будет называться ApodGestures. Во второй части я коснусь только тем, связанных с жестами. Весь программный код можно взять на code.google.com из Mercurial репозитория, либо выполнить в консоли hg clone pyJIoH@apod-gestures.googlecode.com/hg apod-gestures, либо скачать архив во вкладке Downloads.

ApodGestures будет коннектиться к сайту APOD, выкачивать астрономическую картинку в отдельном потоке и загружать ее в ImageView. С помощью жестов мы сделаем навигацию: вперед, назад и диалог выбора любой даты.

В принципе, здесь не используются какие-то специальные фичи из Honeycomb, поэтому, снизив версию, мы без проблем запустим приложение на телефонах. Ограничения скорее накладывал сам Honeycomb, т.к. c этой версии и выше ужесточилась политика того, что можно делать в основном потоке. Здесь я столкнулся с примером NetworkOnMainThreadException при работе в главном потоке HttpClient'а. Почитать можно тут.

Создав проект, положим наш бинарный ресурс по пути apod-gestures\res\raw\gestures.

ImageView в xml layout'е поместим на android.gesture.GestureOverlayView, которое является прозрачным наложением, способным определять ввод жестов. Код будет таким:

<?xml version="1.0" encoding="utf-8"?>
		<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
			android:layout_width="fill_parent" 
			android:layout_height="fill_parent">
			<android.gesture.GestureOverlayView
				android:id="@+id/gestures"
				android:layout_width="fill_parent" 
				android:layout_height="fill_parent" 
				android:layout_weight="1.0">
				<ImageView 
					android:layout_gravity="center_vertical" 
					android:id="@+id/ImageView" 
					android:layout_width="fill_parent" 
					android:layout_height="fill_parent" 
				/>
				<Button
					android:id="@+id/button_select_date"
					android:layout_width="wrap_content" 
					android:layout_height="wrap_content" 
					android:layout_gravity="center_horizontal|top"
					android:padding="12dip"
					android:background="#AA000000"
					android:textColor="#ffffffff"
					android:text="Feb 10, 2011"
			    />
			</android.gesture.GestureOverlayView>
		</FrameLayout>

Далее добавим в ApodGestures activity поле: private GestureLibrary mGestureLib;
В него мы загрузим наши жесты из raw ресурса:

		@Override
		public void onCreate(Bundle savedInstanceState) {
			super.onCreate(savedInstanceState);
			setContentView(R.layout.main);

			mGestureLib = GestureLibraries.fromRawResource(this, R.raw.gestures);
			if (!mGestureLib.load()) {
				finish();
			}

			GestureOverlayView gestures = (GestureOverlayView) findViewById(R.id.gestures);
			gestures.addOnGesturePerformedListener(this);

			refreshActivity();
		}

Чтобы начать отслеживать вводимые жесты имплементируем нашей activity OnGesturePerformedListener и реализуем метод onGesturePerformed:

		public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
			ArrayList<Prediction> predictions = mGestureLib.recognize(gesture);
			if (predictions.size() > 0) {
				Prediction prediction = predictions.get(0);
				if (prediction.score > 1.0) {
					if (prediction.name.equals(Gestures.prev))
						showPrevDay();
					else if (prediction.name.equals(Gestures.next))
						showNextDay();
					else if (prediction.name.equals(Gestures.date))
						showSelectDateDialog();
				}
			}
		}

Как видите, имя которое мы вводили в приложении Gestures Builder является идентификатором жестов. Gestures — это наш класс с константами, где имена забиты фиксировано. Если кого-то напрягают жирные желтые линии, любой цвет мы можем задать в xml для GestureOverlayView, свойства android:gestureColor и android:uncertainGestureColor. UncertainGestureColor — это цвет рисующийся на view, когда нет уверенности, что это жест.

Можно сделать цвета серыми и прозрачными:

	android:gestureColor="#AA000000"
	android:uncertainGestureColor="#AA000000">

Пример того, что получилось в итоге (все еще кликабельно).











Надеюсь Вам понравилось.

UPD. Добавил apk файл во вкладку Download. Для установке требуется Android 3.0 и выше.
Tags:
Hubs:
+29
Comments4

Articles