Kivy. Xamarin Native reagieren. Drei Frameworks - ein Experiment


Grüße an alle! Sobald der Rauch der hitzigen Diskussion in den Kommentaren zu meinem Artikel Kivy ein Esel-Framework für die plattformübergreifende Entwicklung Nr. 1 ist und unter anderem ein bemerkenswerter Kommentar es gemacht hat , hielten wir ( Mirimon , SeOd ) es für uns und die Leser interessant, Kivy zu vergleichen. Xamarin.Forms und React Native, die dieselbe Anwendung darauf schreiben, begleiten sie mit dem entsprechenden Artikel über Habré, Rübe auf GitHub und sagen Ihnen ehrlich, wer bei der Implementierung mit welchen Schwierigkeiten konfrontiert war. Nachdem wir uns im Telegramm versammelt und die Details besprochen hatten, machten wir uns an die Arbeit.

Für diesen Vergleich haben wir uns entschieden, einen einfachen Taskplaner mit drei Bildschirmen zu schreiben. Es dauert zu lange, den Zustand dieser drei Plattformen heute anhand des Beispiels zu ändern, das umfangreicher ist als das von uns gewählte Beispiel, da jeder mit seinen Projekten / bei der Arbeit / zu Hause beschäftigt ist. Trotz der Einfachheit unserer Anwendung können Sie die Prinzipien der Anwendungsentwicklung in jeder Umgebung klar demonstrieren, mit Daten, Benutzeroberfläche usw. arbeiten.

Drei Frameworks - ein Experiment. Xamarin.Forms. Teil 2
Drei Frameworks - ein Experiment. Native reagieren. Teil 3

Dieser Artikel ist der erste im Zyklus, daher möchte ich mit dem ToR beginnen, den wir für uns selbst skizziert haben, damit das Ergebnis ähnlich ist.

Option TK:


  • Notizen sollten nach Projekten strukturiert sein.
  • Notizen können von verschiedenen Personen hinzugefügt werden, daher muss der Autor der Notiz angegeben werden
  • Notizen innerhalb des Projekts müssen hinzugefügt / gelöscht / bearbeitet werden.
  • Notizen sollten die Größe des Inhalts haben, jedoch nicht mehr als 150 Pixel
  • Das Löschen von Notizen sollte sowohl über das Kontextmenü der Notiz selbst als auch durch Wischen erfolgen

Eine Beispiel-Benutzeroberfläche sollte ungefähr so ​​aussehen:



Bevor Sie beginnen, eine kleine Hilfe zu Kivy:
Kivy ist ein plattformübergreifendes Grafikframework in der Programmiersprache Python / Cython, das auf OpenGL ES 2 basiert und auf die Erstellung moderner Benutzeroberflächen abzielt, die sich mehr auf die Arbeit mit Touch-Geräten konzentrieren. Kivy-Apps laufen auf Plattformen wie Linux, OS X, Windows, Android, iOS und Rapberry Pi. In der Entwicklung haben Sie Zugriff auf eine Vielzahl von Python-Bibliotheken, die von Requests über NumPy bis hin zu OpenCV reichen. Kivy hat über PyJNIus (Android) und PyOBJus (iOS) Zugriff auf fast alle nativen mobilen APIs (GPS, Kamera, Beschleunigungsmesser, Google API für Android), die automatisch Java / Objective-C-Code in Python einbinden .

Kivy ist schnell. Dies gilt sowohl für die Anwendungsentwicklung als auch für die Geschwindigkeit der Anwendungsausführung. Alle kritischen Funktionen werden auf C-Ebene implementiert. Kivy verwendet die GPU auch dort, wo es Sinn macht. Die GPU erledigt den größten Teil der Arbeit und steigert die Leistung erheblich.

Kivy ist sehr flexibel. Dies bedeutet, dass Sie sich dank der rasanten Entwicklung von Kivy sofort an neue Technologien anpassen können. Kivy-Entwickler haben wiederholt Unterstützung für neue externe Geräte und Softwareprotokolle hinzugefügt, manchmal sogar noch vor ihrer Veröffentlichung. Kivy kann in Verbindung mit vielen verschiedenen Lösungen von Drittanbietern verwendet werden. Unter Windows unterstützt Kivy beispielsweise WM_TOUCH. Dies bedeutet, dass jedes Gerät mit Windows 7 Pen & Touch-Treibern mit Kivy funktioniert. Unter OS X können Sie Apple-Geräte mit Multi-Touch-Unterstützung verwenden, z. B. Trackpads und Mäuse. Unter Linux können Sie HID-Eingabe-Eingabeereignisse verwenden. Darüber hinaus unterstützt Kivy TUIO (Tangible User Interface Objects) und eine Reihe anderer Eingabequellen.

Sie können eine einfache Anwendung mit wenigen Codezeilen schreiben. Kivy-Programme werden mit der Programmiersprache Python erstellt, die unglaublich vielseitig und leistungsstark ist, aber einfach zu bedienen ist. Darüber hinaus haben Kivy-Entwickler ihre eigene GUI-Markup-Sprache erstellt, um anspruchsvolle benutzerdefinierte GUIs zu erstellen. Mit dieser Sprache können Sie die Elemente der Anwendung schnell konfigurieren, verbinden und organisieren.

Und ja, Kivy ist völlig frei. Sie können es überall verwenden! In einem kommerziellen Produkt oder in Open Source.

Ich werde den gesamten Anwendungscode angeben und ausreichend detailliert zeigen, wie diese oder jene Elemente bei der Entwicklung für mobile Plattformen implementiert werden. Als IDE verwende ich immer PyCharm , das die Kv-Sprachsyntax perfekt unterstützt - eine spezielle DSL-Sprache, in der die UI-Darstellung Ihrer Anwendung geschrieben ist. Das Skelett der Anwendung wurde mit dem Consor- Dienstprogramm CreatorKivyProject erstellt , das grundlegende Bildschirme mithilfe der MVVM-Vorlage bereitstellt.


Der Basisklassenordner enthält die Logik von Widgets und Steuerelementen, die in der Programmiersprache Python implementiert sind, in kv- Schnittstellenbeschreibungsdateien in der Kv-Sprache . Das Verzeichnis applibs wird für Bibliotheken von Drittanbietern verwendet. Im Datenordner befinden sich Medieninhalte, Datenbanken und andere Daten. Die Datei main.py ist der Einstiegspunkt der Anwendung. Er startet nur die Benutzeroberfläche TodoList (). Run () render, fängt einen Fehler ab, wenn er auftritt, und zeigt ein Fenster zum Senden eines Fehlerberichts an, der automatisch vom Dienstprogramm CreatorKivyProject erstellt wurde. Er hat nichts mit dem Schreiben unserer Anwendung zu tun und wird daher nicht berücksichtigt.

Die Datei todolist.py mit dem Programmcode implementiert die TodoList- Klasse, die die Schnittstellenlayouts lädt, ihre Instanzen initialisiert, die Ereignisse der Hardkeys des Geräts überwacht und unseren ersten Bildschirm zurückgibt, der im Aktivitätsmanager aufgeführt ist. Nach TodoList (). Run () wird die Build- Funktion aufgerufen und gibt das Widget zurück, das auf dem Bildschirm angezeigt wird.

Der Code für ein einfaches Programm, das einen einzelnen Bildschirm mit einem Bild anzeigt, sieht beispielsweise folgendermaßen aus:


Und hier ist das Diagramm unserer Anwendungsklasse:


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 


Unsere Anwendung besteht nur aus drei Aktivitäten . Der Screen Manager ( ScreenMenager ), den wir zu den Build- Funktionen zurückgegeben haben, ist für das Umschalten verantwortlich :

 #: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 

Wenn die Anwendung gestartet wird, wird die Aktivität installiert, die zuerst im ActivityManager angegeben wurde. In unserem Fall ist es ListProjectsActivity . In der Anwendung für Listen von Projekten und Aufgaben habe ich ScrollView verwendet . Obwohl es korrekter war - RecycleView . Denn das erste, wenn es über hundert Beiträge und Projekte gibt, kann es nicht. Genauer gesagt wird das Rendern von Listen sehr lange dauern. Mit RecycleView können Sie Listen beliebiger Länge fast sofort anzeigen. Da Sie bei großen Listen in jedem Fall entweder das dynamische Laden von Daten in eine Liste oder die Paginierung verwenden müssten , dies jedoch im TOR nicht erläutert wurde, habe ich ScrollView verwendet . Der zweite Grund ist, dass ich zu faul war, um die Listen unter RecycleView zu wiederholen (und es unterscheidet sich grundlegend von ScrollView ), und es blieb nicht viel Zeit, da die gesamte Anwendung in vier Stunden in Rauchpausen und Kaffeepausen geschrieben wurde.

Der Startbildschirm mit einer Liste von Projekten (ListProjectsActivity.kv und ListProjectsActivity.py) sieht folgendermaßen aus:


Da das Layout des ListProjectsActivity-Bildschirms bereits auf dem Bildschirm angezeigt wird, werde ich zeigen, wie seine Steuerungsklasse aussieht:

 # -*- 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() 

Dialogfeldaufruf:


In der Arbeit sieht das Aufrufen des Fensters und das Erstellen eines neuen Projekts folgendermaßen aus:

Ich werde nicht auf die Frage nach Anwendungsdaten eingehen, da die Daten ein reguläres Wörterbuch des Formulars sind

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

und die im Datenverzeichnis als einfache JSON-Datei gespeichert ist.

Mal sehen, was das Element mit dem Projektnamen ist und wie man mit Kivy ein Element durch Wischen aus der Liste löscht. Dazu müssen wir das Verhalten des Widgets in der Liste von der SwipeBehavior- Klasse der SwipeToDelete- Bibliothek erben :

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) 

Und die Beschreibung des Projektelements im Kv-Markup:

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) 

Im Allgemeinen verfügt jedes Widget in Kivy über eine on_touch- Methode, mit der Sie alle Ereignisse erfassen können, die auf dem Bildschirm auftreten. Hier ist ein kleiner Teil der Liste der verfügbaren Veranstaltungen:

 ['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'] 


Implementierung des Kontextmenüs für Android ...

Auch hier gab es keine Probleme, da dies nur ein Standard-DropDown-Widget ist. Dank der Tatsache, dass Sie alle Widgets und Steuerelemente in Kivy so anpassen können, wie es Ihre Fantasie zulässt, habe ich leicht ein hübsches Menü erhalten. Links ist die Basis DropDown, rechts ist meine:

Layout der Kontextmenüliste:

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) 

Der Software-Teil des Kontextmenüs:

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) 

Als nächstes importieren wir die MenuDropDown- Schaltfläche aus der Animdropdown- Bibliothek, übergeben ihr das Objekt unseres Kontextmenüs als Parameter und fügen diese Schaltfläche anschließend dem gewünschten Bildschirm hinzu. In unserer Anwendung ist dies die Schaltfläche rechts in der Notizkarte:


Hinweise zur Markup-Aktivitätskarte:


Basisklasse NoteActivity :
 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 


Software-Implementierung von 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) 

Wie verwalte ich die Aktivität der Anwendung? Um von einer Aktivität zu einer anderen zu wechseln, müssen wir dem Bildschirmmanager den Namen der neuen Aktivität mitteilen:

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

... wobei 'Neue Notizaktivität hinzufügen' der Name der Aktivität ist, mit der eine neue Notiz hinzugefügt werden soll.

Bildschirm und Layout der AddNewNoteActivity-Aktivität :


Basisklasse:

 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 

Um die Schaltfläche zu animieren, habe ich das Ereignis on_enter verwendet, das ausgelöst wird, wenn die Aktivität auf dem Bildschirm installiert wird:

Im Markup:

 <AddNewNoteActivity> on_enter: root.animationButton() 

Im Python-Code:

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


Im Gegensatz zu Xamarin.Forms sieht die Benutzeroberfläche in Kivy überall gleich aus. Wenn Sie also eine Anwendung für zwei Plattformen (Android und iOS) schreiben, sollten Sie dies berücksichtigen, wenn Sie die Benutzeroberfläche markieren und Eigenschaften für Widgets angeben. Oder machen Sie zwei Markups für zwei Plattformen (die Logik bleibt unverändert). Dies ist ein Plus, da das Rendern und die Ereignisse der Benutzeroberfläche unabhängig von den Funktionen der Plattform sind. Sie verwenden keine nativen APIs, um diese Aktionen zu steuern. Dadurch kann Ihre Anwendung auf nahezu jeder Plattform problemlos ausgeführt werden. Alle Grafiken werden mit nativen OpenGL- und SDL2-Aufrufen auf der GPU gerendert, sodass Sie schnell Menüs, Schaltflächen und andere Reize der grafischen Oberfläche zeichnen können, einschließlich 2D- und 3D-Grafiken.

Diese Anwendung verwendet das Android UI MaterialDesign. Zum Beispiel hatte mein letztes Projekt eine adaptive Schnittstelle:



Hier ist eine Demonstration der Möglichkeiten im Stil des Materialdesigns:



Wie bereits erwähnt, verwendet Kivy keine nativen APIs zum Rendern der Benutzeroberfläche. Daher können Sie mithilfe des Bildschirmmoduls verschiedene Modelle von Geräten und Plattformen emulieren. Es reicht aus, Ihr Projekt mit den erforderlichen Parametern auszuführen, damit das Fenster der getesteten Anwendung auf dem Computer geöffnet wird, als würde es auf einem realen Gerät ausgeführt. Es klingt seltsam, aber da Kivy beim Rendern der Benutzeroberfläche von der Plattform abstrahiert, sind keine schweren und langsamen Emulatoren für Tests erforderlich. Dies gilt nur für die Benutzeroberfläche. Beispielsweise wurde die in diesem Artikel beschriebene Testanwendung mit den Parametern -m Bildschirm getestet : droid2, Porträt, Maßstab = 0,75 , die eins zu eins meinem realen Gerät entsprechen.

Vollständige Liste der Parameter des Bildschirmmoduls:
 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() } 


Was kann abschließend gesagt werden? Ist Kivy gut? Zweifellos gut! Wenn Sie die wunderbare Programmiersprache Python kennen, können Sie mit dem nicht weniger wunderbaren Kivy-Framework problemlos Anwendungen für mobile (und nicht nur) Plattformen erstellen.

Vorteile der Entwicklung von Anwendungen mit dem Kivy-Framework:

  • Da es sich um Python handelt, ist die Entwicklungsgeschwindigkeit von Anwendungen um ein Vielfaches höher als die Entwicklungsgeschwindigkeit in jeder anderen Programmiersprache oder jedem anderen Framework.
  • Megatonnen vorgefertigter Python-Bibliotheken, die Sie in Ihren Projekten verwenden können: OpenCV, Django, Flask, NumPy, ffmpeg, sqlite3, lxml und Tausende anderer.
  • Da Kivy OpenGL und GPU zum Rendern von Grafiken sowie eigene Widgets und Steuerelemente verwendet, ist die Rendergeschwindigkeit der Benutzeroberfläche sehr hoch und Sie sind vollständig von den Kopfschmerzen befreit, die in anderen Frameworks auftreten, die in den nativen Teil gelangen müssen, um einige Teile der Benutzeroberfläche zu implementieren.
  • Sie verwenden das native System nur dort, wo Sie Zugriff auf bestimmte Plattformfunktionen benötigen, die in einem wirklich plattformübergreifenden Framework einfach nicht vorhanden sind: z. B. Zugriff auf die Geolokalisierung, Zugriff auf die Kamera, BlueTooth-Technologie ...

    Implementieren des Zugriffs auf die native Android-API zum Abrufen von IMEI und Gerätemodell mithilfe von 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()) 


Beispiel: Eine Implementierung von nativen IMEI-Empfangsgeräten in 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; } } 

  • Sie können JAR-Bibliotheken von Drittanbietern in Ihren Projekten verwenden, wenn es um Android geht.
  • Sie besitzen alle auf dem Bildschirm auftretenden Ereignisse vollständig: Berühren, Multitouch, Streichen, Stanzen und andere Ereignisse, ohne zum Eingeborenen zu gehen. Dies ist also ein wesentlicher Bestandteil von Kivy.

Kivy-Funktionen in Touch-Geräten:





Trotz aller Vorteile hat Kivy mehrere Nachteile:

  • Die Geschwindigkeit des "Kaltstarts", dh des ersten Starts der Anwendung ab dem Zeitpunkt, an dem alle Bibliotheken bereitgestellt werden, ist ziemlich lang. Die folgenden sind normal, aber je nach Prozessorlast des Mobilgeräts länger als die native.
  • Mit Listen arbeiten. Sie können eine Liste mit einer Größe von 100.000 Elementen in einer halben Sekunde anzeigen (z. B. Benutzerkarten, Schaufenster, Zitate), jedoch unter einer Bedingung: Alle Karten müssen dieselbe Höhe haben. Wenn Sie beispielsweise eine Liste von Zitaten mit einer unbekannten Textmenge im Voraus, jedoch in ihrer Gesamtheit, anzeigen, können gleichzeitig nicht mehr als zehn Punkte angezeigt werden, da dies etwa 10 bis 15 Sekunden dauert. In diesem Fall müssen Sie jeweils 10-15 Elemente laden, während Sie durch die Liste scrollen.
  • Es ist unmöglich, Text mit mehr als 6500 Zeichen (3,5 Seiten gedruckten Text) anzuzeigen - wir erhalten einen schwarzen Bildschirm. Dies wird gelöst, indem der Text gebrochen und dann zusammengeklebt wird, was immer noch eine Krücke zu sein scheint. Es ist jedoch nicht klar, an wen es denken würde, eine solche Textmenge gleichzeitig auszugeben. Besonders wenn es um mobile Plattformen geht.

Weitere Artikel über Kivy

Eine virtuelle Maschine (der erste Beitrag von ZenCODE) von Kivy-Entwicklern ist bereit und konfiguriert, um Projekte für beide Python-Zweige zu erstellen.

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


All Articles