كيفي. Xamarin رد فعل الأم. ثلاثة أطر - تجربة واحدة


تحياتي للجميع! بمجرد أن يتصاعد الدخان من المناقشة الساخنة في التعليقات على مقالتي ، فإن Kivy هو إطار عمل حمار للتطوير عبر الأنظمة الأساسية رقم 1 ، ومن بين التعليقات الأخرى التي تستحق الانتباه ، فقد اعتقدنا ( Mirimon ، SeOd ) أنه سيكون من الممتع لنا والقراء مقارنة Kivy ، Xamarin.Forms and React Native ، كتابة نفس التطبيق عليهم ، ومرافقته بالمقالة المقابلة حول Habré ، واللفت على GitHub وإخبارك بصدق من الذي واجه الصعوبات أثناء التنفيذ. بعد أن اجتمعنا في البرقية وناقشنا التفاصيل ، بدأنا العمل.

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

ثلاثة أطر - تجربة واحدة. Xamarin.Forms. الجزء 2
ثلاثة أطر - تجربة واحدة. رد فعل الأم. الجزء 3

هذه المقالة هي الأولى في الدورة ، لذلك أريد أن أبدأ بـ ToR ، التي رسمناها لأنفسنا ، بحيث تكون النتيجة مماثلة.

الخيار TK:


  • يجب تنظيم الملاحظات حسب المشروع.
  • يمكن إضافة ملاحظات من قبل أشخاص مختلفين ، لذلك يجب الإشارة إلى كاتب الملاحظة
  • يجب إضافة / حذف / تحرير الملاحظات داخل المشروع.
  • يجب أن تكون الملاحظات بحجم المحتوى ، ولكن ليس أكثر من 150 بكسل
  • يجب أن يتم حذف الملاحظات من خلال قائمة السياق للملاحظة نفسها ومن خلال السحب

يجب أن يبدو مثال واجهة المستخدم على النحو التالي:



قبل أن تبدأ ، القليل من المساعدة في Kivy:
Kivy هو إطار عمل رسومي عبر الأنظمة الأساسية مكتوب بلغة برمجة Python / Cython ، استنادًا إلى OpenGL ES 2 ، يهدف إلى إنشاء واجهات مستخدم حديثة ، أكثر تركيزًا على العمل مع الأجهزة التي تعمل باللمس. تعمل تطبيقات Kivy على أنظمة أساسية مثل Linux و OS X و Windows و Android و iOS و Rapberry Pi. أثناء التطوير ، يمكنك الوصول إلى مجموعة واسعة من مكتبات Python التي تتراوح من الطلبات إلى NumPy و OpenCV. يتمتع Kivy بإمكانية الوصول إلى جميع واجهات برمجة تطبيقات الجوال الأصلية تقريبًا (نظام تحديد المواقع العالمي (GPS) ، الكاميرا ، مقياس التسارع ، واجهة برمجة تطبيقات Google لنظام Android) ، من خلال PyJNIus (Android) و PyOBJus (iOS) ، والتي تلتف تلقائيًا رمز Java / Objective-C في Python .

كيفي سريع. هذا ينطبق على كل من تطوير التطبيقات وسرعة تنفيذ التطبيق. يتم تنفيذ جميع الوظائف الحاسمة على مستوى C. تستخدم Kivy أيضًا GPU أينما كان ذلك منطقيًا. تقوم وحدة معالجة الرسومات بمعظم العمل ، مما يؤدي إلى زيادة الأداء بشكل كبير.

كيفي مرنة للغاية. هذا يعني أن تطوير Kivy سريع الخطى يسمح لك بالتكيف على الفور مع التقنيات الجديدة. أضاف مطورو Kivy دعمًا متكررًا للأجهزة الخارجية وبروتوكولات البرامج الجديدة ، وأحيانًا قبل إصدارها. يمكن استخدام Kivy مع العديد من حلول الجهات الخارجية المختلفة. على سبيل المثال ، في Windows ، يدعم Kivy WM_TOUCH ، مما يعني أن أي جهاز يعمل مع برامج تشغيل Windows 7 Pen & Touch سيعمل مع Kivy. على OS X ، يمكنك استخدام أجهزة Apple مع دعم اللمس المتعدد ، مثل لوحات التتبع وأجهزة الماوس. في Linux ، يمكنك استخدام أحداث إدخال HID. بالإضافة إلى ذلك ، تدعم Kivy TUIO (كائنات واجهة المستخدم الملموسة) وعددًا من مصادر الإدخال الأخرى.

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

ونعم ، Kivy مجاني تمامًا. يمكنك استخدامه في كل مكان! في منتج تجاري أو في مصدر مفتوح.

سأقدم كل كود التطبيق وأظهر بالتفصيل الكافي كيف يتم تنفيذ هذه العناصر أو تلك عند تطويرها لمنصات الجوال. بصفتي IDE ، أستخدم دائمًا PyCharm ، الذي يدعم تمامًا بنية لغة Kv - وهي لغة DSL خاصة يتم كتابة تمثيل واجهة المستخدم الخاص بها لتطبيقك . تم إنشاء الهيكل العظمي للتطبيق باستخدام الأداة المساعدة CreatorKivyProject ، والتي توفر شاشات أساسية باستخدام قالب MVVM.


يحتوي المجلد الأساسي على منطق عناصر واجهة المستخدم وعناصر التحكم التي يتم تنفيذها في لغة برمجة Python ، في ملفات وصف واجهة kv في لغة Kv . يتم استخدام دليل applibs لمكتبات الطرف الثالث ، في مجلد البيانات هناك محتوى الوسائط وقواعد البيانات وغيرها من البيانات. الملف main.py هو نقطة دخول التطبيق. إنه لا يفعل شيئًا سوى تشغيل واجهة المستخدم TodoList (). تشغيل () التقديم ، والتقاط خطأ إذا حدث وعرض نافذة لإرسال تقرير خطأ ، تم إنشاؤه تلقائيًا بواسطة الأداة المساعدة CreatorKivyProject ، ليس له علاقة بكتابة طلبنا ، وبالتالي لا يتم اعتباره.

ينفذ ملف todolist.py الذي يحتوي على رمز البرنامج فئة TodoList ، التي تقوم بتحميل تخطيطات الواجهة ، وتهيئة مثيلاتها ، ومراقبة أحداث المفاتيح الصلبة للجهاز وإرجاع شاشتنا الأولى ، المدرجة في مدير النشاط. بعد TodoList (). Run () ، يتم استدعاء وظيفة الإنشاء وإرجاع الأداة التي سيتم عرضها على الشاشة.

على سبيل المثال ، سيبدو رمز برنامج بسيط يعرض شاشة واحدة مع صورة كما يلي:


وهنا الرسم التخطيطي لفئة التطبيق لدينا:


todolist.py:
# -*- coding: utf-8 -*- import os from kivy.app import App from kivy.lang import Builder from kivy.core.window import Window from kivy.factory import Factory from libs.applibs.kivymd.theming import ThemeManager from libs.dataBase import DataBase class TodoList(App, DataBase): title = 'Todo List' icon = 'icon.png' theme_cls = ThemeManager() theme_cls.primary_palette = 'BlueGrey' def __init__(self, **kvargs): super(TodoList, self).__init__(**kvargs) Window.bind(on_keyboard=self.eventsProgram) Window.softinput_mode = 'below_target' self.Window = Window self.pathToBase = '%s/data/dataProjects.json' % self.directory self.nameAuthor = u' ' def build(self): self.setDataProjects() self.loadAllKvFiles(os.path.join(self.directory, 'libs', 'uix', 'kv')) self.rootScreen = Factory.RootScreen() #    #  Activity. self.activityManager = self.rootScreen.ids.activityManager self.listProjectsActivity = self.rootScreen.ids.listProjectsActivity self.listNotesActivity = self.rootScreen.ids.listNotesActivity self.addNewNoteActivity = self.rootScreen.ids.addNewNoteActivity return self.rootScreen def loadAllKvFiles(self, directory_kv_files): for kv_file in os.listdir(directory_kv_files): kv_file = os.path.join(directory_kv_files, kv_file) if os.path.isfile(kv_file): Builder.load_file(kv_file) def on_start(self): self.listProjectsActivity.setListProjects(self) def eventsProgram(self, instance, keyboard, keycode, text, modifiers): if keyboard in (1001, 27): if self.activityManager.current == 'add new note activity': self.activityManager.backActivity( 'list notes activity', self.addNewNoteActivity.ids.floatingButton) if self.activityManager.current == 'list notes activity': self.activityManager.current = 'list project activity' return True 


يتكون تطبيقنا من ثلاثة أنشطة فقط ، مدير الشاشة ( ScreenMenager ) ، الذي عدناه إلى وظائف البناء ، هو المسؤول عن التبديل :

 #:import ListProjectsActivity libs.uix.baseclass.ListProjectsActivity.ListProjectsActivity #:import ListNotesActivity libs.uix.baseclass.ListNotesActivity.ListNotesActivity #:import AddNewNoteActivity libs.uix.baseclass.AddNewNoteActivity.AddNewNoteActivity #:import ActivityManager libs.uix.baseclass.ActivityManager.ActivityManager <RootScreen@BoxLayout>: orientation: 'vertical' spacing: dp(2) ActivityManager: id: activityManager ListProjectsActivity: id: listProjectsActivity ListNotesActivity: id: listNotesActivity AddNewNoteActivity: id: addNewNoteActivity 

عند بدء تشغيل التطبيق ، سيتم تثبيت النشاط المحدد في ActivityManager أولاً. في حالتنا ، هو ListProjectsActivity . في تطبيق قوائم المشاريع والمهام ، استخدمت ScrollView . على الرغم من أنه كان أكثر صحة - RecycleView . لأن الأول ، إذا كان هناك أكثر من مائة منشور ومشروع ، لا يمكنك القيام بذلك. بتعبير أدق ، سيستغرق تقديم القوائم وقتًا طويلاً جدًا. يتيح لك RecycleView عرض قوائم بأي طول على الفور تقريبًا. ولكن نظرًا لأنه على أي حال ، مع القوائم الكبيرة ، يجب عليك استخدام إما تحميل البيانات الديناميكية في قائمة أو ترقيم صفحات ، ولكن لم تتم مناقشة ذلك في TOR ، لقد استخدمت برنامج ScrollView . والسبب الثاني هو أنني كنت كسولًا جدًا لإعادة عرض القوائم ضمن RecycleView (وهي مختلفة بشكل أساسي في الاستخدام من ScrollView ) ، ولم يكن هناك الكثير من الوقت ، لأن التطبيق بأكمله تمت كتابته في أربع ساعات في فترات استراحة الدخان وفترات القهوة.

تبدو شاشة البدء بقائمة المشاريع (ListProjectsActivity.kv و ListProjectsActivity.py) كما يلي:


نظرًا لأن تخطيط شاشة ListProjectsActivity معروض بالفعل على الشاشة ، فسأوضح كيف تبدو فئة التحكم الخاصة بها:

 # -*- coding: utf-8 -*- from kivy.app import App from kivy.uix.screenmanager import Screen as Activity from libs.uix.baseclass.InputDialog import InputDialog from . ProjectItem import ProjectItem class ListProjectsActivity(Activity): objApp = App.get_running_app() def setListProjects(self, objApp): for nameProject in objApp.dataProjects.keys(): self.ids.layoutContainer.add_widget(ProjectItem(projectName=nameProject)) def createNewProject(self, projectName): if projectName and not projectName.isspace(): self.ids.layoutContainer.add_widget(ProjectItem(projectName=projectName)) self.objApp.addProjectInBase(projectName) def deleteProject(self, instance): for projectName in self.objApp.dataProjects: if instance.projectName == projectName: self.objApp.deleteProjectFromBase(projectName) break def showDialogCreateProject(self, *args): InputDialog( title=' ', hintText=' ', textButtonCancel='', textTuttonOk='', eventsCallback=self.createNewProject).show() 

استدعاء مربع الحوار:


في العمل ، سيبدو استدعاء النافذة وإنشاء مشروع جديد كما يلي:

لن أطيل في السؤال حول بيانات التطبيق ، لأن البيانات عبارة عن قاموس منتظم للنموذج

 {"Name Project": [{"pathToAvatar": "", "nameDate": "", "nameAuthor": "", "textNote": ""}]} 

والتي يتم تخزينها في دليل البيانات كملف json بسيط.

دعونا نرى ما هو العنصر مع اسم المشروع وكيفية استخدام Kivy لحذف عنصر من القائمة عن طريق التمرير السريع؟ للقيام بذلك ، يجب أن نرث سلوك الأداة في القائمة من فئة SwipeBehavior في مكتبة SwipeToDelete :

ProjectItemActivity.py
 from kivy.properties import StringProperty from kivy.uix.boxlayout import BoxLayout from libs.applibs.swipetodelete import SwipeBehavior class ProjectItemActivity(SwipeBehavior, BoxLayout): projectName = StringProperty() def on_touch_down(self, touch): if self.collide_point(touch.x, touch.y): self.move_to = self.x, self.y return super(ProjectItemActivity, self).on_touch_down(touch) def on_touch_move(self, touch): if self.collide_point(touch.x, touch.y): self.reduce_opacity() return super(ProjectItemActivity, self).on_touch_move(touch) def on_touch_up(self, touch): if self.collide_point(touch.x, touch.y): self.check_for_left() self.check_for_right() return super(ProjectItemActivity, self).on_touch_up(touch) 

ووصف عنصر المشروع في ترميز Kv:

ProjectItemActivity.kv
 <ProjectItemActivity>: swipe_rectangle: self.x, self.y , self.width, self.height swipe_timeout: 1000000 swipe_distance: 1 event_after_swipe: app.listActivity.deleteProject OneLineListItem: text: root.projectName on_press: app.listActivity.setNotesProject(root.projectName) 

بشكل عام ، تحتوي كل أداة في Kivy على طريقة on_touch يمكنك من خلالها التقاط أي أحداث تحدث على الشاشة. هنا جزء صغير من قائمة الأحداث المتاحة:

 ['double_tap_time', 'grab_state', 'is_double_tap', 'is_mouse_scrolling', 'is_touch', 'is_triple_tap', 'move', 'push', 'push_attrs', 'push_attrs_stack', 'scale_for_screen', 'time_end', 'time_start', 'time_update', 'triple_tap_time', 'ungrab', 'update_time_end'] 


جاري تنفيذ قائمة السياق لنظام Android ...

لم تكن هناك مشاكل هنا أيضًا ، لأن هذه مجرد أداة DropDown قياسية. بفضل حقيقة أنه يمكنك تخصيص جميع الأدوات وعناصر التحكم في Kivy بقدر ما يسمح لك خيالك ، حصلت بسهولة على قائمة جميلة. على اليسار هو قاعدة DropDown ، على اليمين ملكي:

تخطيط قائمة قائمة السياق:

ContextMenuAndroidActivity.kv
 #:import MDSeparator libs.applibs.kivymd.card.MDSeparator #:import MenuItem libs.applibs.animdropdown.MenuItem <ContextMenuAndroidActivity>: MenuItem: text: '' menu: root on_press: root.tapOnItem(self.text) MDSeparator: MenuItem: text: '' menu: root on_press: root.tapOnItem(self.text) 

جزء البرنامج من قائمة السياق:

ContextMenuAndroidActivity.kv
 from kivy.app import App from kivy.clock import Clock from libs.applibs.animdropdown import AnimMenuDropDown class ContextMenuAndroidActivity(AnimMenuDropDown): def tapOnItem(self, textItem): objApp = App.get_running_app() if textItem == '': objApp.listActivity.deletePost() else: objApp.activityManager.current = 'add new note activity' Clock.schedule_once(objApp.addNewNoteActivity.editNote, .5) 

بعد ذلك ، نستورد زر MenuDropDown من مكتبة الرسوم المتحركة ، ونمرره إلى كائن قائمة السياق كمعلمة ، وبعد ذلك نضيف هذا الزر إلى الشاشة التي نحتاجها. في تطبيقنا ، هذا هو الزر الموجود على اليمين في بطاقة الملاحظات:


ملاحظات بطاقة نشاط الترميز:


ملاحظة أساسية :
 from kivy.app import App from kivy.properties import StringProperty from kivy.uix.boxlayout import BoxLayout from libs.applibs.animdropdown import MenuButton from libs.applibs.swipetodelete import SwipeBehavior from . ContextMenu import ContextMenu class NoteActivity(SwipeBehavior, BoxLayout): nameDate = StringProperty() textNote = StringProperty() pathToAvatar = StringProperty() def __init__(self, **kwargs): super(NoteActivity, self).__init__(**kwargs) self.objApp = App.get_running_app() menuButton = MenuButton( dropdown_cls=ContextMenu, icon='dots-vertical', _on_dropdown_fnc=self.setCurrentPost) self.ids.titleBox.add_widget(menuButton) def setCurrentPost(self, *args): self.objApp.listNotesActivity.checkCurentPost = self 


تنفيذ برنامج ListNotesActivity :
 # -*- coding: utf-8 -*- from kivy.app import App from kivy.uix.screenmanager import Screen as Activity from kivy.properties import ObjectProperty from . NoteActivity import NoteActivity class ListNotesActivity(Activity): checkCurentPost = ObjectProperty() objApp = App.get_running_app() def clearList(self): if self.objApp.activityManager.current == 'list project activity': self.ids.layoutContainer.clear_widgets() def addNewNote(self, objApp): objApp.activityManager.current = 'add new note activity' def setDefaultcheckCurentPost(self): self.checkCurentPost = lambda x: None def setNotesProject(self, nameProject): self.ids.toolBar.title = nameProject for dataProject in self.objApp.dataProjects[nameProject][1]: self.ids.layoutContainer.add_widget(NoteActivity( textNote=dataProject['textNote'], nameDate=dataProject['nameDate'], pathToAvatar=dataProject['pathToAvatar'])) def deletePost(self, instance=None): #  . if not self.checkCurentPost: checkCurentPost = instance else: checkCurentPost = self.checkCurentPost self.ids.layoutContainer.remove_widget(self.checkCurentPost) nameProject = self.ids.toolBar.title self.objApp.deleteNoteFromBase(nameProject, checkCurentPost.textNote) def checkScroll(self): if self.checkCurentPost and type(self.checkCurentPost) is not NoteActivity: self.checkCurentPost(self) 

كيفية إدارة نشاط التطبيق؟ للتبديل من نشاط إلى آخر ، يجب أن نوضح لمدير الشاشة اسم النشاط الجديد:

 class ListNotesActivity(Activity): ... def addNewNote(self, *args): self.objApp.activityManager.current = 'add new note activity' 

... حيث "إضافة نشاط ملاحظة جديد" هو اسم النشاط لإضافة ملاحظة جديدة.

شاشة وتخطيط نشاط AddNewNoteActivity :


الفئة الأساسية:

 from kivy.app import App from kivy.animation import Animation from kivy.uix.screenmanager import Screen as Activity from kivy.metrics import dp from libs.uix.baseclass.NoteActivity import NoteActivity class AddNewNoteActivity(Activity): objApp = None edit = False oldTextNote = '' def animationButton(self): self.objApp = App.get_running_app() self.ids.toolBar.title = self.objApp.listNotesActivity.ids.toolBar.title Animation(size=(dp(56), dp(56)), d=.5, t='in_out_cubic').start(self.ids.floatingButton) def addNewNotes(self, textNote): if self.edit: nameProject = self.ids.toolBar.title self.objApp.addEditNoteInBase(nameProject, textNote, self.oldTextNote) self.objApp.activityManager.backActivity('list notes activity', self.ids.floatingButton) self.objApp.listNotesActivity.checkCurentPost.textNote = textNote self.edit = False return self.objApp.listNotesActivity.ids.layoutContainer.add_widget( NoteActivity( textNote=textNote, nameDate='%s\n%s' % ( self.objApp.nameAuthor, self.objApp.getDate()), pathToAvatar='data/images/avatar.png')) self.objApp.addNoteInBase(self.ids.toolBar.title, textNote, 'data/images/avatar.png') def editNote(self, interval): self.edit = True self.ids.textInput.text = self.objApp.listNotesActivity.checkCurentPost.textNote self.oldTextNote = self.ids.textInput.text 

لتحريك الزر ، استخدمت حدث on_enter ، والذي يتم رفعه عند تثبيت النشاط على الشاشة:

في الترميز:

 <AddNewNoteActivity> on_enter: root.animationButton() 

في كود بايثون:

 class AddNewNoteActivity(Activity): def animationButton(self): Animation(size=(dp(56), dp(56)), d=.5, t='in_out_cubic').start(self.ids.floatingButton) 


على عكس Xamarin.Forms ، ستبدو واجهة المستخدم في Kivy متشابهة في كل مكان. لذلك ، إذا كنت تكتب تطبيقًا لمنصتين (Android و iOS) ، يجب أن تأخذ هذا في الاعتبار عند ترميز الواجهة وتحديد خصائص الأدوات. أو قم بعمل ترميزين لنظامين أساسيين (المنطق يبقى دون تغيير). هذه ميزة إضافية ، نظرًا لأن عرض واجهة المستخدم والأحداث مستقلة عن ميزات النظام الأساسي ، فأنت لا تستخدم واجهات برمجة التطبيقات الأصلية للتحكم في هذه الإجراءات ، مما يسمح بتنفيذ تطبيقك دون ألم على أي نظام أساسي تقريبًا. يتم تقديم جميع الرسومات باستخدام مكالمات OpenGL و SDL2 الأصلية على وحدة معالجة الرسومات ، مما يسمح لك برسم قوائم وأزرار وسحر أخرى للواجهة الرسومية بما في ذلك رسومات ثنائية الأبعاد وثلاثية الأبعاد.

يستخدم هذا التطبيق Android UI MaterialDesign. على سبيل المثال ، كان لمشروعي الأخير واجهة تكيفية:



فيما يلي توضيح للإمكانيات في أسلوب التصميم متعدد الأبعاد:



كما قلت ، لا تستخدم Kivy واجهات برمجة التطبيقات الأصلية لعرض واجهة المستخدم ، وبالتالي فهي تسمح لك بمحاكاة نماذج مختلفة من الأجهزة والأنظمة الأساسية باستخدام وحدة الشاشة . يكفي تشغيل مشروعك بالمعلمات الضرورية حتى تفتح نافذة التطبيق المختبر على الكمبيوتر كما لو كانت تعمل على جهاز حقيقي. يبدو الأمر غريبًا ، ولكن نظرًا لأن Kivy يلخص من النظام الأساسي في عرض واجهة المستخدم ، فإن هذا يلغي الحاجة إلى المحاكيات الثقيلة والبطيئة للاختبارات. ينطبق هذا فقط على واجهة المستخدم. على سبيل المثال ، تم اختبار تطبيق الاختبار الموضح في هذه المقالة باستخدام المعلمات - شاشة m: droid2، portrait، scale = .75 التي يتوافق معها جهاز واحد إلى جهازي الحقيقي.

قائمة كاملة بمعلمات وحدة الشاشة:
 devices = { # device: (name, width, height, dpi, density) 'onex': ('HTC One X', 1280, 720, 312, 2), 'one': ('HTC One', 1920, 1080, 468, 3), 'onesv': ('HTC One SV', 800, 480, 216, 1.5), 's3': ('Galaxy SIII', 1280, 720, 306, 2), 'note2': ('Galaxy Note II', 1280, 720, 267, 2), 'droid2': ('Motorola Droid 2', 854, 480, 240, 1.5), 'xoom': ('Motorola Xoom', 1280, 800, 149, 1), 'ipad': ('iPad (1 and 2)', 1024, 768, 132, 1), 'ipad3': ('iPad 3', 2048, 1536, 264, 2), 'iphone4': ('iPhone 4', 960, 640, 326, 2), 'iphone5': ('iPhone 5', 1136, 640, 326, 2), 'xperiae': ('Xperia E', 480, 320, 166, 1), 'nexus4': ('Nexus 4', 1280, 768, 320, 2), 'nexus7': ('Nexus 7 (2012 version)', 1280, 800, 216, 1.325), 'nexus7.2': ('Nexus 7 (2013 version)', 1920, 1200, 323, 2), # taken from design.google.com/devices # please consider using another data instead of # a dict for autocompletion to work # these are all in landscape 'phone_android_one': ('Android One', 854, 480, 218, 1.5), 'phone_htc_one_m8': ('HTC One M8', 1920, 1080, 432, 3.0), 'phone_htc_one_m9': ('HTC One M9', 1920, 1080, 432, 3.0), 'phone_iphone': ('iPhone', 480, 320, 168, 1.0), 'phone_iphone_4': ('iPhone 4', 960, 640, 320, 2.0), 'phone_iphone_5': ('iPhone 5', 1136, 640, 320, 2.0), 'phone_iphone_6': ('iPhone 6', 1334, 750, 326, 2.0), 'phone_iphone_6_plus': ('iPhone 6 Plus', 1920, 1080, 400, 3.0), 'phone_lg_g2': ('LG G2', 1920, 1080, 432, 3.0), 'phone_lg_g3': ('LG G3', 2560, 1440, 533, 3.0), 'phone_moto_g': ('Moto G', 1280, 720, 327, 2.0), 'phone_moto_x': ('Moto X', 1280, 720, 313, 2.0), 'phone_moto_x_2nd_gen': ('Moto X 2nd Gen', 1920, 1080, 432, 3.0), 'phone_nexus_4': ('Nexus 4', 1280, 768, 240, 2.0), 'phone_nexus_5': ('Nexus 5', 1920, 1080, 450, 3.0), 'phone_nexus_5x': ('Nexus 5X', 1920, 1080, 432, 2.6), 'phone_nexus_6': ('Nexus 6', 2560, 1440, 496, 3.5), 'phone_nexus_6p': ('Nexus 6P', 2560, 1440, 514, 3.5), 'phone_samsung_galaxy_note_4': ('Samsung Galaxy Note 4', 2560, 1440, 514, 3.0), 'phone_samsung_galaxy_s5': ('Samsung Galaxy S5', 1920, 1080, 372, 3.0), 'phone_samsung_galaxy_s6': ('Samsung Galaxy S6', 2560, 1440, 576, 4.0), 'phone_sony_xperia_c4': ('Sony Xperia C4', 1920, 1080, 400, 2.0), 'phone_sony_xperia_z_ultra': ('Sony Xperia Z Ultra', 1920, 1080, 348, 2.0), 'phone_sony_xperia_z1_compact': ('Sony Xperia Z1 Compact', 1280, 720, 342, 2.0), 'phone_sony_xperia_z2z3': ('Sony Xperia Z2/Z3', 1920, 1080, 432, 3.0), 'phone_sony_xperia_z3_compact': ('Sony Xperia Z3 Compact', 1280, 720, 313, 2.0), 'tablet_dell_venue_8': ('Dell Venue 8', 2560, 1600, 355, 2.0), 'tablet_ipad': ('iPad', 1024, 768, 132, 1.0), 'tablet_ipad_mini': ('iPad Mini', 1024, 768, 163, 1.0), 'tablet_ipad_mini_retina': ('iPad Mini Retina', 2048, 1536, 326, 2.0), 'tablet_ipad_pro': ('iPad Pro', 2732, 2048, 265, 2.0), 'tablet_ipad_retina': ('iPad Retina', 2048, 1536, 264, 2.0), 'tablet_nexus_10': ('Nexus 10', 2560, 1600, 297, 2.0), 'tablet_nexus_7_12': ('Nexus 7 12', 1280, 800, 216, 1.3), 'tablet_nexus_7_13': ('Nexus 7 13', 1920, 1200, 324, 2.0), 'tablet_nexus_9': ('Nexus 9', 2048, 1536, 288, 2.0), 'tablet_samsung_galaxy_tab_10': ('Samsung Galaxy Tab 10', 1280, 800, 148, 1.0), 'tablet_sony_xperia_z3_tablet': ('Sony Xperia Z3 Tablet', 1920, 1200, 282, 2.0), 'tablet_sony_xperia_z4_tablet': ('Sony Xperia Z4 Tablet', 2560, 1600, 297, 2.0)TodoList() app.run() } 


ماذا يمكن أن يقال في الختام؟ هل كيفي جيد؟ جيد بلا شك! إذا كنت تعرف لغة برمجة Python الرائعة ، يمكنك بسهولة إنشاء تطبيقات لمنصات الهواتف المحمولة (وليس فقط) مع إطار عمل Kivy الرائع.

مزايا تطوير التطبيقات باستخدام إطار عمل Kivy:

  • نظرًا لأننا نتعامل مع Python ، فإن سرعة تطوير التطبيقات أسرع عدة مرات من سرعة التطوير في أي لغة برمجة أو إطار عمل آخر.
  • ميغا طن من مكتبات Python الجاهزة التي يمكنك استخدامها في مشاريعك: OpenCV و Django و Flask و NumPy و ffmpeg و sqlite3 و lxml وآلاف آخرين.
  • نظرًا لأن Kivy تستخدم OpenGL و GPU لعرض الرسومات ، بالإضافة إلى عناصر واجهة المستخدم وعناصر التحكم الخاصة بها ، فإن سرعة عرض واجهة المستخدم عالية جدًا وتريحك تمامًا من الصداع ، الموجود في أطر أخرى تحتاج إلى الدخول إلى الجزء الأصلي لتنفيذ بعض أجزاء الواجهة.
  • أنت تستخدم اللغة الأصلية فقط حيث تحتاج إلى الوصول إلى ميزات النظام الأساسي المحددة التي لا يمكن أن توجد ببساطة في إطار عمل عبر الأنظمة الأساسية حقًا: على سبيل المثال ، الوصول إلى الموقع الجغرافي ، والوصول إلى الكاميرا ، وتقنية BlueTooth ...

    تنفيذ الوصول إلى واجهة برمجة تطبيقات Android الأصلية للحصول على IMEI وطراز الجهاز باستخدام PyJnius:

 def _get_model_android(): from jnius import autoclass Build = autoclass('android.os.Build') return str(Build.DEVICE) def _get_imei_android(): from jnius import autoclass Service = autoclass('org.renpy.android.PythonActivity').mActivity Context = autoclass('android.content.Context') TelephonyManager = Service.getSystemService(Context.TELEPHONY_SERVICE) return str(TelephonyManager.getDeviceId()) 


على سبيل المثال ، تنفيذ أجهزة IMEI الأصلية في Java:

 import android.content.Context; import android.telephony.TelephonyManager; public class GetImeiAndroid { public String getImeiAndroid() { TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE); String IMEINumber = tm.getDeviceId(); return IMEINumber; } } 

  • يمكنك استخدام مكتبات برطمانات الطرف الثالث في مشاريعك عندما يتعلق الأمر بنظام Android.
  • أنت تمتلك جميع الأحداث التي تحدث على الشاشة تمامًا: اللمس ، اللمس المتعدد ، التمرير ، اللكم ، وغيرها من الأحداث دون الذهاب إلى السكان الأصليين ، لذلك هذا جزء لا يتجزأ من Kivy.

ميزات Kivy في أجهزة اللمس:





على الرغم من كل المزايا ، فإن Kivy لديها العديد من العيوب:

  • إن سرعة "البداية الباردة" ، أي الإطلاق الأول للتطبيق منذ لحظة نشر جميع المكتبات ، طويلة جدًا. أما الوحدات اللاحقة فهي عادية ، ولكنها أطول من الأصلي ، اعتمادًا على حمل المعالج للجهاز المحمول.
  • العمل مع القوائم. يمكنك عرض قائمة بحجم 100000 عنصر في نصف ثانية (على سبيل المثال ، بطاقات المستخدم ، الواجهة ، الاقتباسات) ، ولكن بشرط واحد - يجب أن تكون جميع البطاقات بنفس الارتفاع. إذا قمت بعرض قائمة ، على سبيل المثال ، من الاقتباسات ، مع كمية غير معروفة من النص مقدمًا ، ولكن في مجملها ، في وقت واحد لا يمكن عرض أكثر من عشر نقاط ، لأن هذا سيستغرق حوالي 10-15 ثانية. في هذه الحالة ، سيكون عليك تحميل 10-15 عنصرًا أثناء التمرير عبر القائمة.
  • من المستحيل عرض نص يتجاوز 6500 حرفًا (3.5 صفحات من النص المطبوع) - نحصل على شاشة سوداء. يتم حل ذلك عن طريق كسر النص ثم لصقه معًا ، والذي لا يزال يبدو عكازًا. ومع ذلك ، ليس من الواضح لمن قد يتبادر إلى الذهن لإخراج هذا القدر من النص في كل مرة. خاصة عندما يتعلق الأمر بمنصات الجوال.

المزيد من المقالات حول Kivy

آلة افتراضية (المشاركة الأولى من ZenCODE) من مطوري Kivy جاهزة ومهيأة لبناء مشاريع لكلا فرعي Python.

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


All Articles