Освой программирование играючи

Сайт Александра Климова

Шкодим

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

GestureOverlayView

Подготовительные работы - приложение Gestures Builder
Создаём приложение с распознаванием жестов
Слайд-шоу на основе жестов
Цвета для жестов

Данный компонент присутствовал в Eclipse и в ранних версиях студии. Сейчас на панели инструментов его нет, но класс не объявлен устаревшим. Статья была написана ещё во времена использования Eclipse много лет назад.

Android позволяет быстро добавить в приложение возможность распознавания собственных жестов. Например, можно нарисовать кота и программа, распознав ваш жест, может замяукать (воспроизвести звуковой файл).

Подготовительные работы - приложение Gestures Builder

Найдите на эмуляторе программу Gestures Builder. Запустите её. Нажмите на кнопку Add gesture (Добавить жест). Введите имя для нового жеста, например, Slide to left (Жест влево) и проведите мышкой по экрану справа налево. Нажмите на кнопку Done, чтобы завершить создание жеста. Появится сообщение, что жест был сохранён по адресу /mnt/sdcard/gestures.

Ваш эмулятор должен иметь виртуальную SD-карту, иначе Gestures Builder не сможет ничего сохранить.

Аналогично добавьте жесты Slide to right (Жест вправо) и Kitty - Жест, напоминающий кота (просто жесть!).

Gestures Builder

Когда закончите с жестами, программу можете закрывать, она вам больше не понадобится. Но если задумаете добавить новые жесты или удалить старые - снова запускайте приложение и выполняйте нужные действия.

В Eclipse откройте перспективу DDMS и найдите вкладку File Explorer. Перейдите по указанному адресу /mnt/sdcard/, где были сохранены жесты, и найдите файл gestures без расширения. Скопируйте его на свой рабочий компьютер при помощи кнопки Pull a file from the device. На этом подготовительная часть завершена.

Также можно использовать командную строку
adb pull /sdcard/gestures gestures

Создаём приложение с распознаванием жестов

Создайте новый проект. Далее создайте новую папку res/raw и скопируйте в него файл gestures, сохранённый вами ранее.

Разместим компонент GestureOverlayView на экране:


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <android.gesture.GestureOverlayView
        android:id="@+id/gestures1"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:eventsInterceptionEnabled="true"
        android:gestureStrokeType="multiple" />

</RelativeLayout>

Далее пишем код по распознаванию жестов:


package ru.alexanderklimov.gestureoverlayview;

import java.util.ArrayList;

import android.os.Bundle;
import android.app.Activity;
import android.gesture.Gesture;
import android.gesture.GestureLibraries;
import android.gesture.GestureLibrary;
import android.gesture.GestureOverlayView;
import android.gesture.GestureOverlayView.OnGesturePerformedListener;
import android.gesture.Prediction;
import android.view.Menu;
import android.widget.Toast;

public class MainActivity extends Activity {

	private GestureLibrary gestureLib;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		GestureOverlayView gestureview = (GestureOverlayView) findViewById(R.id.gestures1);

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

		gestureview.addOnGesturePerformedListener(handleGestureListener);
	}

	private OnGesturePerformedListener handleGestureListener = new OnGesturePerformedListener() {
		public void onGesturePerformed(GestureOverlayView gestureView,
				Gesture gesture) {

			ArrayList<Prediction> predictions = gestureLib.recognize(gesture);

			if (predictions.size() > 0) {
				Prediction prediction = predictions.get(0);
				if (prediction.score > 1.0) {
					Toast.makeText(MainActivity.this,
							"Ваш жест : " + prediction.name,
							Toast.LENGTH_LONG).show();
				}
			}

		}
	};
}

Как видите, мы подключаем жесты через ресурсы:


gestureLib = GestureLibraries.fromRawResource(this, R.raw.gestures);

Запускаем приложение и пытаемся повторить жесты, которые мы создавали в Gesture Builder. Если приложение распознает созданные вами жесты, то появится всплывающее сообщение.

Слайд-шоу на основе жестов

Перейдём к более практичному примеру на основе предыдущего примера.

Добавим в разметку элемент ViewFlipper, который будет распознавать жесты и работать как слайд-шоу при использовании наших жестов.


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <android.gesture.GestureOverlayView
        android:id="@+id/gestures1"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:eventsInterceptionEnabled="true"
        android:gestureStrokeType="multiple" />

    <LinearLayout
        android:id="@+id/LinearLayout1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="75dp" >

        <ViewFlipper
            android:id="@+id/ViewFlipper01"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" >

            <ImageView
                android:id="@+id/imageView1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/cat1" />

            <ImageView
                android:id="@+id/imageView2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/cat2" />

            <ImageView
                android:id="@+id/imageView3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/cat3" />

            <ImageView
                android:id="@+id/imageView4"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/cat4" />
        </ViewFlipper>
    </LinearLayout>

</RelativeLayout>

Теперь нам нужно распознать жест по его имени и выполнить нужную операцию:


package ru.alexanderklimov.gestureoverlayview;

import ...

public class MainActivity extends Activity {

	private GestureLibrary gestureLib;
	ViewFlipper vf;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		GestureOverlayView gestureview = (GestureOverlayView) findViewById(R.id.gestures1);

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

		gestureview.addOnGesturePerformedListener(handleGestureListener);

		vf = (ViewFlipper) findViewById(R.id.ViewFlipper1);
		vf.setInAnimation(this, android.R.anim.fade_in);
		vf.setOutAnimation(this, android.R.anim.fade_out);
	}

	private OnGesturePerformedListener handleGestureListener = new OnGesturePerformedListener() {
		public void onGesturePerformed(GestureOverlayView gestureView,
				Gesture gesture) {

			ArrayList<Prediction> predictions = gestureLib.recognize(gesture);

			if (predictions.size() > 0) {
				Prediction prediction = predictions.get(0);
				if (prediction.score > 1.0) {

					String action = predictions.get(0).name;
					if ("Slide to left".equals(action)) {
						vf.showPrevious();
						Toast.makeText(MainActivity.this,
								prediction.name + " : Show Next Picture",
								Toast.LENGTH_LONG).show();
					} else if ("Slide to right".equals(action)) {
						vf.showPrevious();
						vf.showPrevious();
						Toast.makeText(MainActivity.this,
								prediction.name + " : Show Previous Picture",
								Toast.LENGTH_LONG).show();
					} else if ("Kitty".equals(action)) {
						// можно мяукать или делать другие действия
						Toast.makeText(MainActivity.this,
								prediction.name,
								Toast.LENGTH_LONG).show();
					}
				}
			}
		}
	};
}

Gestures

Конечно, жесты вправо-влево слишком примитивны и реализовать слайд-шоу можно и более стандартными способами. Здесь они показаны только для демонстрации. Но можно придумать и более замысловатые жесты. В нашем примере есть сложный жест, напоминающий фигурку кота и программа прекрасно распознаёт его. Также можно придумать жесты в виде отдельных буквы. Скажем, жест в виде буквы S может сохранять документ (Save) и т.д.

Цвета для жестов

По умолчанию, когда мы делаем жесты в приложении, то рисуются жирные жёлтые линии. Вы можете настроить цвет через XML, установив у GestureOverlayView необходимые атрибуты:


android:gestureColor="#AAFF0000"
android:uncertainGestureColor="#AA00FF00"

Если приложение распознало жест, то линия будет выводиться цветом из первого параметра, иначе - из второго. Поменяв цвета на красный и зелёный, я сделал процесс распознавания жестов более наглядным. В реальном приложении возможно стоит использовать прозрачные цвета, чтобы не отвлекать пользователя.

Реклама