تخصيص شكل side menu في flutter بدون مكتبات مع تصميم مختلف

تخصيص شكل side menu في flutter بدون مكتبات مع تصميم مختلف

تخصيص شكل side menu في flutter بدون مكتبات مع تصميم مختلف

الاسباب التي تجعل موقعك او برنامجك او حتى تطبيقك مميز عن غيره وهو وجود عناصر مختلفه غير معتاد عليها المستخدم العادي وتناسق الالوان والعنصر الاخير والذي لا غنى عنه وهو الانميشن في كل هذه العناصر تؤثر بشكل كبير لدى المستخدم وتترك في داخله طابع قوي وشغف من البحث والتفكير في كيفية القيام بهذه العناصر وايضا يفضل تطبيقك لانه سهل الاستخدام عن غيره وكل هذه العناصر يمكنك الحصول عليها من ابداعك ونحن في قسم الانميشن والتصميم نشارك معكم بين كل فتره والاخرى افكار لانميشن وتصاميم تحسن بشكل كبير من مستواك البرمجي .


side menu واحد من العناصر الضروريه والتي لها انماط كثيره تستطيع استخدامها في تطبيقك ولكن الشكل الذي نقدمه لكم اليوم لا يحتاج منك اي مكتبات خارجية او اي عناصر خارجية فقط كل شيئ موجود في هذه المقاله ولن تحتاج الى تثبيت اي عناصر من الخارج حتى تستطيع القيام بذلك في تطبيقك وكل هذه العمليات بسيطة جدا وسبق وشاركنها معكم في كثير من المقالات .


How to creatw side menu animation with Flutter Project

التصميم التالي عباره عن عرض للشريط الجانبي ولدينا list عباره عن bool وفي البداية سوف تكون عباره عن اول عنصر بشكل true وباقي العناصر false وبعد اختيار اي عنصر يتم ارساله وتحويله الى true والباقي false كما هو موضح بالكود ولدينا ايضا NavBarItem وهو عباره عن التصميم الذي يمكنك استخدامه في تطبيقك او البرنامج الذي تعمل عليه حتى تحصل على الشكل المراد بدون ادنى مشاكل .


How to creatw side menu animation with Flutter Project

android sdk manager تحميل flutter developers applications create app android android studio mac


side.dart


import 'package:flutter/material.dart';

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

  @override
  State<MyMobileBody> createState() => _MyMobileBodyState();
}

List<bool> selected = [true, false, false, false, false];


class _MyMobileBodyState extends State<MyMobileBody> {

  List<IconData> icon = [
    Icons.wine_bar,
    Icons.folder,
    Icons.monitor,
    Icons.lock,
    Icons.mail,
  ];

  void select(int n) {
    for (int i = 0; i < 5; i++) {
      if (i == n) {
        selected[i] = true;
      } else {
        selected[i] = false;
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Stack(
        children: [
          Container(
            color: Colors.blue.shade50,
          ),
          Container(
            height: MediaQuery.of(context).size.height,
            width: 150.0,
            decoration: const BoxDecoration(
              color: Color(0xff332A4C),
            ),
            child: Stack(
              children: [
                Positioned(
                  top: 10,
                  child: Column(
                    children: icon
                        .map(
                          (e) => NavBarItem(
                        icon: e,
                        selected: selected[icon.indexOf(e)],
                        onTap: () {
                          setState(() {
                            select(icon.indexOf(e));
                          });
                        },
                      ),
                    )
                        .toList(),
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }

}

class NavBarItem extends StatefulWidget {
  final IconData icon;
  final Function onTap;
  final bool selected;
  // ignore: use_key_in_widget_constructors
  const NavBarItem({
    required this.icon,
    required this.onTap,
    required this.selected,
  });

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

class _NavBarItemState extends State<NavBarItem> with TickerProviderStateMixin {
  late AnimationController _controller1;
  late AnimationController _controller2;

  late Animation<double> _anim1;
  late Animation<double> _anim2;
  late Animation<double> _anim3;
  late Animation<Color?> _color;

  bool hovered = false;

  @override
  void initState() {
    super.initState();
    _controller1 = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 250),
    );
    _controller2 = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 275),
    );
    _anim1 = Tween(begin: 150.0, end: 75.0).animate(_controller1);
    _anim2 = Tween(begin: 150.0, end: 25.0).animate(_controller2);
    _anim3 = Tween(begin: 150.0, end: 50.0).animate(_controller2);
    _color = ColorTween(end: const Color(0xff332a7c), begin: Colors.white)
        .animate(_controller2);

    _controller1.addListener(() {
      setState(() {});
    });
    _controller2.addListener(() {
      setState(() {});
    });
  }

  @override
  void didUpdateWidget(NavBarItem oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (!widget.selected) {
      Future.delayed(const Duration(milliseconds: 10), () {
        //_controller1.reverse();
      });
      _controller1.reverse();
      _controller2.reverse();
    } else {
      _controller1.forward();
      _controller2.forward();
      Future.delayed(const Duration(milliseconds: 10), () {
        //_controller2.forward();
      });
    }
  }
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        widget.onTap();
      },
      child: MouseRegion(
        onEnter: (value) {
          setState(() {
            hovered = true;
          });
        },
        onExit: (value) {
          setState(() {
            hovered = false;
          });
        },
        child: Container(
          width: 150.0,
          color:
          hovered && !widget.selected ? Colors.white12 : Colors.transparent,
          child: Stack(
            children: [
              Positioned(
                child: CustomPaint(
                  painter: CurvePainter(
                    value1: 0,
                    animValue1: _anim3.value,
                    animValue2: _anim2.value,
                    animValue3: _anim1.value,
                  ),
                ),
              ),
              SizedBox(
                height: 80.0,
                width: 100.0,
                child: Center(
                  child: Icon(
                    widget.icon,
                    color: _color.value,
                    size: 20.0,
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class CurvePainter extends CustomPainter {
  final double value1; // 200
  final double animValue1; // static value1 = 50.0
  final double animValue2; //static value1 = 75.0
  final double animValue3; //static value1 = 75.0

  CurvePainter({
    required this.value1,
    required this.animValue1,
    required this.animValue2,
    required this.animValue3,
  });

  @override
  void paint(Canvas canvas, Size size) {
    Path path = Path();
    Paint paint = Paint();

    path.moveTo(150, value1);
    path.quadraticBezierTo(150, value1 + 20, animValue3,
        value1 + 20); // have to use animValue3 for x2
    path.lineTo(animValue1, value1 + 20); // have to use animValue1 for x
    path.quadraticBezierTo(animValue2, value1 + 20, animValue2,
        value1 + 40); // animValue2 = 25 // have to use animValue2 for both x
    path.lineTo(150, value1 + 40);
    // path.quadraticBezierTo(25, value1 + 60, 50, value1 + 60);
    // path.lineTo(75, value1 + 60);
    // path.quadraticBezierTo(150, value1 + 60, 150, value1 + 80);
    path.close();
    path.moveTo(150, value1 + 80);
    path.quadraticBezierTo(150, value1 + 60, animValue3, value1 + 60);
    path.lineTo(animValue1, value1 + 60);
    path.quadraticBezierTo(animValue2, value1 + 60, animValue2, value1 + 40);
    path.lineTo(150, value1 + 40);
    path.close();

    paint.color = Colors.blue.shade50;
    paint.strokeWidth = 150.0;
    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return oldDelegate != this;
  }
}


تعليقات