تطوير واجهة المستخدم مع رفرفة

مرحبا يا هبر! تقديم انتباهكم ترجمة المقال " تخطيطات البناء ".

اليوم نكتشف:


  • كيف يعمل بناة Flutter UI
  • كيفية تخطيط الشاشات أفقيا وعموديا
  • كيفية تعويض الشاشة باستخدام الرفرفة

ستكون نتيجة درس اليوم هي تخطيط الشاشة التالي

الصورة


الخطوة 0: إعداد المشروع


أولاً ، قم بإنشاء ملف مشروع جديد -> مشروع رفرفة جديد -> التالي ، التالي ، التالي ...
بعد ذلك ، قم بإنشاء دليل الصور في جذر المشروع ووضع ملف باسم lake.jpg هناك - يمكنك تنزيل الملف من هنا - الارتباط

من الضروري أيضًا إصلاح pubspec.yaml لملف التكوين (شيء مثل المبارزة لأقراص android and pods في iOS ، يمكننا إضافة تبعيات خارجية فيه). يمكن تنزيل نص الملف نفسه هنا.

يمكن تنزيل مصدر المشروع هنا - يجب وضعه في ملف main.dart

الخطوة 1: مخطط الشاشة


أولاً ، قم بتقسيم التخطيط إلى عناصر بسيطة

  • تحديد الصفوف والأعمدة
  • تحديد ما إذا كان تخطيط يتضمن شبكة؟
  • هل هناك أي عناصر متداخلة
  • هل أحتاج إلى علامات تبويب لواجهة المستخدم؟
  • انتبه إلى المناطق التي تتطلب المحاذاة أو المسافة البادئة

أولا ، نحدد العناصر الكبيرة الرئيسية. في هذا المثال ، يتم ترتيب 4 عناصر في عمود: صورة وصفان وكتلة اختبار

الصورة

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

الصورة

يحتوي الصف التالي ، المسمى قسم الزر ، أيضًا على 3 أطفال. كل واحد منهم يحتوي على صورة ونص.

الصورة

أخيرًا ، وضعنا التصميم في عناصر بسيطة. أسهل طريقة لاستخدام نهج "من القاعدة إلى القمة" لتخطيط الشاشة. لتجنب البنية المعقدة ، قسّم واجهة المستخدم إلى متغيرات ووظائف.

الخطوة 2: بناء صف من الرؤوس


أولاً ، نحتاج إلى بناء العمود الأيسر من قسم الرأس. يؤدي إدراج عمود داخل عنصر واجهة مستخدم قابل للتوسيع إلى توسيع العمود لاستخدام كل المساحة المتبقية في الصف. قم بتعيين خاصية crossAxisAlignment إلى CrossAxisAlignment.start لمحاذاة العمود إلى بداية الصف.

يتيح لك وضع سطر من النص داخل الحاوية تنشيط الحشو. الطفل الثاني في العمود هو أيضًا نص ، حيث يكون باللون الرمادي. يتم تمييز العنصرين الأخيرين برمز "نجمة" باللون الأحمر والنص بقيمة "41". ضع السطر بالكامل في الحاوية وأضف المسافة البادئة 32 بكسل على كل جانب. ويرد رمز لإكمال هذه الخطوات أدناه.

class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { Widget titleSection = Container( padding: const EdgeInsets.all(32.0), child: Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( padding: const EdgeInsets.only(bottom: 8.0), child: Text( 'Oeschinen Lake Campground', style: TextStyle( fontWeight: FontWeight.bold, ), ), ), Text( 'Kandersteg, Switzerland', style: TextStyle( color: Colors.grey[500], ), ), ], ), ), Icon( Icons.star, color: Colors.red[500], ), Text('41'), ], ), ); //... } 

الخطوة 3: بناء سلسلة من الأزرار


يتكون قسم الأزرار من 3 أعمدة ، مبنية وفقًا لمبدأ مماثل - أيقونة أعلى سطر النص. يتم تعبئة العمود في هذا الصف بالتساوي ويتم رسم النص والرموز باللون الرئيسي ، والذي يتم تحديده باللون الأزرق في مشروعنا في طريقة build ().

 class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { //... return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), //... } 

نظرًا لأن كود البناء في كل صف سيكون متطابقًا تقريبًا ، فسيكون من الأكثر فعالية استخدام دالة متداخلة مثل buildButtonColumn () ، والذي يتضمن أيقونة ونصًا ويعيد عمودًا به هذه الأداة.

 class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { //... Column buildButtonColumn(IconData icon, String label) { Color color = Theme.of(context).primaryColor; return Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(icon, color: color), Container( margin: const EdgeInsets.only(top: 8.0), child: Text( label, style: TextStyle( fontSize: 12.0, fontWeight: FontWeight.w400, color: color, ), ), ), ], ); } //... } 

تضيف وظيفة الإنشاء أيقونة مباشرة إلى العمود. ضع النص في الحاوية لإضافة الحشو وفصله عن الرمز. نقوم ببناء كل صف من هذه الأعمدة عن طريق استدعاء وظيفة وتمرير الرمز والنص داخل العمود. قم بمحاذاة العمود على طول المحور الرئيسي باستخدام MainAxisAlignment.spaceEvenly ، وتنظيم مساحة حرة قبل كل عمود وبعده وبعده.

 class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { //... Widget buttonSection = Container( child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ buildButtonColumn(Icons.call, 'CALL'), buildButtonColumn(Icons.near_me, 'ROUTE'), buildButtonColumn(Icons.share, 'SHARE'), ], ), ); //... } 

الخطوة 4: بناء قسم الوصف


تحديد قسم وصف طويل جدا. ضع النص في الحاوية وأضف مسافة بادئة 32 بكسل من كل حافة.

 class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { //... Widget textSection = Container( padding: const EdgeInsets.all(32.0), child: Text( ''' Lake Oeschinen lies at the foot of the Blüemlisalp in the Bernese Alps. Situated 1,578 meters above sea level, it is one of the larger Alpine Lakes. A gondola ride from Kandersteg, followed by a half-hour walk through pastures and pine forest, leads you to the lake, which warms to 20 degrees Celsius in the summer. Activities enjoyed here include rowing, and riding the summer toboggan run. ''', softWrap: true, ), ); //... } 

الخطوة 5: بناء قسم الصور


تم بالفعل بناء ثلاثة من الأعمدة الأربعة ، يبقى فقط لإنشاء عمود الصورة. الصورة المستخدمة في هذا المشروع متاحة على الإنترنت تحت رخصة المشاع الإبداعي. لكنها كبيرة وسيتم تحميلها ببطء. في الخطوة 0 ، أضفنا صورة إلى مشروعنا وقمنا بتحديث ملف التكوين ، والآن سنضيف رابطًا إليه في الكود الخاص بنا.

 return MaterialApp( //... body: ListView( children: [ Image.asset( 'images/lake.jpg', height: 240.0, fit: BoxFit.cover, ), // ... ], ), //... ); 

يخبر BoxFit.cover إطار عمل Flutter أن الصورة يجب أن تكون صغيرة بقدر الإمكان مع تغطية منطقة العرض بأكملها.

الخطوة 6: وضع كل شيء معا


في الخطوة الأخيرة ، سنقوم بجمع جميع أجزاء الكود الخاص بنا معًا. يتم تنظيم عنصر واجهة المستخدم في ListView ، وليس عمودًا لأن ListView سيتم تلقائيًا التمرير أثناء التمرير على جهاز صغير.

 //... return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: Scaffold( appBar: AppBar( title: Text('Top Lakes'), ), body: ListView( children: [ Image.asset( 'images/lake.jpg', width: 600.0, height: 240.0, fit: BoxFit.cover, ), titleSection, buttonSection, textSection, ], ), ), ); //... 

Source: https://habr.com/ru/post/ar433256/


All Articles