Недавно в Android был представлен новый шаблон дизайна. Один из самых известных паттернов — продвигаемые действия . Это действия, которые непосредственно видны в пользовательском интерфейсе вместо использования кнопки панели действий; по этой причине эти действия называются повышенными, к ним можно легко получить доступ и определить основное действие в текущем пользовательском интерфейсе. Например, если мы используем приложение электронной почты и перечисляем папку «Входящие», одно продвигаемое действие может быть новым письмом. Визуальный шаблон называется Float Action Button (или FAB), потому что продвигаемое действие может быть представлено с помощью плавающей круглой кнопки в пользовательском интерфейсе.
Этот тип шаблонов дизайна доступен в Android L, но мы можем создать плавающую кнопку и в предыдущей версии Android. Предположим, у нас есть список элементов в нашем пользовательском интерфейсе, продвигаемое действие может быть «Добавить новый элемент», поэтому у нас может быть что-то вроде рисунка, показанного ниже:
Есть несколько способов, которыми мы можем использовать, чтобы создать плавающую кнопку действия.
Плавающая кнопка действия с использованием ImageButton
Первый способ создания FAB — это использование ImageButton , мы просто добавляем ImageButton в наш макет пользовательского интерфейса и используем некоторые новые функции, предоставляемые Android L.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
< ImageButton android:layout_width = "56dp" android:layout_height = "56dp" android:src = "@drawable/plus" android:layout_alignParentBottom = "true" android:layout_alignParentRight = "true" android:layout_marginRight = "16dp" android:layout_marginBottom = "16dp" android:tint = "@android:color/white" android:id = "@+id/fab" android:elevation = "1dp" android:background = "@drawable/ripple" android:stateListAnimator = "@anim/fab_anim" /> |
Если мы посмотрим выше, мы можем заметить, что это обычная кнопка ImageButton, которую мы обычно размещаем в правом нижнем углу. Есть некоторые аспекты, которые мы должны рассмотреть:
- Фон
- Тень
- Анимация
Чтобы сделать нашу кнопку более «привлекательной», мы можем реализовать эффект фона. Если мы заметим, мы используем рисование пульсации, определенное следующим образом:
1
2
3
4
5
6
7
|
< ripple xmlns:android = "http://schemas.android.com/apk/res/android" android:color = "?android:colorControlHighlight" > < item > < shape android:shape = "oval" > < solid android:color = "?android:colorAccent" /> </ shape > </ item > </ ripple > |
Мы сказали, что это плавающая кнопка, поэтому она должна плавать над данными пользовательского интерфейса, как если бы она находилась на другом уровне плоскости. Этот эффект можно получить с помощью атрибута высоты, который «перемещает» наш компонент пользовательского интерфейса по оси Z. Последнее — это эффект анимации при нажатии кнопки. Мы хотим дать пользователю ощущение, что кнопка тонет, когда мы нажимаем ее, поэтому мы должны увеличить тень вокруг нее:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
< item android:state_enabled = "true" android:state_pressed = "true" > < objectAnimator android:duration = "@android:integer/config_shortAnimTime" android:propertyName = "translationZ" android:valueFrom = "@dimen/start_z" android:valueTo = "@dimen/end_z" android:valueType = "floatType" /> </ item > < item > < objectAnimator android:duration = "@android:integer/config_shortAnimTime" android:propertyName = "translationZ" android:valueFrom = "@dimen/end_z" android:valueTo = "@dimen/start_z" android:valueType = "floatType" /> </ item > </ selector > |
Плавающая кнопка действия с использованием пользовательского компонента
Еще один способ создать нашу плавающую кнопку — использование пользовательского компонента. В этом случае мы не используем функцию Android L, но кодируем ее вручную.
Во-первых, мы создаем наш класс, который представляет пользовательский компонент:
1
2
3
|
public class CustomFAB extends ImageButton { ... } |
Следующим шагом является чтение некоторых пользовательских атрибутов, которые влияют на поведение пользовательского интерфейса, мы можем сделать это с помощью метода init:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
private void init(AttributeSet attrSet) { Resources.Theme theme = ctx.getTheme(); TypedArray arr = theme.obtainStyledAttributes(attrSet, R.styleable.FAB, 0 , 0 ); try { setBgColor(arr.getColor(R.styleable.FAB_bg_color, Color.BLUE)); setBgColorPressed(arr.getColor(R.styleable.FAB_bg_color_pressed, Color.GRAY)); StateListDrawable sld = new StateListDrawable(); sld.addState( new int [] {android.R.attr.state_pressed}, createButton(bgColorPressed)); sld.addState( new int [] {}, createButton(bgColor)); setBackground(sld); } catch (Throwable t) {} finally { arr.recycle(); } } |
В то же время мы определяем эти атрибуты в файле XML:
1
2
3
4
5
6
7
8
|
<? xml version = "1.0" encoding = "utf-8" ?> < resources > < declare-styleable name = "FAB" > <!-- Background color --> < attr name = "bg_color" format = "color|reference" /> < attr name = "bg_color_pressed" format = "color|reference" /> </ declare-styleable > </ resources > |
Если вы заметили, у нас есть атрибут, управляющий цветом фона. В строке 8 мы определяем несколько состояний кнопки, используя StateListDrawable, и для каждого состояния мы создаем нашу кнопку:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
private Drawable createButton( int color) { OvalShape oShape = new OvalShape(); ShapeDrawable sd = new ShapeDrawable(oShape); setWillNotDraw( false ); sd.getPaint().setColor(color); OvalShape oShape1 = new OvalShape(); ShapeDrawable sd1 = new ShapeDrawable(oShape); sd1.setShaderFactory( new ShapeDrawable.ShaderFactory() { @Override public Shader resize( int width, int height) { LinearGradient lg = new LinearGradient( 0 , 0 , 0 , height, new int [] { Color.WHITE, Color.GRAY, Color.DKGRAY, Color.BLACK }, null , Shader.TileMode.REPEAT); return lg; } }); LayerDrawable ld = new LayerDrawable( new Drawable[] { sd1, sd }); ld.setLayerInset( 0 , 5 , 5 , 0 , 0 ); ld.setLayerInset( 1 , 0 , 0 , 5 , 5 ); return ld; } |
Наконец, мы можем добавить этот компонент в наш макет:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
android:layout_width = "match_parent" android:layout_height = "match_parent" android:paddingLeft = "@dimen/activity_horizontal_margin" android:paddingRight = "@dimen/activity_horizontal_margin" android:paddingTop = "@dimen/activity_vertical_margin" android:paddingBottom = "@dimen/activity_vertical_margin" tools:context = ".MyActivity" > ... < com.survivingwithandroid.fab.CustomFAB android:layout_width = "56dp" android:layout_height = "56dp" android:src = "@android:drawable/ic_input_add" android:layout_alignParentBottom = "true" android:layout_alignParentRight = "true" android:layout_marginRight = "16dp" android:layout_marginBottom = "16dp" custom:bg_color = "@color/light_blue" android:tint = "@android:color/white" /> </ RelativeLayout > |
- Доступен исходный код @ github
Ссылка: | Действия, продвигаемые Android: кнопка плавающего действия (FAB) от нашего партнера по JCG Франческо Аццолы в блоге Surviving w / Android . |