Кривая анимации Flutter Drawer

Есть ли способ добавить кривую в ящик флаттера? Например, Кривые.ElasticOut.

Я думал о расширении класса Drawer или DrawerControllerState для создания пользовательской версии, которая позволяет вводить кривую, однако, похоже, нет очевидного способа сделать это.

Существует полезный плагин, который обеспечивает функциональность кривой, используя свой собственный класс бокового меню, но я хотел бы сделать это с помощью ящика каркаса, так как это не кажется сложным расширением (альтернативный плагин https://github.com/GabrieleCicconetti/uts_sidemenu/blob/master/lib/uts_sidemenu.dart )

Я изучил существующие вопросы SO и не могу найти ни одного, дублирующего эту тему, однако это мой первый вопрос о переполнении стека, поэтому прошу прощения, если я допустил здесь какие-либо ошибки.


person pigeon8    schedule 15.10.2019    source источник


Ответы (1)


Я пробовал больше о том, что вы хотите сделать, но, конечно, я не мог этого сделать. Но я создал собственный ящик с другой анимацией. здесь вы можете дать свои duration, curve. Так что это более сложный и красивый ящик, чем вы хотите создать. Вот исходный код и объяснение:

Сначала нам нужно создать два виджета с отслеживанием состояния, CustomDrawer и HomeScreem: После создания этих виджетов нам нужно создать виджет Wrapper, который будет управлять изменениями экрана.

  • Wrapper виджет:
class Wrapper extends StatelessWidget {
  const Wrapper({Key key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        CustomDrawer(),
        HomeScreen(),
      ],
    );
  }
}

И затем мы должны создать наш виджет CustomDrawer:

  • CustomDrawer виджет:
class CustomDrawer extends StatefulWidget {
  @override
  _CustomDrawerState createState() => _CustomDrawerState();
}

class _CustomDrawerState extends State<CustomDrawer> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Color(0xffD53437),
      body: Stack(
        children: [
          /// Add here whatever you want..
          Row(children: []),
        ],
      ),
    );
  }
}

Самое время создать HomeScreen виджет, который будет управлять анимацией. так что все, что мы должны сделать, находится здесь. Здесь нам нужно создать расширение с отслеживанием состояния и вернуть AnimatedContainer. как вы видете:

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

  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  @override
  Widget build(BuildContext context) {
    return AnimatedContainer(
      color: Colors.grey[900],
      child: buildScaffold(),
    );
  }

  Widget buildScaffold() {
    return Scaffold(
      appBar: buildCustomAppBar(),
      backgroundColor: Colors.black54,
      body: Center(
        child: Text("Curve Drawer Example"),
      )
    );
  }

А теперь мы сделаем методы и некоторые расчеты для управления нашим экраном. Сначала создайте эти переменные до _HomeScreenState:

double x = 0;
double y = 0;
double s = 1;
bool _isDrawerOpened = false;
int _currentIndex = 0;

Тогда нам нужны два метода, openDrawer и closeDrawer.

  • Первый – openDrawer:
void openDrawer() {
  setState(() {
    x = 250;
    y = 150;
    s = 0.6;
    _isDrawerOpened = true;
  });
}
  • Второй – closeDrawer:
void closeDrawer() {
  setState(() {
    x = 0;
    y = 0;
    s = 1;
    _isDrawerOpened = false;
  });
}

И пришло время заполнить наш AnimatedContainer для внесения изменений:

  • Наши AnimatedContainer после заполнения:
AnimatedContainer(
  color: Colors.grey[900],
  curve: Curves.easeInOutBack,
  transform: Matrix4.translationValues(x, y, 0)..scale(s),
  duration: Duration(seconds: 1),
  child: buildScaffold(),
);

И теперь нам нужен appBar для использования наших методов, поэтому для openDrawer и closeDrawer:

AppBar buildCustomAppBar() {
  return AppBar(
    backgroundColor: Colors.black,
    leading: IconButton(
      icon: Icon(
        _isDrawerOpened ? Icons.clear : Icons.menu,
        color: Colors.white,
      ),
      onPressed: _isDrawerOpened ? closeDrawer : openDrawer,
    ),
  );
}

Если вы выполнили эти шаги, вы можете использовать и наслаждаться! просто введите Wrapper в ваш main.dart › Дом MaterialApp.

  • Полный код HomeScreen:
class HomeScreen extends StatefulWidget {
  const HomeScreen({Key key}) : super(key: key);

  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  final pageController = PageController();

  double x = 0;
  double y = 0;
  double s = 1;
  bool _isDrawerOpened = false;
  int _currentIndex = 0;

  void openDrawer() {
    setState(() {
      x = 250;
      y = 150;
      s = 0.6;
      _isDrawerOpened = true;
    });
  }

  void closeDrawer() {
    setState(() {
      x = 0;
      y = 0;
      s = 1;
      _isDrawerOpened = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedContainer(
      color: Colors.grey[900],
      curve: Curves.easeInOutBack,
      transform: Matrix4.translationValues(x, y, 0)..scale(s),
      duration: Duration(seconds: 1),
      child: buildScaffold(),
    );
  }

  Widget buildScaffold() {
    return Scaffold(
      appBar: buildCustomAppBar(),
      backgroundColor: Colors.black54,
      body: Center(
        child: Text("Curve Drawer Example"),
      ),
    );
  }

  AppBar buildCustomAppBar() {
  return AppBar(
    backgroundColor: Colors.black,
    leading: IconButton(
      icon: Icon(
        _isDrawerOpened ? Icons.clear : Icons.menu,
        color: Colors.white,
      ),
      onPressed: _isDrawerOpened ? closeDrawer : openDrawer,
    ),
  );
}

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

person theiskaa    schedule 08.02.2021