/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000
Разработка приложений для носимых устройств отличается от разработки под стандартные устройства. Прежде всего это связано с форм-фактором. На данный момент имеются круглые и квадратные часы. Отсюда могут возникнуть проблемы.
Старайтесь не размещать информацию таким образом, чтобы она обрезалась в круглых часах.
Существует два подхода для решения проблемы. Первый - создать две отдельные разметки под каждый тип устройства. Приложение само определит, какую разметку следует использовать. Этот способ подходит, когда вы изначально планируете разрабатывать разный дизайн под разные типы экрана.
Второй подход - использовать специальную разметку, включающую оба варианта для круглых и квадратных часов.
Когда вы создавали проект, расчитанный на использование часов, то в Gradle добавлялась строка в зависимости.
compile 'com.google.android.support:wearable:1.0.0'
Если вы решили добавить поддержку часов в старом проекте, то добавьте эту строку вручную.
Поговорим о втором способе с использованием универсальной разметки. Разметка называется WatchViewStub и она является корневым элементом. В атрибуте rectLayout нужно указать разметку для квадратных часов, в атрибуте roundLayout - для круглых часов. Откройте файл activity_wear_main.xml модуля wear (у вас может быть другое имя) и посмотрите готовый вариант:
<?xml version="1.0" encoding="utf-8"?>
<android.support.wearable.view.WatchViewStub
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/watch_view_stub"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:rectLayout="@layout/rect_activity_wear_main"
app:roundLayout="@layout/round_activity_wear_main"
tools:context=".WearMainActivity"
tools:deviceIds="wear">
</android.support.wearable.view.WatchViewStub>
Разметка загружается в экран обычным способом через метод setContentView():
setContentView(R.layout.activity_wear_main);
Сами разметки, как видно из XML-кода, находятся в файлах layout/rect_activity_wear_main.xml и layout/round_activity_wear_main.xml.
При загрузке вы не можете сразу определить нужный тип разметки. Вам следует установить слушатель, который отслеживает загрузку требуемой разметки - круглой или квадратной. И в методе слушателя onLayoutInflated() можете получить доступ к используемым компонентам.
final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
@Override
public void onLayoutInflated(WatchViewStub stub) {
// Теперь можно
mTextView = (TextView) stub.findViewById(R.id.text);
}
});
В этом отношении код немного усложнился.
Разработчики Гугла решили немного схитрить и придумали специальный универсальный вид разметки BoxInsetLayout, который является потомком FrameLayout. Смысл разметки заключается в том, что прямоугольная разметка вписывается в круг.
Пример такой разметки, взятый из документации
<android.support.wearable.view.BoxInsetLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@drawable/robot_background"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:padding="15dp">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="5dp"
app:layout_box="all">
<TextView
android:gravity="center"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="@string/sometext"
android:textColor="@color/black" />
<ImageButton
android:background="@null"
android:layout_gravity="bottom|left"
android:layout_height="50dp"
android:layout_width="50dp"
android:src="@drawable/ok" />
<ImageButton
android:background="@null"
android:layout_gravity="bottom|right"
android:layout_height="50dp"
android:layout_width="50dp"
android:src="@drawable/cancel" />
</FrameLayout>
</android.support.wearable.view.BoxInsetLayout>