Michael Bely

BottomSheet

21 Сентября 2016

Библиотека для создания модальных диалоговых окон в приложениях Android.

Подключить библиотеку можно добавив зависимость в build.gradle:

dependencies {
    implementation 'org.michaelbel:bottomsheet:1.2.3'
}

Список всех доступных методов выглядит так:

BottomSheet.Builder builder = new BottomSheet.Builder(context);
builder
   .setTitle(CharSequence title)
   .setItems(CharSequence[] items, Drawable[] icons, DialogInterface.OnClickListener listener)
   .setMenu(@MenuRes int menuResId, DialogInterface.OnClickListener listener)
   .setView(@LayoutRes int layoutResId)
   .setContentType(@BottomSheet.Type int type)
   .setDarkTheme(boolean darkTheme)
   .setFullWidth(boolean fullWidth)
   .setCellHeight(int cellHeightDp)
   .setDividers(boolean dividers)
   .setWindowDimming(@Range(from = 0, to = 255) int windowDimming)
   .setTitleMultiline(boolean multiline)
   .setFabBehavior(FloatingActionButton button)
   .setFabBehavior(FloatingActionButton button, @BottomSheet.FabBehavior int fabBehavior)
   .setBackgroundColor(@ColorInt int color)
   .setBackgroundColorRes(@ColorRes int color)
   .setTitleTextColor(@ColorInt int color)
   .setTitleTextColorRes(@ColorRes int color)
   .setItemTextColor(@ColorInt int color)
   .setItemTextColorRes(@ColorRes int color)
   .setIconColor(@ColorInt int color)
   .setIconColorRes(@ColorRes int color)
   .setItemSelector(int selector);
   .setOnShowListener(new DialogInterface.OnShowListener() {
       @Override
       public void onShow(DialogInterface dialog) {
       }
   });
   .setOnDismissListener(new DialogInterface.OnDismissListener() {
       @Override
       public void onDismiss(DialogInterface dialog) {
       }
   });
   .setCallback(new BottomSheetCallback() {
       @Override
       public void onShown() {
       }
       
       @Override
       public void onDismissed() {
       }
   })
   .show();

Библиотека BottomSheet это приложение, написанное на языке Java. Оно включает в себя несколько классов и комплект android-ресурсов.

Импортировать необходимые зависимости и создать экземпляр диалога:

import org.michaelbel.bottomsheet.BottomSheet;
import org.michaelbel.bottomsheet.BottomSheetCallback;
import org.michaelbel.bottomsheet.Utils;

BottomSheet.Builder builder = new BottomSheet.Builder(context);

Задать название диалога можно передав экземпляр строки напрямую:

builder.setTitle("My title");

или указав адрес строкового ресурса:

builder.setTitle(R.string.title_text);

Элементы создаются с помощью массивов. Поддерживаемые типы данных:

String[] items = new String[] {
    "Share",
    "Upload",
    "Copy",
    "Print this page"
};

CharSequence[] items = new CharSequence[] {
    "Share",
    "Upload",
    "Copy",
    "Print this page"
};

int[] items = new int[] {
    R.string.share,
    R.string.upload,
    R.string.copy,
    R.string.print_this_page
};

Поддерживаемые типы данных для иконок:

int[] icons = new int[] {
    R.drawable.ic_share,
    R.drawable.ic_upload,
    R.drawable.ic_copy,
    R.drawable.ic_print
};
Drawable[] icons = new Drawable[] {
    ContextCompat.getDrawable(context, R.drawable.ic_share),
    ContextCompat.getDrawable(context, R.drawable.ic_upload),
    ContextCompat.getDrawable(context, R.drawable.ic_copy),
    ContextCompat.getDrawable(context, R.drawable.ic_print)
};

Готовый метод будет выглядеть так:

builder.setItems(items, icons, new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        // your code here.
    }
});

Метод также можно создать, используя вместо массивов готовый menu layout файл:

builder.setMenu(R.menu.menu_items, new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        // your code here.
    }
});

Кастомизация

Установить тип контента. Элементы будут отображаться в виде списка или сетки. По умолчанию выбран список.

builder.setContentType(BottomSheet.LIST);
builder.setContentType(BottomSheet.GRID);

Изменить цвет заголовка можно многими способами, в том числе напрямую указав адрес цветового ресурса:

builder.setTitleTextColor(Color.RED);
builder.setTitleTextColor(0xFFFF5252);
builder.setTitleTextColor(getResources().getColor(R.color.my_color));
builder.setTitleTextColor(ContextCompat.getColor(context, R.color.my_color));

builder.setTitleTextColorRes(R.color.my_color);

Можно также получить экземпляр заголовка и задать любые другие доступные параметры:

TextView titleTextView = builder.getTitleTextView();

Изменить цвет элементов:

builder.setItemTextColor(Color.RED);
builder.setItemTextColor(0xFFFF5252);
builder.setItemTextColor(getResources().getColor(R.color.my_color));
builder.setItemTextColor(ContextCompat.getColor(context, R.color.my_color));

builder.setItemTextColorRes(R.color.my_color);

А также изменить любые другие настройки, получив экземпляр контейнера:

ListView listView = builder.getListView();
GridView gridView = builder.getGridView();

Изменить цвет диалога:

builder.setBackgroundColor(Color.RED);
builder.setBackgroundColor(0xFFFF5252);
builder.setBackgroundColor(getResources().getColor(R.color.my_color));
builder.setBackgroundColor(ContextCompat.getColor(context, R.color.my_color));

builder.setBackgroundColorRes(R.color.my_color);

Изменить цвет иконок:

builder.setIconColor(Color.RED);
builder.setIconColor(0xFFFF5252);
builder.setIconColor(getResources().getColor(R.color.my_color));
builder.setIconColor(ContextCompat.getColor(context, R.color.my_color));

builder.setIconColorRes(R.color.my_color);

При открыти диалог будет занимать всю доступную ширину экрана. Значения можно указывать напрямую из строковых ресурсов.

builder.setFullWidth(true);
builder.setFullWidth(R.bool.full_width);

Установить высоту ячеек:

builder.setCellHeight(Utils.dp(this, 52);

Установить разделительные полосы между элементами:

builder.setDividers(true);
builder.setDividers(R.bool.dividers);

Сделать заголовок многострочным:

builder.setTitleMultiline(true);
builder.setTitleMultiline(R.bool.multiline);

Установить темную тему:

builder.setDarkTheme(true);
builder.setDarkTheme(R.bool.multiline);

Установить значение затемнения экрана в диапазоне от 0 до 255.

builder.setWindowDimming(100);

Установить поведение кнопки FloatingActionButton. Кнопка будет либо подниматься вместе с диалоговым окном, либо скрываться при его открытии.

builder.setFabBehavior(floatingActionButton, BottomSheet.FAB_SHOW_HIDE);
builder.setFabBehavior(floatingActionButton, BottomSheet.FAB_SLIDE_UP);

Установить слушателей при открытии и закрытии диалога:

builder.setOnShowListener(new DialogInterface.OnShowListener() {
    @Override
    public void onShow(DialogInterface dialog) {
        // your code here.
    }
});

builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
    @Override
    public void onDismiss(DialogInterface dialog) {
        // your code here.
    }
});

Установить универсальный коллбек:

builder.setCallback(new BottomSheetCallback() {
    @Override
    public void onShown() {
        // your code here.
    }

    @Override
    public void onDismissed() {
        // and here.
    }
});

В конце не забыть указать метод show, иначе ничего не запустится.

builder.show();

Демо-приложение в Google Play

Доступно в Google Play

Исходный код на GitHub

Доступно на GitHub

И последнее

Библиотека BottomSheet больше не поддерживается. Последняя стабильная версия 1.2.3 от 20 Августа 2018. Новых версий не будет. С выходом Material Design 2.0 и развитием библиотеки Material Components был создан BottomSheetDialogFragment, который я и рекомендую использовать теперь. Спасибо всем!