Эффект круговой ряби Flutter: как создать красивый материал BottomNavigationBar

Поскольку приложение Google stadia создано с использованием флаттера, мне было интересно, как они добились гораздо более красивой анимации ряби на своей BottomNavigationBar.

Пример:

Как они добились пользовательской анимации ряби?

Изменить: простой пользовательский элемент BottomNavigationItem:

bottomNavigationBar: Container(
      height: 50,
      child: Row(
        children: <Widget>[
          Expanded(
            child: BottomItem(),
          ),
          Expanded(
            child: BottomItem(),
          ),
          Expanded(
            child: BottomItem(),
          ),
        ],
      )),
class BottomItem extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: () {},
      child: Center(child: Icon(Icons.shop)),
    );
  }
}

4 ответа

Решение

Чернила вы ищете это InkResponse и неInkWell. InkWell заполняет все доступное пространство выделением, а затем делает всплеск, но,InkResponse делает всплеск тем круговым эффектом, который вы ищете, вам нужно немного его настроить, но это пример кода:


Material(
  child: Container(
    child: Center(
       child: InkResponse(
            focusColor: Colors.transparent,
            hoverColor: Colors.transparent,
            highlightColor: Colors.transparent,
            onTap: () {},
            child: Padding(
              padding: const EdgeInsets.all(30),
              child: Icon(Icons.home),
            ),
          ),
        ),
      ),
    )

| InkWell | InkResponse По умолчанию | Пользовательский ответ InkResponse |

Пример приложения Google Stadia:изображение 1Изображение 2

NB: используйте виджет материала в качестве родительского элемента для строки, чтобы эффект можно было расширить по всей ширине строки и с условием ограничения «радиус: 40».

      Container(
      width: double.infinity,
      height: 300,
      child: Material(
        color: Colors.transparent,
        child: Row(
          children: [
            Expanded(
              flex: 20,
              child: InkResponse(
                onTap: () {},
                //containedInkWell: false,
                splashFactory: InkRipple.splashFactory,
                radius: 40,
                splashColor: Colors.black12,
                highlightColor: Colors.transparent,
                child: Container(height: double.infinity, alignment: Alignment.center, child: Icon(Icons.search_rounded)),
              ),
            ),
            Expanded(
              flex: 20,
              child: InkResponse(
                onTap: () {},
                //containedInkWell: false,
                splashFactory: InkRipple.splashFactory,
                radius: 40,
                splashColor: Colors.black12,
                highlightColor: Colors.transparent,
                child: Container(height: double.infinity, alignment: Alignment.center, child: Icon(Icons.search_rounded)),
              ),
            ),
            Expanded(
              flex: 20,
              child: InkResponse(
                onTap: () {},
                //containedInkWell: false,
                splashFactory: InkRipple.splashFactory,
                radius: 40,
                splashColor: Colors.black12,
                highlightColor: Colors.transparent,
                child: Container(height: double.infinity, alignment: Alignment.center, child: Icon(Icons.search_rounded)),
              ),
            ),
            Expanded(
              flex: 20,
              child: InkResponse(
                onTap: () {},
                //containedInkWell: false,
                splashFactory: InkRipple.splashFactory,
                radius: 40,
                splashColor: Colors.black12,
                highlightColor: Colors.transparent,
                child: Container(height: double.infinity, alignment: Alignment.center, child: Icon(Icons.search_rounded)),
              ),
            ),
            Expanded(
              flex: 20,
              child: InkResponse(
                onTap: () {},
                //containedInkWell: false,
                splashFactory: InkRipple.splashFactory,
                radius: 40,
                splashColor: Colors.black12,
                highlightColor: Colors.transparent,
                child: Container(height: double.infinity, alignment: Alignment.center, child: Icon(Icons.search_rounded)),
              ),
            ),
          ],
        ),
      ),
    )

Возможно, вы захотите использовать класс InkResponse в своем BottomNavigationBar:)

Отредактировано из InkWell в InkResponse.

                                       FIRST WAY
    

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'BottomNavigationBar in style Material Design 2',
      theme: ThemeData(primarySwatch: Colors.indigo),
      home: BottomNavigationMaterial2(),
    );
  }
}

class BottomNavigationMaterial2 extends StatefulWidget {
  const BottomNavigationMaterial2({Key? key}) : super(key: key);

  @override
  State<BottomNavigationMaterial2> createState() =>
      _BottomNavigationMaterial2State();
}

class _BottomNavigationMaterial2State extends State<BottomNavigationMaterial3> {
  Widget _bottomNavItem() {
    return InkWell(
      onTap: () {},
      radius: 93,
      splashColor: Color.fromARGB(124, 108, 130, 255),
      highlightColor: Colors.white,
      splashFactory: InkRipple.splashFactory,
      child: Center(child: Icon(Icons.search, size: 25)),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      bottomNavigationBar: Container(
        height: 80,
        child: Row(
          children: <Widget>[
            Container(child: _bottomNavItem(), width: 196),
            Container(child: _bottomNavItem(), width: 196),
          ],
        ),
      ),
    );
  }
}
                                 SECOND WAY
    

theme: ThemeData(splashFactory: InkRipple.splashFactory),
Другие вопросы по тегам