Введение в Gestures

    или толкование жестов :)



    Сейчас мы на боевом примере поработаем с жестами в среде 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 и выше.
    • +29
    • 14.2k
    • 4
    Share post

    Comments 4

      +1
      Спасибо, интересно.
      Как раз на днях пришлось бы по работе ковырять эту тему.
        0
        Пожалуйста, «ковырять эту тему» — это жесты, honeycomb или астрономию? ))
          0
          Спасибо, добавил фразу «ковырять эту тему» в свой словарь технических слов-паразитов.
        +1
        Как раз не давно у меня проскакивала идея сделать рукописный ввод на жестах, теперь знаю как их использовать и можно начать реализовывать.

        Only users with full accounts can post comments. Log in, please.