للأشخاص الذين يعرفون بالفعل Android:
واجهة المستخدم - يحتاج Android إلى تكامل XML في حين أن كل شيء عبارة
لم يعد المستمعون مستمعين لـ Onclicks ، ويدعون الأساليب ، وتغيير الحالة والتمتع بالمنظر
FindView - لا مزيد من FindViewById () - ما عليك سوى القيام بكل شيء داخل عنصر واجهة المستخدم () {} واترك النتيجة إلى Android
Gradle - لا مزيد من مشكلات Gradle - أضف تبعيات في ملف PubSpec.yaml وتحديث التطبيق لاستخدام المكتبات الجديدة
الأصول - يجب أن تدار بشكل منفصل في رفرفة ، عليك أن تعلن كل ما تستخدمه - على سبيل المثال: الصور ، الخطوط. في Android ، يمكنك ببساطة إضافته في قسم الملفات واستخدامها.
الرسوم المتحركة أسهل بكثير ودعمها بشكل جيد في Flutter - الاستخدامات الأساسية - على سبيل المثال: نشاط الرش ، علامات التمرير ، النتائج ، صفحة التحليلات ، التنقل
تشغيل التطبيق - إعادة التحميل الساخن في Flutter - فقط ضرب 'r' لإعادة التحميل و 'r' لإعادة تشغيل التطبيق. يمكن أن يستغرق Android Studio ما يصل إلى 20-30 ثانية لكل إعادة تحميل ، وحتى أكثر إذا كانت هناك مشكلات Gradle ، والتي تنبثق مرة واحدة كل مرة
API - يمكن إجراء واجهات برمجة تطبيقات Android مع مكتبات مختلفة مثل Retrofit باستخدام GSON ، في حين يمكن إجراء جلب في الرفرفة دون أي ألم. يمكن استخدام وظيفة الجلب المشتركة في الرفرفة ولديها أساليب Async لاتصال واجهات برمجة التطبيقات.
عرض Recycler/List - يتم استخدام عرض Recycler في Android لإنشاء قوائم مختلفة على الشاشة. نحتاج إلى محول لتلك التي تحتوي على واجهة ونحتاج إلى معرفة جميع أنواع الوظائف المختلفة لتنفيذها بالكامل. يحتوي Flutter فقط على عنصر واجهة مستخدم لمشاهدة ListView حيث يمكننا تحديد Listtiles المختلفة أو إضافة الأشياء بشكل ديناميكي. أسهل بكثير ، تبدو أبسط.
منحنى التعلم - العمل في Flutter أسهل بمجرد معرفة Dart ، وهو ما يشبه JavaScript ، وفهم المفاهيم الأساسية حول الأدوات. يتيح لك Android إجراء تخطيطات بمساعدة المصمم ، والتي يمكن استخدامها لإجراء تخطيطات القيود. من المؤكد أن إجراء التطبيقات الأساسية أسهل في التعلم في Android ، ولكن مع تقدمنا في الشظايا وغيرها من الأشياء ، يبدأ الأمر في التعقيد
شظايا مقابل مكونات (أجهزة واجهة المستخدم) - يمكننا ببساطة استخدام مكون عنصر واجهة المستخدم أينما نريد على عكس الشظايا التي نصنعها في Android ، والتي تتطلب بعض المعرفة قبل استخدام حزمة ، محولات ، تخطيطات XML ، وطرق مختلفة مثل onCreateview و layoutinflator
قاعدة بيانات SQL - تشبه إلى حد كبير في كل من التقنيات. الفرق الوحيد هو أن إدارة الحالة يمكن أن تدخل في مكانها إذا كنت تحاول إضافة شيء على التوالي ، فسيتعين عليك تخزين المفتاح في الحالة وتغييره باستخدام setState () {_ Key+= 1} -> مجرد حالة استخدام. مكتبة الغرفة في Android تستخدم على نطاق واسع للغاية وسهلة التنفيذ أيضًا
أنماط الهندسة المعمارية - كل شيء يتلخص في MVP/ MVVM/ MVC في Android ، في حين أن لدينا كتلة ومقدمين في رفرفة ، والتي تفعل شيئًا مشابهًا لـ MVC ، وفصل منطق العمل عن طريق إنشاء الأحواض والتدفقات
محرر الرمز - VSCODE/Android Studio - Flutter و Android Studio لنظام Android
دليل البدء - Straighforward for Android ، قم بتنزيل الاستوديو والبدء ، في حين أن عليك القيام بمجموعة من الأشياء من أجل الرفرفة - يمكن أن تكون مزعجة
Firebase - موارد Flutter Firebase: -
https://firebase.google.com/docs/flutter/setup
https://flutter.dev/docs/development/data-and-backend/firebase
https://www.youtube.com/watch؟v=8m-fa239hy4
https://www.youtube.com/channel/ucftm1fgjzskospdzgtbp7ho/search؟query=firebase
https://codelabs.developers.google.com/codelabs/flutter-firebase/#0
اتصال Firebase - من الأسهل بالتأكيد تنفيذ Flutter ، يمكنك القيام بذلك في 20 سطرًا من التعليمات البرمجية حسب عرض القائمة الذي تقوم به. الأساسيات هي نفسها ، فأنت بحاجة إلى ملفات .json وعليها إضافتها إلى وحدة تحكم Firebase. يساعدك الترميز في رفرفة على فهمه بطريقة أفضل بكثير. بشكل عام ، إنه مشابه.
Lists + Firebase - يحتوي Android على وجهات نظر مجنونة لإعادة التدوير التي تجعل كل شيء صعبًا للغاية ، ودمج Firebase + Recycler View يحتوي على حوالي 200 مقالة ، ولا يمكنك إتقانها. لم يكن هناك أي طريقة لتطبيق شيء في Android بدون برنامج تعليمي ، ولكن في الرفرفة ، يمكنك دائمًا المحاولة
جلب البيانات - دفع البيانات - دفع البيانات أسهل أيضًا في Flutter Firebase ، هناك حرفيًا طريقة ONTAP () تتيح لك إرسال لقطة من البيانات
التعلم الآلي - دمج التعلم الآلي
واجهة المستخدم - Flutter و RN لديها نظام ملف واحد ، حيث تحدد القواعد و UI. أنا شخصياً أحب واجهة تطبيقات Flutter لأنها محددة كثيرًا. يتم الحفاظ عليها أيضًا بواسطة Google التي تمتلك Android ويمكن أن يكون لها تكامل أفضل مع Google.
الفصول - تستخدم Flutter عناصر واجهة المستخدم لكل شيء حرفيًا ، من TextViews إلى TabViews - يطلق عليها "عناصر واجهة المستخدم". يستخدم Flutter Dart ، في حين يستخدم React Native TypeScript أو JavaScript.
المكونات - RN تحتوي على مكونات وعلينا استيرادها من "React -Itive" لاستخدامها. الرفرفة لديها أجهزة واجهة المستخدم التي يمكن استخدامها في مساحة مماثلة. كلاهما متشابهان باستثناء التصميم والجزء التقديم.
رفرفة التصميم - داخل الحاجيات - لذلك إذا كنت تريد حشوة => ، فأنت تغلب عنصر واجهة المستخدم في الحشو مع بعض الحشوة ، React Native: يمكنك تحديد نمط const: ورقة الأنماط وإضافة أنماطك هناك - على غرار نمط الويب الذي لديك CSS. لذلك React Native لديه تصميم CSS في حين أن Flutter لديه تصميم "عنصر واجهة المستخدم"
الرسوم المتحركة - Flutter أسهل بكثير في Grasb ، في حين أن React Native لديه جانب أوسع لها
منحنى التعلم - مشابه في React Native و Flutter.
المكتبات - NPM تساعد في React Native ، بينما نضيفها فقط من أجل الرفرفة إلى ملف PubSpec.yaml
واجهات برمجة التطبيقات - كلاهما لديه رؤية واضحة لاستخدام واجهات برمجة التطبيقات. مقالة جيدة لـ RN-https://medium.com/better-programming/handling-api-like-a-boss-in-niater-364abd92dc3d
محرر الرمز - VS Code شائع لكليهما
البدء - شخصياً ، كان من الصعب حقًا العمل مع React Native على Windows. من الأفضل بكثير إذا كنت تستخدم جهاز Mac ، ولكن بشكل عام تزعجك الشاشة الحمراء كثيرًا. Flutter ليس لديه دليل البدء الأسهل ، ولكن هناك دعم لمساعدتك.
بشكل عام - يمكن أن يصنع كلاهما التطبيقات الأصلية المتقاطعة وسأختار Flutter anyday - Hackathons/ Quick Projects/ Learn Android أيضًا ، وتفاعل Web/ Learn React.js/ -> إذا كنت تريد التأكيد على نفسك: P



fetch () async {
var url = "API-HERE" ;
var res = await http. get (url);
var body = jsonDecode (res.body);
// body is your API body
}content description إلى زر ، أو TextView وما إلى ذلك في Android لـ Voice Over https://steemit.com/utopian-io/@tensor/advanced-flutter-project-best-practices-generic-bloc-providers-part-three
class App extends StatelessWidget {
@override
Widget build ( BuildContext context) {
// TODO: implement build
return MaterialApp (
home : Home (),
theme : ThemeData (primaryColor : PrimaryColor ), //add-your-color here || or remove this
debugShowCheckedModeBanner : false ,
);
}
}
class Home extends StatefulWidget {
@override
State < StatefulWidget > createState () {
// TODO: implement createState
return new _HomeState ();
}
}
class _HomeState extends State < Home >{
@override
Widget build ( BuildContext context) {
return Scaffold (
body : Column ()
);
}child : users.length <= 0
? Center (
child : EmptyState (
title : 'Oops' ,
message : 'Add form by tapping add button below' ,
),
)
: ListView . builder (
addAutomaticKeepAlives : true ,
itemCount : users.length,
itemBuilder : (_, i) => users[i],
),
) fetch () async {
var url = "API-HERE" ;
var res = await http. get (url);
var body = jsonDecode (res.body);
// body is your API body
} for ( int i = 0 ;i < body[ 0 ][ 'staggered_tiles' ].length;i ++ ){
_staggeredTiles. add ( new StaggeredTile . count (
body[ 0 ][ 'staggered_tiles' ][i][ 'cross_axis' ], // body is what we get from the API
body[ 0 ][ 'staggered_tiles' ][i][ 'main_axis' ] // body is what we get from the API
));
}
if (body[i][ 0 ][ 'type' ] == 'donut' ) {
List < LabelPieSales > _d = [];
for ( int j = 0 ; j < body[i][ 0 ][ 'data' ].length; j ++ ) {
_d. add ( new LabelPieSales (
body[i][ 0 ][ 'data' ][j][ 'year' ], body[i][ 0 ][ 'data' ][j][ 'sales' ])); // body is what we get from the API
}
_wid_top. add ( new Container (
height : 200 ,
width : 200 ,
child : DonutChartWidget . withSampleData (_d),
));
}
else if (body[i][ 0 ][ 'type' ] == 'label-pie' ) {
List < LabelPieSales > _d = [];
for ( int j = 0 ; j < body[i][ 0 ][ 'data' ].length; j ++ ) {
_d. add ( new LabelPieSales (
body[i][ 0 ][ 'data' ][j][ 'year' ], body[i][ 0 ][ 'data' ][j][ 'sales' ])); // body is what we get from the API
}
_wid_top. add ( new Container (
height : 200 ,
width : 200 ,
child : SimpleBarChart . withSampleData (_d),
));
} return Container (
padding : const EdgeInsets . all ( 4.0 ),
child : appState.isFetching
? CircularProgressIndicator ()
: appState. getResponseJson () != null
? ListView . builder (
primary : false ,
shrinkWrap : true ,
itemCount : appState. getResponseJson ().length,
itemBuilder : (context, index) {
return Container (
height : 100 ,
width : 100 ,
child : graph (appState. getResponseJson ()),
);
},
)
: Text ( "Press Button above to fetch data" ),
); initDB () async {
return await openDatabase (
join ( await getDatabasesPath (), 'graphs_database.db' ),
onCreate : (db, version) {
return db. execute (
"CREATE TABLE graphs(id INTEGER PRIMARY KEY, type TEXT)" ,
);
},
version : 1 ,
);
}floatingActionButton : FloatingActionButton (
child : Icon ( Icons .add),
onPressed : () async {
Dog dog = new Dog (id : _id, name : "name" ,age : 22 );
await insertDog (dog);
setState (() {
_id += 1 ;
});
},
), List < Graph > graphs_sql = await graphs ();
List < String > graphs_sql_types = [];
for ( int i = 0 ;i < graphs_sql.length;i ++ ){
graphs_sql_types. add (graphs_sql[i].type);
}
if (graphs_sql.length != _types.length) {
for ( int i = 0 ; i < _types.length; i ++ ) {
if ( ! graphs_sql_types. contains (_types[i])){ // add only if a new type
await insertGraph ( new Graph (id : i, type : _types[i]));
}
}
} launchUrl () {
setState (() {
urlString = controller.text;
flutterWebviewPlugin. reloadUrl (urlString);
});
} class News {
String dateAdded;
String title;
String body;
String level;
String category;
News ( this .dateAdded, this .title, this .body, this .level, this .category);
}
class Record {
final String name;
final int votes;
final DocumentReference reference;
Record . fromMap ( Map < String , dynamic > map, { this .reference})
: assert (map[ 'name' ] != null ),
assert (map[ 'votes' ] != null ),
name = map[ 'name' ],
votes = map[ 'votes' ];
Record . fromSnapshot ( DocumentSnapshot snapshot)
: this . fromMap (snapshot.data, reference : snapshot.reference);
@override
String toString () => "Record<$ name :$ votes >" ;
} double _height = MediaQuery . of (context).size.height;
double _width = MediaQuery . of (context).size.width; @override
void initState () {
// TODO: implement initState
super . initState ();
_image = {url};
localList1 = globalList1;
localList1 = globalList2;
} export const sendToTopic = functions.firestore
.document( 'recipes/{recipyId}' )
.onCreate(async snapshot => {
// const recipe = snapshot.data();
const payload : admin.messaging.MessagingPayload = {
notification: {
title: 'new recipe added, check it out' ,
body: 'Make it and eat it'
}
};
return fcm. sendToTopic ( 'recipes' , payload);
}); @override
Widget build ( BuildContext context) {
return Scaffold (
appBar : AppBar (title : Text ( 'Recipes for you' )),
body : _buildBody (context),
);
}
Widget _buildBody ( BuildContext context) {
return StreamBuilder < QuerySnapshot >(
stream : Firestore .instance. collection ( 'recipes' ). snapshots (),
builder : (context, snapshot) {
if ( ! snapshot.hasData) return LinearProgressIndicator ();
return _buildList (context, snapshot.data.documents);
},
);
} List<Recipe> recipe_list = [];
// snapshot.map((data) => recipeList(context, data).toList());
for(int i=0;i<snapshot.length;i++){
Recipe recipe = Recipe.fromSnapshot(snapshot[i]);
recipe_list.add(recipe);
}
return AsymmetricView(products: recipe_list,);