Практическое применение Sliver’ов для создания современного UI

от автора

Hola, Amigos! На связи Саша Чаплыгин, Flutter-dev агентства продуктовой разработки Amiga и соавтор телеграм-канала Flutter. Много

Мы уже касались темы Sliver’ов, а сегодня я предлагаю погрузиться в практику. В нашей текущей работе над приложением для сети пекарен, где множество интересных задач и вопросов интерфейса, я активно применяю Sliver’ы и другие виджеты. Давайте рассмотрим, как эти техники могут преобразить создание современного пользовательского интерфейса.

Используем Stack для эффекта перекрытия карточки. Для этого применяем DraggableScrollableSheet:

Stack(  children: [    Padding(      padding: const EdgeInsets.fromLTRB(16, 8, 16, 0),      child: CreateProfileCard(state.pageState),    ),    DraggableScrollableSheet(      initialChildSize: 379 / 640,      minChildSize: 379 / 640,      maxChildSize: 1,      builder: (context, scrollController) {        return Container(          decoration: BoxDecoration(            color: AppColors.white,            borderRadius: const BorderRadius.vertical(top: Radius.circular(30)),          ),          padding: const EdgeInsets.fromLTRB(16, 6, 16, 0),          child: Column(            children: [              Padding(                padding: const EdgeInsets.only(bottom: 15.0),                child: SvgPicture.asset(AppConstants.icons + 'holder.svg'),              ),              Expanded(                child: CustomScrollView(                  controller: scrollController,                  slivers: [...],                ),              ),            ],          ),        );      },    ),

В DraggableScrollableSheet передаем скролл контроллер в наш CustomScroollView для использования Sliver’ов:

Для таких элементов UI используем SliverToBoxAdapter:

SliverToBoxAdapter(  child: Padding(    padding: const EdgeInsets.only(top: 8.0),    child: MainBanners(state.pageState),  ), ), // элемент CustomScrollView  class MainBanners extends StatelessWidget {  const MainBanners(this.pageState, {Key? key}) : super(key: key);   final MainPageState pageState;   @override  Widget build(BuildContext context) {    return Container(      height: 120,      child: Column(        mainAxisSize: MainAxisSize.min,        children: [          Expanded(            child: CarouselSlider(              options: CarouselOptions(                autoPlay: true,                height: 88,                viewportFraction: 1.025,              ),              items: List.generate(                5,                (index) => InkWell(                  onTap: () {},                  child: Container(                    width: MediaQuery.of(context).size.width,                    margin: const EdgeInsets.symmetric(horizontal: 5),                    decoration: BoxDecoration(                        borderRadius: const BorderRadius.all(Radius.circular(16)), color: setColor.elementAt(index)),                  ),                ),              ),            ),          ),          Row(            mainAxisAlignment: MainAxisAlignment.center,            children: List.generate(                5,                (index) => InkWell(                      onTap: () {},                      child: Container(                        width: 16.0,                        height: 6.0,                        margin: const EdgeInsets.symmetric(                          vertical: 12.0,                          horizontal: 4.0,                        ),                        decoration: BoxDecoration(                          borderRadius: const BorderRadius.all(Radius.circular(4)),                          color: Theme.of(context).primaryColor.withOpacity(0.5),                        ),                      ),                    )).toList(),          ),        ],      ),    );  } }
SliverToBoxAdapter(  child: Padding(    padding: const EdgeInsets.only(top: 28.0, bottom: 8),    child: Row(      mainAxisAlignment: MainAxisAlignment.spaceBetween,      children: [        Text(          'НОВИНКИ',          style: Theme.of(context)              .textTheme              .headlineLarge              ?.copyWith(color: AppColors.black),        ),        Row(          children: [            Text(              'все',              style: Theme.of(context)                  .textTheme                  .bodyLarge                  ?.copyWith(color: AppColors.black),            ),            const SizedBox(width: 4),            SvgPicture.asset(AppConstants.icons + 'deep_arrow.svg'),          ],        ),      ],    ),  ), ),

А для прокручиваемых списков используем SliverList и SliverGrid:

SliverGrid.builder(  gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(    crossAxisCount: 2,    childAspectRatio: 160 / 208,    crossAxisSpacing: 8,    mainAxisSpacing: 8,  ),  itemCount: 4,  itemBuilder: (context, index) => Container(    padding: const EdgeInsets.only(bottom: 8),    decoration: const BoxDecoration(      borderRadius: BorderRadius.all(Radius.circular(8)),      color: AppColors.white,      boxShadow: [        BoxShadow(          color: Color.fromRGBO(0, 0, 0, 0.1),          blurRadius: 6,        ),        BoxShadow(          color: Color.fromRGBO(0, 0, 0, 0.15),          blurRadius: 2,        ),      ],    ),    child: Column(      children: [        Container(          height: 120,          decoration: const BoxDecoration(            color: Colors.red,            borderRadius: BorderRadius.all(Radius.circular(8)),          ),        )      ],    ),  ), ),

Slivers во Flutter представляют собой мощный инструмент для создания гибких и эффективных UI. Они позволяют легко реагировать на действия пользователя, работать с большими объемами данных и создавать привлекательные анимированные макеты.  

Смело используйте Slivers для улучшения UI/UX в ваших приложениях на Flutter, и пользователи скажут вам спасибо!

Подписывайтесь на наш авторский телеграм-канал Flutter. Много, который мы ведем командой мобильных разработчиков. Рассказываем про свой личный опыт и делимся советами от софт-скиллов до технических знаний. Будем рады новым участникам!


ссылка на оригинал статьи https://habr.com/ru/articles/794510/


Комментарии

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

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