تصميم صفحة sign in و sign up بإستخدام animation في flutter

تصميم صفحة sign in و sign up بإستخدام animation في flutter

 

تصميم صفحة sign in و sign up بإستخدام animation في flutter

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


بسم الله الرحمن الرحيم , في هذا الدرس نقوم لكم صفحة signIn و signUp في flutter وعمل انميشن للانتقال من صفحة الى , حيث ان التصميم بالكامل سوف يكون في نفس الصفحة وهذا الدرس من دروس تصاميم في flutter , ويوجد قسم خاص بهذه التصاميم في موقعنا اذا كنت تريد ان تحسن مستواك في التصميم والتعامل مع الwedgets المختلفه فنحن نقدم كل بين كل فتره والاخرى مجموعة تصاميم يمكنك اخذ منها افكار في تطوير تطبيقات الجوال التي تعملها عليها .


تصميم صفحة login

بدلا من كتابة الكود كامل في صفحة واحده قمنا بتقسيمه الى 4 اجزاء , في هذا الجزء يكون الlogin وهو عباره عن مربع نصي ومربع نصي اخر يمكنك استخدامهم في كتابة اسم المستخدم وكلمة المرور وهذا هو التصميم بكل بساطة


تصميم صفحة login

login.dart


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

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.symmetric(
          horizontal: MediaQuery.of(context).size.width * 0.13),
      child: Form(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Spacer(),
            TextFormField(
              decoration: InputDecoration(
                hintText: "Email",
              ),
            ),
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 16),
              child: TextFormField(
                obscureText: true,
                decoration: InputDecoration(
                  hintText: "Password",
                ),
              ),
            ),
            TextButton(
              onPressed: () {},
              child: Text(
                "Forgot Password?",
                style: TextStyle(color: Colors.white),
              ),
            ),
            Spacer(flex: 2),
          ],
        ),
      ),
    );
  }
}


صفحة register

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


صفحة register

sign_up_form.dart


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

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.symmetric(
          horizontal: MediaQuery.of(context).size.width * 0.13),
      child: Form(
        child: Column(
          children: [
            Spacer(),
            TextFormField(
              decoration: InputDecoration(
                hintText: "Email",
              ),
            ),
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 16),
              child: TextFormField(
                obscureText: true,
                decoration: InputDecoration(
                  hintText: "Password",
                ),
              ),
            ),
            TextFormField(
              obscureText: true,
              decoration: InputDecoration(
                hintText: "Confirm Password",
              ),
            ),
            Spacer(flex: 2)
          ],
        ),
      ),
    );
  }
}


صفحة مواقع التواصل الاجتماعي

الجزء الاخير من الصفحات التي قمنا بعملها وهو تصميم لصفحة مواقع التواصل الاجتماعي وهنا قمنا بعمل صفحة تحتوي فقط على ثلاث عناصر وهم مواقع التواصل الاجتماعي يمكنك تغييرها باي عناصر اخرى او تركها في نهايه الامر القرار يرجع لك .


صفحة مواقع التواصل الاجتماعي

social.dart

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

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        IconButton(onPressed: () {}, icon: Image.asset("assets/fb.png")),
        IconButton(onPressed: () {}, icon: Image.asset("assets/linkedin.png")),
        IconButton(onPressed: () {}, icon: Image.asset("assets/twitter.png")),
      ],
    );
  }
}

تصميم login و register وعمل انتقال بينهم بشكل جديد


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


تصميم login و register وعمل انتقال بينهم بشكل جديد



design.dart

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

  @override
  State<CodeLess> createState() => _CodeLessState();
}

class _CodeLessState extends State<CodeLess> with SingleTickerProviderStateMixin {
  bool isShowSignUp = false;
  late AnimationController animationController;
  late Animation<double> animationTextRotate;

  void setUpAnimation() {
    animationController = AnimationController(vsync: this , duration:const Duration(milliseconds: 300),);
    animationTextRotate = Tween<double>(begin: 0 , end: 90).animate(animationController);
  }

@override
  void initState() {
  setUpAnimation();
  super.initState();
  }

  void updateView(){
    setState(() {
      isShowSignUp = !isShowSignUp;
    });
    isShowSignUp ? animationController.forward() : animationController.reverse();
  }


  @override
  void dispose() {
    animationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size;
    return Scaffold(
        body: AnimatedBuilder(
          animation: animationController,
          builder: (context, snapshot) {
            return Stack(
             children: [
            // login screen
            AnimatedPositioned(
              duration: Duration(milliseconds: 300),
              // width = %88 from screen
              width: size.width * 0.88,
              height: size.height,
              left: isShowSignUp ? -size.width * 0.76 : 0 ,
              child: Container(
                color: Colors.amber,
                child: const LoginForm(),
              ),
            ),

            // register Screen
            AnimatedPositioned(
              duration: Duration(milliseconds: 300),
              // width = %88 from screen
              width: size.width * 0.88,
              height: size.height,
              left: isShowSignUp ? size.width * 0.12 : size.width * 0.88,
              child: GestureDetector(
                onTap: (){

                },
                child: Container(
                  color: Colors.teal,
                  child: SignUpForm(),
                ),
              ),
            ),

            // logo
            AnimatedPositioned(
            duration: Duration(milliseconds: 300),
              // top = 10% from screen
              top: size.height * 0.1,
              left: 0,
              right: isShowSignUp ? - size.width * 0.06 : size.width * 0.06,
              child: CircleAvatar(
                backgroundColor: Colors.white38,
                radius: 25,
                child: isShowSignUp ?
                SvgPicture.asset(
                  "assets/login.svg",
                  color: Colors.amber,
                ) :
                SvgPicture.asset(
                  "assets/login.svg",
                  color: Colors.teal,
                ),
              ),
            ),

            // SocialMedia icons
            AnimatedPositioned(
                duration: Duration(milliseconds: 300),
                width: size.width,
                bottom: size.height * 0.1,
                right: isShowSignUp ? - size.width * 0.06 : size.width * 0.05,
                child: SocalButtns()),

            //login text
            AnimatedPositioned(
                duration: const Duration(milliseconds: 300),
                bottom: isShowSignUp ? size.height / 2 - 80 : size.height * 0.3,
                left: isShowSignUp ? 0 : size.width * 0.44 - 80, // 88 / 2 = 44
                child: AnimatedDefaultTextStyle(
                  duration: const Duration(milliseconds: 300),
                  textAlign:TextAlign.center,
                  style:TextStyle(
                      fontSize: isShowSignUp ? 20 : 32 ,
                      fontWeight: FontWeight.bold ,
                      color: isShowSignUp ?  Colors.white : Colors.white38),
                  child: Transform.rotate(
                  angle: -animationTextRotate.value * pi / 180,
                  alignment: Alignment.topLeft,
                  child: InkWell(
                    onTap:(){
                      if (isShowSignUp) {
                        updateView();
                      } else {
                        // login
                      }
                    },
                    child: Container(
                      padding: const EdgeInsets.symmetric(vertical: 16 * 0.75),
                      width: 160,
                      child: Text('Login'.toUpperCase(),)),
                  ),
                  ),
                )),

            // signUp text
            AnimatedPositioned(
                   duration: const Duration(milliseconds: 300),
                   bottom: !isShowSignUp ? size.height / 2  - 80 : size.height * 0.3,
                   right: isShowSignUp ? size.width * 0.44 - 80 : 0, // 88 / 2 = 44
                   child: AnimatedDefaultTextStyle(
                     duration: const Duration(milliseconds: 300),
                     textAlign:TextAlign.center,
                     style:TextStyle(
                         fontSize: !isShowSignUp ? 20 : 32 ,
                         fontWeight: FontWeight.bold ,
                         color: isShowSignUp ?  Colors.white38 : Colors.white),
                     child: Transform.rotate(
                       angle: (90 - animationTextRotate.value) * pi / 180,
                       alignment: Alignment.topRight,
                       child: InkWell(
                         onTap:(){
                           if (!isShowSignUp) {
                             updateView();
                           }else {
                            // sign up
                           }
                         },
                         child: Container(
                             padding: const EdgeInsets.symmetric(vertical: 16 * 0.75),
                             width: 170,
                             child: Text('Register'.toUpperCase(),)),
          ),
         ),
       )),
      ],
    );
   }
        ));
  }
}


تغيير الtheme الخاص بالالوان في صفحة main

الجزء الاخير وهو تحسين الالوان والتصميم وذلك سوف ننتقل معكم الى صفحة Main لكي نكمل معكم الكود ونقوم بعمل ثيم مخصص للتصميم الذي نعمل عليه , قد لا تحتاج اليه اذا لم يعجبك التصميم الحالي للعناصر ويمكنك عمل تصميم لكل عنصر كما ترغب الامر متروك لك .

تغيير الtheme الخاص بالالوان في صفحة main

فيديو الشرح


لمزيد من المقالات

تعليقات