إنشاء Animation أثناء عمليات تسجيل الدخول في flutter بإستخدام Riv
في هذا المقال والذي يساعدكم في تحسين مظهر تطبيقات الجوال الخاص بكم والتي تقومون بصنعها سوف نقدم لكم شرح لكيفية عمل انميشن اثناء عملية تسجيل الدخول للتطبيق الخاص بك في flutter باستخدام مكتبة riv وهيا خدمه لعمل الانميشن في تطبيقك ويمكنك استخدامها بكل سهوله من اجل الوصول الى التصميم الذي ترغب به في تطبيقك وتحسين المظهر العام للتطبيق وكل هذا مجاني من خلال استخدام المكتبة التي يقدمها لنا موقع riv المخصصه لفلاتر وبعدها يمكنك تحميل اي صورة ترغب بها من الموقع الخاص بهم ولكن في هذه المقاله سوف نقدم لكم تصميم للدب في عملية تسجيل الدخول والخروج من التطبيق الخاص بك ويمكنك تحميل الملف في البداية من خلال الرابط التالي .
Native ARM هي إحدى ميزات Flutter المفيدة للشركات الناشئة والشركات التقنية. يمكّنك من تنفيذ فكرتك وجني ثمارها الكاملة لمشاريعك اللاحقة. سيجد المستخدمون أنه من الأسهل قراءة مواد الويب في تطبيقات الهاتف بفضل هذه الخصائص. يسهل Flutter أيضًا تثبيت التطبيق والتنقل. ثم تبين أن أحدث ترقية لـ Dart.2.2 قد غيرت قواعد اللعبة. تحسين أداء التعليمات البرمجية المترجمة AOT. يتوفر أيضًا عدد من فئات المجموعات في مكتبة dart لنمذجة الخرائط والقوائم ومجموعات الكائنات. تتيح الميزة إمكانية متابعة المعاملة في تطبيقك عندما يبدأ المستخدم واحدة في متجر التطبيقات.
download taddy riv
add package :
rive: ^0.9.1
How to use riv in flutter
في الكود التالي تم عمل اكثر من controller من اجل تتبع حركة الدب وعرض الحركه المخصصه في كل نتيجه نقوم بالبحث بها والكود بسيط جدا وكل شيئ واضح بداخله حاول استخدام موقع riv للتعرف على ال keys التي قمنا باستخدامها في التطبيق من اجل الاستفاده منها ومعرفة كل الحركات التي يستطيع الدب القيام بها .
riv.dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:rive/rive.dart';
enum AnimationEnum {
idle,
Hands_up,
hands_down,
success,
fail,
Look_down_right,
Look_down_left,
look_idle
}
class TeddyPage extends StatefulWidget {
const TeddyPage({Key? key}) : super(key: key);
@override
State<TeddyPage> createState() => _TeddyPageState();
}
class _TeddyPageState extends State<TeddyPage> {
Artboard? riveArtboard;
late RiveAnimationController controllerIdle;
late RiveAnimationController controllerHandsUp;
late RiveAnimationController controllerHandsDown;
late RiveAnimationController controllerLookLeft;
late RiveAnimationController controllerLookRight;
late RiveAnimationController controllerSuccess;
late RiveAnimationController controllerFail;
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
String testEmail = "omar@gmail.com";
String testPassword = "123456";
final passwordFocusNode = FocusNode();
bool isLookingLeft = false;
bool isLookingRight = false;
void removeAllControllers() {
riveArtboard?.artboard.removeController(controllerIdle);
riveArtboard?.artboard.removeController(controllerHandsUp);
riveArtboard?.artboard.removeController(controllerHandsDown);
riveArtboard?.artboard.removeController(controllerLookLeft);
riveArtboard?.artboard.removeController(controllerLookRight);
riveArtboard?.artboard.removeController(controllerSuccess);
riveArtboard?.artboard.removeController(controllerFail);
isLookingLeft = false;
isLookingRight = false;
}
void addIdleController() {
removeAllControllers();
riveArtboard?.artboard.addController(controllerIdle);
debugPrint("idleee");
}
void addHandsUpController() {
removeAllControllers();
riveArtboard?.artboard.addController(controllerHandsUp);
debugPrint("hands up");
}
void addHandsDownController() {
removeAllControllers();
riveArtboard?.artboard.addController(controllerHandsDown);
debugPrint("hands down");
}
void addSuccessController() {
removeAllControllers();
riveArtboard?.artboard.addController(controllerSuccess);
debugPrint("Success");
}
void addFailController() {
removeAllControllers();
riveArtboard?.artboard.addController(controllerFail);
debugPrint("Faillll");
}
void addLookRightController() {
removeAllControllers();
isLookingRight = true;
riveArtboard?.artboard.addController(controllerLookRight);
debugPrint("Righttt");
}
void addLookLeftController() {
removeAllControllers();
isLookingLeft = true;
riveArtboard?.artboard.addController(controllerLookLeft);
debugPrint("Leftttttt");
}
void checkForPasswordFocusNodeToChangeAnimationState() {
passwordFocusNode.addListener(() {
if (passwordFocusNode.hasFocus) {
addHandsUpController();
} else if (!passwordFocusNode.hasFocus) {
addHandsDownController();
}
});
}
@override
void initState() {
super.initState();
controllerIdle = SimpleAnimation(AnimationEnum.idle.name);
controllerHandsUp = SimpleAnimation(AnimationEnum.Hands_up.name);
controllerHandsDown = SimpleAnimation(AnimationEnum.hands_down.name);
controllerLookRight = SimpleAnimation(AnimationEnum.Look_down_right.name);
controllerLookLeft = SimpleAnimation(AnimationEnum.Look_down_left.name);
controllerSuccess = SimpleAnimation(AnimationEnum.success.name);
controllerFail = SimpleAnimation(AnimationEnum.fail.name);
rootBundle.load('assets/animated_login_character.riv').then((data) {
final file = RiveFile.import(data);
final artboard = file.mainArtboard;
artboard.addController(controllerIdle);
setState(() {
riveArtboard = artboard;
});
});
checkForPasswordFocusNodeToChangeAnimationState();
}
void validateEmailAndPassword() {
Future.delayed(const Duration(seconds: 1), () {
if (formKey.currentState!.validate()) {
addSuccessController();
} else {
addFailController();
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xffd6e2ea),
appBar: AppBar(title: const Text('Animated Login')),
body: Padding(
padding: EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width / 20),
child: Column(
children: [
SizedBox(
height: MediaQuery.of(context).size.height / 3,
child: riveArtboard == null
? const SizedBox.shrink()
: Rive(
artboard: riveArtboard!,
),
),
SizedBox(height: 10,),
Form(
key: formKey,
child: Column(
children: [
TextFormField(
decoration: InputDecoration(
labelText: "Email",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(25.0),
),
),
validator: (value) =>
value != testEmail ? "Wrong email" : null,
onChanged: (value) {
if (value.isNotEmpty &&
value.length < 16 &&
!isLookingLeft) {
addLookLeftController();
} else if (value.isNotEmpty &&
value.length > 16 &&
!isLookingRight) {
addLookRightController();
}
},
),
SizedBox(
height: MediaQuery.of(context).size.height / 25,
),
TextFormField(
obscureText: true,
decoration: InputDecoration(
labelText: "Password",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(25.0),
),
),
focusNode: passwordFocusNode,
validator: (value) =>
value != testPassword ? "Wrong password" : null,
),
SizedBox(
height: MediaQuery.of(context).size.height / 18,
),
Container(
width: double.infinity,
padding: EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width / 8,
),
child: TextButton(
style: TextButton.styleFrom(
shape: const StadiumBorder(),
backgroundColor: Colors.blue,
padding: const EdgeInsets.symmetric(vertical: 14),
),
onPressed: () {
passwordFocusNode.unfocus();
validateEmailAndPassword();
},
child: const Text(
'Login',
style: TextStyle(fontSize: 20, color: Colors.white),
),
),
),
],
),
),
],
),
),
);
}
}