Pull to refresh

Подсвечиваемый виджет в Android

Reading time5 min
Views19K

Здравствуйте, уважаемые хабражители. В данной статье описывается процесс создания «подсвечиваемого» виджета, то есть виджета, который можно выделить с помощью пятипозиционного манипулятора D-Pad, присутствующего во многих Android-устройствах в виде трекболов или кнопок. Эта статья ориентирована на подготовленного читателя, уже написавшего свой первый «Android hello, world». Думаю, не стоит рассказывать о преимуществах управления аппаратными клавишами на устройствах с ёмкостным экраном в холодное время года, так что сразу приступим к делу.


Файл конфигурации виджета


Начнем с файла конфигурации виджета widget.xml, создадим его в поддиректории res/xml/ вашего проекта.
<?xml version="1.0" encoding="utf-8" ?><br><appwidget-provider<br>    xmlns:android="http://schemas.android.com/apk/res/android"<br>    android:minWidth="72dip"<br>    android:minHeight="72dip"<br>    android:focusable="true"<br>    android:updatePeriodMillis="0"<br>    android:initialLayout="@layout/widget" /><br><br>* This source code was highlighted with Source Code Highlighter.

Атрибуты android:minWidth и android:minHeight отвечают за размеры виджета, android:updatePeriodMillis за то, как часто будет обновляться виджет, в конкретном случае обновление нам не требуется, android:initialLayout — указывает на то, какой интерфейс Activity будет использоваться для виджета. Нам же интересен атрибут android:focusable, который, как ясно из названия, позволяет или запрещает фокусировать курсор на элементах виджета.

Макет виджета


Виджет будет состоять из иконки и подписи под ней, оба элемента будут нажимаемыми и подсвечиваемыми.

res/layout/widget.xml
<?xml version="1.0" encoding="utf-8"?><br><LinearLayout<br>    xmlns:android="http://schemas.android.com/apk/res/android"<br>    android:layout_width="72dip"<br>    android:layout_height="72dip"<br>    android:orientation="vertical"><br>  <ImageView<br>      android:id="@+id/icon"<br>      android:layout_width="48dip"<br>      android:layout_height="48dip"<br>      android:clickable="true"<br>      android:focusable="true"<br>      android:src="@drawable/icon"<br>      android:background="@drawable/icon_background"<br>      android:layout_gravity="center" /><br>  <LinearLayout<br>      android:id="@+id/label"<br>      xmlns:android="http://schemas.android.com/apk/res/android"<br>      android:layout_width="wrap_content"<br>      android:layout_height="22dip"<br>      android:orientation="vertical"<br>      android:clickable="true"<br>      android:focusable="true"<br>      android:background="@drawable/label_background"<br>      android:gravity="center"><br>    <TextView<br>        android:layout_width="wrap_content"<br>        android:layout_height="wrap_content"<br>        android:text="@string/label"<br>        android:textSize="13sp"<br>        android:textColor="#ffffff" /><br>  </LinearLayout><br></LinearLayout><br><br>* This source code was highlighted with Source Code Highlighter.

Тут стоит обратить внимание на атрибут android:background у иконки и подписи. Этот параметр, как можно догадаться, позволяет поместить на задний план объекта фоновое изображение или цвет, в данном случае он указывает на файлы, в которых описаны правила подсветки элементов.

Правила подсветки


«Правилами подсветки» я назвал StateListDrawable, инструмент, применяемый для изменения фона объекта в зависимости от его состояния. Правила содержаться в тегах item, атрибуты android:state_focused (объект в фокусе) и android:state_pressed (объект нажат) — это условия при которых будет устанавливаться фоновое изображение, android:drawable указывает на ресурс, который будет использоваться в качестве фона.

res/drawable/icon_background.xml
<?xml version="1.0" encoding="utf-8"?><br><selector xmlns:android="http://schemas.android.com/apk/res/android"><br>  <item<br>      android:state_focused="true" <br>      android:state_pressed="false" <br>      android:drawable="@drawable/icon_shadow" /><br>  <item<br>      android:state_focused="true" <br>      android:state_pressed="true"<br>      android:drawable="@drawable/icon_shadow" /><br>  <item<br>      android:state_focused="false" <br>      android:state_pressed="true"<br>      android:drawable="@drawable/icon_shadow" /><br></selector><br><br>* This source code was highlighted with Source Code Highlighter.

В правилах подсветки иконки мы видим три правила, которые можно озвучить так:
  • подсвечивать, если иконка выделена, но не нажата;
  • подсвечивать, если выделена и нажата;
  • подсвечивать, если нажата, но не выделена.


res/drawable/label_background.xml
<?xml version="1.0" encoding="utf-8"?><br><selector xmlns:android="http://schemas.android.com/apk/res/android"><br>  <item<br>      android:state_focused="true" <br>      android:state_pressed="false" <br>      android:drawable="@drawable/label_shadow" /><br>  <item<br>      android:state_focused="true" <br>      android:state_pressed="true"<br>      android:drawable="@drawable/label_shadow" /><br>  <item<br>      android:state_focused="false" <br>      android:state_pressed="true"<br>      android:drawable="@drawable/label_shadow" /><br>  <item android:drawable="@drawable/label" /><br></selector><br><br>* This source code was highlighted with Source Code Highlighter.

Правила подсветки подписи практически ничем не отличаются, за исключением четвертого правила без условий, которое устанавливает фоновое изображение по умолчанию.

Заключение


Теперь нам осталось только уложить ресурсы в директорию res/drawable и составить Manifest:
<?xml version="1.0" encoding="utf-8"?><br><manifest<br>    xmlns:android="http://schemas.android.com/apk/res/android"<br>    package="org.selectdroid"<br>    android:versionCode="1"<br>    android:versionName="1.0"><br>  <application<br>      android:icon="@drawable/icon"<br>      android:label="@string/app_name"><br>    <receiver<br>        android:name=".Widget"<br>        android:label="@string/app_name"><br>      <intent-filter><br>        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /><br>      </intent-filter><br>      <meta-data<br>          android:name="android.appwidget.provider"<br>          android:resource="@xml/widget" /><br>    </receiver><br>  </application><br></manifest><br><br>* This source code was highlighted with Source Code Highlighter.

После компиляции и запуска мы получим вот такой вот виджет:


Всем спасибо за внимание. Надеюсь, что эта статья будет кому-то полезной.

При написании статьи использовалась документация с developer.android.com.
Исходный код прототипа виджета можно скачать здесь.
Скомпилированый apk здесь.
Tags:
Hubs:
+20
Comments8

Articles