Делаем красивые кнопки в Android

Одним из важных компонентов пользовательского интерфейса в приложения является кнопка. Она используется для выполнения различных действий пользователя.

В этой статье мы приведём примеры использования и стилизации кнопки.

Добавляем кнопку на разметку

Пользовательский интерфейс приложения определён в XML-файле с разметкой. Вы можете добавить элемент Button и установить атрибуты вручную. Или вы можете, воспользовавшись инструментом дизайна, добавить Button из палитры элементов и задать атрибуты.

<Button
    android:id="@+id/account_b"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginEnd="8dp"
    android:layout_marginStart="8dp"
    android:text="Добавить аккаунт"
    />

Атрибуты кнопки

Button является подклассом TextView и наследует атрибуты от TextView и View. Ниже приведены некоторые важные атрибуты кнопки, которые можно использовать для настройки стиля и поведения.

  • background: установка в качестве фона как цвета, так и drawable
  • onClick: установить метод, который будет запускаться при нажатии на кнопку
  • minHeight: для определения минимальной высоты кнопки
  • minWidth: для определения минимальной ширины кнопки
  • stateListAnimator: определение анимации при изменении состояния кнопки
  • focusable: для определения того, будет ли обработано нажатие клавиши
  • clickable: указать, является ли кнопка кликабельной
  • gravity: установка выравнивания текста кнопки
  • textAppearance: установить стиль текста

Включение и выключение кнопки

Вы можете использовать атрибут enabled для включения или выключения кнопки, установив его в true или false. Также это можно сделать программно, вызвав метод setEnabled(), как показано ниже:

((Button)findViewById(R.id.button)).setEnabled(false);

Кнопка с Drawable

Вы можете отображать на кнопке вместе с текстом изображение, используя drawableTop, drawableRight, drawableBottom или drawableLeft, в зависимости от того, где располагать картинку, как показано на скриншоте ниже.

ImageButton

Android также предоставляет ImageButton, задачей которого является использование изображения в качестве кнопки. Чтобы установить изображение, вы можете использовать атрибут src. Вы также можете использовать разные изображения, которые будут меняться в зависимости от состояния кнопки, меняя в XML drawable selector как показано ниже.

<ImageButton
    android:id="@+id/img_b"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:onClick="doSomething"
    android:src="@drawable/img_state"
    />

Пример XML drawable selector

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:drawable="@drawable/arrow_down"
      android:state_pressed="true"/>
  <item android:drawable="@drawable/arrow_up"
      android:state_focused="true"/>
  <item android:drawable="@drawable/arrow_up"/>
</selector>

Обработка нажатий на кнопку

Клики можно обрабатывать двумя способами. Первый — это установить атрибут onClick в разметке XML. Второй — назначить кнопке слушатель в коде активности или фрагмента.

Чтобы установить атрибут onClick, сначала определите метод типа void, принимающий в качестве параметра View, в активности или фрагменте и затем используйте имя этого метода как значение для атрибута onClick, как показано ниже.

public void doSomething(View v) {
  //do something
}
<Button
    android:id="@+id/button"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:onClick="doSomething"
    android:text="Делай что-нибудь"
    />

Ниже приведён код обработки нажатия с помощью слушателя.

Button doSomethingButton = (Button) findViewById(R.id.do_something_b);

doSomethingButton.setOnClickListener(new View.OnClickListener() {
  @Override public void onClick(View view) {
    //пишем код
  }
});

Дизайн и стили кнопок

Вы можете применять стили и темы для изменения внешнего вида кнопок. Платформа Android предоставляет заранее определённые стили. На рисунке ниже вы можете увидеть, как отображаются кнопки с различными стилями.

Пример применения темы для кнопки.

<Button
    android:id="@+id/button3"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Button3"
    style="@style/Widget.AppCompat.Button.Borderless.Colored"
    />

Настройка стилей кнопок

Вы можете изменить цвета по умолчанию для стилей, применяемых к кнопке, установив атрибут colorAccent на уровне приложения и атрибут colorButtonNormal на уровне виджета для нужных цветов. Атрибут colorControlHighlight используется для установки цвета кнопки, когда она находится в нажатом состоянии.

Как только вы определите собственный стиль, вы можете применить его к кнопкам с помощью атрибута theme. Ниже приведен пример пользовательской темы.

<style name="PurpleButton" parent="@style/Widget.AppCompat.Button.Colored">
  <item name="colorButtonNormal">#1a237e</item>
  <item name="colorControlHighlight">#673ab7</item>
</style>

Кнопка с закруглёнными углами

Вы можете определить элемент inset, как показано ниже, чтобы создать кнопку с закруглёнными углами и сохранить файл с drawable в папке res/drawable. Вы можете увеличить или уменьшить атрибут радиуса элемента, чтобы отрегулировать радиус углов кнопки.

<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:insetBottom="6dp"
    android:insetLeft="4dp"
    android:insetRight="4dp"
    android:insetTop="6dp">
  <ripple android:color="?attr/colorControlHighlight">
    <item>
      <shape android:shape="rectangle"
          android:tint="#0091ea">
        <corners android:radius="10dp"/>
        <solid android:color="#1a237e"/>
        <padding android:bottom="6dp"/>
      </shape>
    </item>
  </ripple>
</inset>

Затем определите стиль, задающий атрибут background для xml drawable и примените его к кнопке с помощью атрибута style.

<style name="RoundedCornerButton" parent="@style/Widget.AppCompat.Button.Colored">
  <item name="background">@drawable/btn_rounded_corner</item>
  <item name="colorButtonNormal">#1a237e</item>
  <item name="colorControlHighlight">#673ab7</item>
</style>

Высота и тень кнопки

Вы можете установить атрибуты elevation и translationZ, чтобы нарисовать тень кнопки.

<Button
    ...
    android:elevation="6dp"
    android:stateListAnimator="@null"
    android:translationZ="4dp"/>

Настройка анимации тени

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

Обратите внимание, что stateListAnimator установлен в null в приведённом выше примере. Это было сделано для удаления аниматора по умолчанию, чтобы elevation и translationZ работали.

Чтобы настроить анимацию тени при изменении состояния кнопок, вам нужно определить селектор, как показано ниже, в папке res/animator и установить свойство stateListAnimator своей темы для определённого аниматора.

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:state_enabled="true" android:state_pressed="true">
    <set>
      <objectAnimator android:duration="120"
          android:propertyName="translationZ"
          android:valueTo="8dp"
          android:valueType="floatType"/>
      <objectAnimator android:duration="120"
          android:propertyName="elevation"
          android:valueTo="4dp"
          android:valueType="floatType"/>
    </set>
  </item>
  <item android:state_enabled="true">
    <set>
      <objectAnimator android:duration="120"
          android:propertyName="translationZ"
          android:startDelay="80"
          android:valueTo="4dp"
          android:valueType="floatType"/>
      <objectAnimator android:duration="120"
          android:propertyName="elevation"
          android:valueTo="2dp"
          android:valueType="floatType"/>
    </set>
  </item>
</selector>

Примените следующую тему, которая использует аниматор, к кнопке с использованием атрибута style или theme.

<style name="CustomAnimationButton" parent="@style/Widget.AppCompat.Button">
  <item name="colorButtonNormal">#1a237e</item>
  <item name="colorControlHighlight">#673ab7</item>
  <item name="android:stateListAnimator">@animator/button_elevation</item>
</style>

Простая кнопка логина

Совмещая всё вышесказанное, можно создать красивую кнопку, позволяющую, например, заходить пользователям на свои аккаунты. Код разметки будет выглядеть следующим образом:

<Button
    android:id="@+id/btn_email_password"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:layout_marginTop="4dp"
    android:background="@drawable/element_background"
    android:drawablePadding="8dp"
    android:fontFamily="sans-serif-medium"
    android:paddingLeft="8dp"
    android:paddingRight="8dp"
    android:text="Password"
    android:textAllCaps="false"
    android:textStyle="normal"
    />

Стиль фона:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

  <item>
    <shape android:shape="rectangle">
      <solid android:color="#BDBDBD"/>
      <corners android:radius="5dp"/>
    </shape>
  </item>

  <item
      android:bottom="2dp"
      android:left="0dp"
      android:right="0dp"
      android:top="0dp">
    <shape android:shape="rectangle">
      <solid android:color="#ffffff"/>      
    </shape>
  </item>
</layer-list>

Кроме того, с помощью атрибута drawableLeft можно добавить изображение к нашей кнопке, в том числе и векторное. На старых устройствах, векторные изображения  вызывают падение всего приложения, поэтому  сделаем это программно в коде активности при помощи AppCompatResources:

((Button) findViewById(R.id.btn_email_password)).setCompoundDrawablesWithIntrinsicBounds(
    AppCompatResources.getDrawable(this, R.drawable.ic_vpn_key_black_24dp), null, null, null);

Метод setCompoundDrawablesWithIntrinsicBounds() делает то же, что и атрибуты drawableLeft, drawableTop и так далее. В качестве параметров нужно указать, где именно будет размещаться изображение (указываем null в случае, если здесь изображение не нужно).

Нашли ошибку в тексте?

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *