Προγραμματισμός

GraphLib: Μια βιβλιοθήκη Android ανοιχτού κώδικα για γραφήματα

Τα γραφήματα και οι γραφικές παραστάσεις δεδομένων είναι υπέροχα εργαλεία για την απεικόνιση των σχέσεων, την απεικόνιση των τάσεων δεδομένων και την παρακολούθηση των στόχων στις εφαρμογές σας Android. Το είδα αυτό για μένα πριν από αρκετά χρόνια, όταν ένας πρώην μαθητής μου κέρδισε την πρώτη θέση σε έναν διαγωνισμό φοιτητικών εφαρμογών για κινητές συσκευές που χρηματοδοτήθηκε από την Ένωση Εργολάβων Άμυνας του Τσάρλεστον. Ένα βασικό χαρακτηριστικό της επιτυχημένης εφαρμογής, "Diabetes and Me", ήταν η ικανότητα να γράφετε καθημερινά επίπεδα σακχάρου.

Ως άλλο παράδειγμα, σκεφτείτε μια εφαρμογή παρακολούθησης βάρους που σχεδιάζει την πρόοδο σε σχέση με ένα βάρος στόχου. Το σχήμα 1 απεικονίζει πώς μπορεί να φαίνεται μια τέτοια εφαρμογή σε τηλέφωνο Android. Ο αριθμός χρησιμοποιεί ένα γράφημα κόκκινων γραμμών για να δείξει τα μέσα μηνιαία βάρη για το έτος 2017. Δείχνει το βάρος στόχου ως πράσινη ευθεία γραμμή κοντά στο κάτω μέρος. (Αν και οι τιμές δεδομένων που εμφανίζονται στο γράφημα γραμμών είναι υποθετικές, είναι ρεαλιστικές για τον συγγραφέα αυτού του άρθρου.)

Τζον Ι. Μουρ

Σε αυτό το άρθρο θα χρησιμοποιήσω τη βιβλιοθήκη ανοιχτού κώδικα, GraphLib, για να δείξω τα βασικά των γραφικών μαθηματικών συναρτήσεων στο Android. Δεν είναι η ίδια βιβλιοθήκη γραφημάτων που χρησιμοποίησε ο μαθητής μου για την εφαρμογή του. Στην πραγματικότητα, είναι πολύ πιο απλό και πιο εύκολο στη χρήση.

λήψη Λήψη GraphLib Λάβετε τον πηγαίο κώδικα για τη βιβλιοθήκη γραφικών Android ανοιχτού κώδικα που παρουσιάζεται σε αυτό το άρθρο. Δημιουργήθηκε από τον John I. Moore.

Επισκόπηση του GraphLib

GraphLib αποτελείται από μία διεπαφή και οκτώ τάξεις. Τρεις από αυτές τις τάξεις είναι εσωτερικές στη βιβλιοθήκη και έχουν μόνο πρόσβαση στο πακέτο, οπότε δεν θα χρειαστεί να τις κατανοήσετε για να χρησιμοποιήσετε το GraphLib. Δύο από τις υπόλοιπες τάξεις έχουν πολύ απλή λειτουργικότητα και οι υπόλοιπες δεν είναι δύσκολο να παραληφθούν.

Παρακάτω θα περιγράψω τη διεπαφή GraphLib και καθεμία από τις οκτώ κατηγορίες της. Σημειώστε ότι χρησιμοποίησα τις δυνατότητες Java 8 όπως λειτουργικές διεπαφές και εκφράσεις lambda για την ανάπτυξη και τη δοκιμή της βιβλιοθήκης, αλλά είναι σχετικά απλό να τροποποιήσω αυτές τις δυνατότητες για παλαιότερες εκδόσεις της Java.

Λειτουργική διεπαφή GraphLib

Όπως φαίνεται στην καταχώριση 1, διεπαφή Λειτουργία έχει μόνο μία αφηρημένη μέθοδο και είναι, συνεπώς, μια λειτουργική διεπαφή. Σημειώστε ότι αυτή η διεπαφή είναι περίπου ισοδύναμη με την Java 8's DoubleUnaryOperator, βρέθηκε στο πακέτο java.util.function. Η διαφορά είναι ότι Λειτουργία δεν χρησιμοποιεί άλλες δυνατότητες Java 8 εκτός από τον σχολιασμό @FunctionalInterface. Η κατάργηση αυτού του σχολιασμού είναι η μόνη απαραίτητη αλλαγή για τη δημιουργία του Λειτουργία διεπαφή συμβατή με παλαιότερες εκδόσεις Java.

Λίστα 1. Λειτουργία διεπαφής

 πακέτο com.softmoore.android.graphlib; @FunctionalInterface δημόσια διεπαφή Λειτουργία {public double apply (double x); } 

Μαθαίνοντας για τις εκφράσεις λάμδα

Οι εκφράσεις λάμδα, επίσης γνωστές ως κλείσιμο, λεξιλόγιο λειτουργίας, ή απλά λάμδα, περιγράφουν ένα σύνολο χαρακτηριστικών που ορίζονται στο Java Specification Request (JSR) 335. Λιγότερες επίσημες εισαγωγές σε lambda εκφράσεις παρέχονται σε μια ενότητα της τελευταίας έκδοσης του Java Tutorial. στο άρθρο JavaWorld "Προγραμματισμός Java με εκφράσεις lambda" και σε μερικά άρθρα του Brian Goetz, "State of the lambda" και "State of the lambda: Libraries edition."

Τάξεις GraphLib

Μαθήματα Σημείο και Επιγραφή είναι σχετικά απλοί: Σημείο ενσωματώνει ένα ζευγάρι διπλών τιμών που αντιπροσωπεύουν ένα σημείο στο x, ε- αεροπλάνο και Επιγραφή ενσωματώνει μια διπλή τιμή και μια συμβολοσειρά, όπου η διπλή τιμή αντιπροσωπεύει ένα σημείο σε έναν άξονα και η συμβολοσειρά χρησιμοποιείται για την επισήμανση αυτού του σημείου. Το παράδειγμα στο Σχήμα 1 χρησιμοποιεί σημεία για να περιγράψει το γράφημα γραμμής και τις ετικέτες για τον άξονα στο κάτω μέρος, δείχνοντας συντομογραφίες ενός γράμματος για τους μήνες. Θα παράσχω περισσότερα παραδείγματα που επεξηγούν τη χρήση αυτών των τάξεων αργότερα στο άρθρο.

Μαθήματα Λειτουργία γραφήματος, Γραφικά σημεία, και Σημείο οθόνης δεν είναι μόνο πολύ απλά, είναι επίσης εσωτερικά στη βιβλιοθήκη και έχουν μόνο πρόσβαση στο πακέτο. Δεν χρειάζεται να καταλάβετε αυτά τα μαθήματα για να χρησιμοποιήσετε τη βιβλιοθήκη, οπότε θα τα περιγράψω εν συντομία εδώ:

  • Λειτουργία γραφήματος ενσωματώνει μια συνάρτηση (δηλαδή, μια κλάση που εφαρμόζει διεπαφή Λειτουργία) και ένα χρώμα που χρησιμοποιείται για τη σχεδίαση αυτής της λειτουργίας.
  • Γραφικά σημεία ενσωματώνει μια λίστα σημείων μαζί με ένα χρώμα που χρησιμοποιείται για να τα σχεδιάσει. Αυτή η τάξη χρησιμοποιείται εσωτερικά τόσο για γραφικά σημεία όσο και για σχεδίαση γραφημάτων γραμμών.
  • Σημείο οθόνης ενσωματώνει ένα ζευγάρι ακέραιων τιμών που αντιπροσωπεύουν συντεταγμένες pixel στην οθόνη μιας συσκευής Android. Αυτή η τάξη είναι παρόμοια με αλλά απλούστερη από την κλάση Android Σημείο σε συσκευασία android.graphics.

Έχω παράσχει τον πηγαίο κώδικα για αυτά τα μαθήματα σε περίπτωση που ενδιαφέρεστε για τις λεπτομέρειες.

Οι τρεις υπόλοιπες τάξεις στη βιβλιοθήκη GraphLib είναι Γραφική παράσταση, Γράφημα. Οικοδόμος, και Προβολή γραφικών. Είναι σημαντικό να κατανοήσετε τον ρόλο που παίζει καθένας από αυτούς σε μια εφαρμογή Android.

Τάξη Γραφική παράσταση περιέχει πληροφορίες σχετικά με τα χρώματα, τα σημεία, τις ετικέτες, τα γραφήματα κ.λπ. που πρόκειται να σχεδιαστούν, αλλά είναι ουσιαστικά ανεξάρτητο από τις λεπτομέρειες γραφικών Android. Ενώ Γραφική παράσταση έχει πολλά πεδία, όλα έχουν προεπιλεγμένες τιμές και επομένως είναι λογικό να χρησιμοποιήσετε το μοτίβο Builder για να δημιουργήσετε παρουσίες αυτής της κλάσης. Τάξη Γραφική παράσταση περιέχει μια ένθετη στατική υποκατηγορία που ονομάζεται Οικοδόμος, το οποίο χρησιμοποιείται για τη δημιουργία Γραφική παράσταση αντικείμενα.

Οι δύο τάξεις Γραφική παράσταση και Γράφημα. Οικοδόμος πηγαίνετε μαζί, από την προοπτική ενός προγραμματιστή, και πρέπει να γίνει κατανοητό, ουσιαστικά, ως ένα. Στην πραγματικότητα, χρειάζεται μόνο να καταλάβετε πώς να χρησιμοποιήσετε την ένθετη τάξη Οικοδόμος για να δημιουργήσετε ένα Γραφική παράσταση αντικείμενο. Οι προγραμματιστές δεν κάνουν πραγματικά τίποτα απευθείας με ένα Γραφική παράσταση αντικείμενο μετά τη δημιουργία του εκτός από το να το μεταβιβάσετε σε ένα Προβολή γραφικών αντικείμενο, το οποίο κάνει το έργο να εμφανίζει τα πάντα σε μια συσκευή Android.

Η Λίστα 2 συνοψίζει τις διαθέσιμες μεθόδους στην τάξη Γράφημα. Οικοδόμος. Αργότερα παραδείγματα θα δείξουν πώς να χρησιμοποιήσετε το μοτίβο Builder για τη δημιουργία Γραφική παράσταση αντικείμενα. Προς το παρόν, αρκεί να σημειωθεί ότι, εκτός από τον προεπιλεγμένο κατασκευαστή (πρώτη γραμμή στην καταχώριση 2) ​​και το χτίζω() μέθοδος (τελευταία γραμμή στη λίστα 2), όλες οι άλλες μέθοδοι επιστρέφουν το Οικοδόμος αντικείμενο. Αυτό καθιστά δυνατή την αλυσίδα κλήσεων σε μεθόδους δημιουργού.

Λίστα 2. Σύνοψη μεθόδων στην τάξη Γράφημα. Οικοδόμος

 public Builder () public Builder addFunction (Function function, int graphColor) public Builder addFunction (Function function) public Builder addPoints (Point [] points, int pointColor) public Builder addPoints (Point list, int pointColor) public Builder addPoints (Σημείο [] πόντους) δημόσιο Builder addPoints (Λίστα πόντων) δημόσιο Builder addLineGraph (Σημείο [] πόντους, int lineGraphColor) δημόσιο Builder addLineGraph (Σημεία λίστας, int lineGraphColor) δημόσιο Builder addLineGraph (Point [] πόντους) δημόσιο Builder addLineGraph (πόντους λίστας) δημόσιο Builder setBackgroundColor (int bgColor) public Builder setAxesColor (int axesColor) public Builder setFunctionColor (int functColor) public Builder setPointColor (int pointColor) public Builder setWorldCoordinates (double xMin, double xMax, double yMin, double yMax) public Builder setAxes δημόσιο Builder setXTicks (διπλό [] xTicks) δημόσιο Builder setXTicks (List xTicks) public Builder setYTicks (double [] yTicks) δημόσιο Builder setYTicks (Λίστα yT icks) public Builder setXLabels (Label [] xLabels) public Builder setXLabels (List xLabels) public Builder setYLabels (Label [] yLabels) δημόσιο Builder setYLabels (List yLabels) δημόσιο Build Graph () 

Στη Λίστα 2 θα παρατηρήσετε ότι πολλές από τις μεθόδους είναι υπερφορτωμένες για να αποδεχτείτε είτε πίνακες αντικειμένων είτε λίστες αντικειμένων. Προτιμώ τις συστοιχίες σε σχέση με λίστες για παραδείγματα σε αυτό το άρθρο, απλώς και μόνο επειδή είναι πολύ πιο εύκολο να ξεκινήσετε τις συστοιχίες, αλλά GraphLib υποστηρίζει και τα δύο. Ωστόσο, η Java 9 θα περιέχει μεθόδους εργοστασιακής ευκολίας για συλλογές, καταργώντας έτσι αυτό το μικρό πλεονέκτημα για συστοιχίες. Ήταν το Java 9 σε ευρεία χρήση τη στιγμή αυτού του άρθρου, θα προτιμούσα λίστες από τις συστοιχίες και στα δύο GraphLib και τα μεταγενέστερα παραδείγματα.

Το μοτίβο Builder

Για να μάθετε περισσότερα σχετικά με το μοτίβο Builder, ανατρέξτε στη δεύτερη έκδοση του Effective Java από τον Joshua Bloch ή το άρθρο JavaWorld "Πάρα πολλές παράμετροι στις μεθόδους Java, Μέρος 3: Μοτίβο Builder" του Dustin Marx.

Οι κατηγορίες διεπαφών χρήστη στο Android καλούνται προβολέςκαι τάξη Θέα σε συσκευασία android.view είναι το βασικό δομικό στοιχείο για στοιχεία διεπαφής χρήστη. Η προβολή καταλαμβάνει μια ορθογώνια περιοχή στην οθόνη και είναι υπεύθυνη για το σχεδιασμό και το χειρισμό συμβάντων. Από την άποψη της κληρονομιάς, τάξη Θέα είναι ένα τάξη προγόνων όχι μόνο των στοιχείων ελέγχου διεπαφής χρήστη (κουμπιά, πεδία κειμένου κ.λπ.), αλλά και διατάξεων, οι οποίες είναι αόρατες ομάδες προβολής που είναι κυρίως υπεύθυνες για τη διευθέτηση των θυγατρικών τους στοιχείων.

Τάξη Προβολή γραφικών επεκτείνει την τάξη Θέα και είναι υπεύθυνη για την εμφάνιση των πληροφοριών που περιλαμβάνονται στο α Γραφική παράσταση στην οθόνη μιας συσκευής Android. Έτσι, τάξη Προβολή γραφικών είναι όπου γίνεται όλο το σχέδιο.

Χρήση του GraphLib

Υπάρχουν δύο προσεγγίσεις για τη δημιουργία διεπαφών χρήστη για Android: μια διαδικαστική προσέγγιση (εντός του πηγαίου κώδικα Java) ή μια δηλωτική προσέγγιση (σε ένα αρχείο XML). Οποιοσδήποτε είναι έγκυρος, αλλά η συναίνεση είναι να χρησιμοποιήσουμε τη δηλωτική προσέγγιση όσο το δυνατόν περισσότερο. Χρησιμοποίησα μια δηλωτική προσέγγιση για τα παραδείγματα μου.

Υπάρχουν πέντε βασικά βήματα για τη χρήση του GraphLib βιβλιοθήκη. Πριν ξεκινήσετε, πραγματοποιήστε λήψη του μεταγλωττισμένου πηγαίου κώδικα Java για τη βιβλιοθήκη GraphLib.

λήψη Λήψη GraphLib.jar Λάβετε τον μεταγλωττισμένο πηγαίο κώδικα Java για το GraphLib. Δημιουργήθηκε από τον John I. Moore.

Βήμα 1. Κάντε το graphlib.jar διαθέσιμο στο έργο σας Android

Δημιουργήστε ένα νέο έργο χρησιμοποιώντας το Android Studio και αντιγράψτε το αρχείο JAR graphlib.jar στο libs υποκατάλογος των έργων σας εφαρμογή Ευρετήριο. Στο Android Studio, αλλάξτε τη δομή φακέλων από Android προς την Εργο. Στη συνέχεια, στο libs φάκελο (ένθετο εντός του εφαρμογή φάκελο), κάντε δεξί κλικ στο αρχείο JAR και κάντε κλικ στο Προσθήκη ως βιβλιοθήκη. Αυτή η τελευταία ενέργεια θα προσθέσει το αρχείο JAR στην ενότητα εξαρτήσεων των εφαρμογών σας build.gradle αρχείο. Ανατρέξτε στην ενότητα "Πώς να προσθέσετε ένα βάζο σε εξωτερικές βιβλιοθήκες στο Android Studio" εάν χρειάζεστε βοήθεια με αυτό το βήμα.

Βήμα 2. Δημιουργήστε μια δραστηριότητα Android που θα χρησιμοποιεί το GraphLib

Σε εφαρμογές Android, ένα δραστηριότητα αντιπροσωπεύει μία μόνο οθόνη με διεπαφή χρήστη. Οι δραστηριότητες ορίζονται κυρίως σε δύο αρχεία: ένα αρχείο XML που δηλώνει τη διάταξη και τα στοιχεία του περιβάλλοντος εργασίας χρήστη και ένα αρχείο Java που ορίζει τη λειτουργικότητα χρόνου εκτέλεσης, όπως ο χειρισμός συμβάντων. Όταν δημιουργείται ένα νέο έργο, το Android Studio δημιουργεί συνήθως μια προεπιλεγμένη δραστηριότητα που ονομάζεται Κύρια δραστηριότητα. Χρησιμοποιήστε αυτήν τη δραστηριότητα ή δημιουργήστε μια νέα για την εφαρμογή σας.

Βήμα 3. Προσθέστε ένα GraphView στη διάταξη της δραστηριότητας

Στο αρχείο XML για τη διάταξη της δραστηριότητας, θα δηλώσετε ένα Προβολή γραφικών αντικείμενο με τον ίδιο τρόπο που δηλώνετε ένα κουμπί ή μια προβολή κειμένου, εκτός από το ότι πρέπει να δώσετε το πλήρες όνομα πακέτου για το Προβολή γραφικών. Η λίστα 3 εμφανίζει ένα απόσπασμα από ένα αρχείο διάταξης που δηλώνει α Προβολή γραφικών ακολουθούμενο από ένα Προβολή κειμένου ως μέρος μιας κάθετης γραμμικής διάταξης. Σύμφωνα με τη συνιστώμενη πρακτική, οι πραγματικές τιμές για το πλάτος και το ύψος του Προβολή γραφικών ορίζονται σε ξεχωριστά εξασθενημένος αρχεία πόρων, όπου διαφορετικά αρχεία πόρων παρέχουν τιμές για διαφορετικά μεγέθη / πυκνότητες οθόνης. (Σημείωση: Χρησιμοποίησα 325 και για τις δύο τιμές στα παρακάτω παραδείγματα.)

Λίστα 3. Δήλωση GraphView και TextView σε αρχείο XML διάταξης

Βήμα 4. Εισαγάγετε τις τάξεις της βιβλιοθήκης στη δραστηριότητα

Η λίστα 4 εμφανίζει τη λίστα των δηλώσεων εισαγωγής για μια εφαρμογή εάν οι τάξεις βιβλιοθήκης εισάγονται ξεχωριστά. Ο κατάλογος των εισαγωγών μπορεί να συντομευτεί σε μία μόνο γραμμή ως εισαγωγή com.softmoore.android.graphlib. * αν είναι επιθυμητό. Προσωπικά, προτιμώ να βλέπω τη διευρυμένη λίστα όπως φαίνεται στην Λίστα 4.

Λίστα 4. Εισαγωγή τάξεων βιβλιοθήκης

 εισαγωγή com.softmoore.android.graphlib.Function; εισαγωγή com.softmoore.android.graphlib.Graph; εισαγωγή com.softmoore.android.graphlib.GraphView; εισαγωγή com.softmoore.android.graphlib.Label; εισαγωγή com.softmoore.android.graphlib.Point; 

Βήμα 5. Δημιουργήστε ένα αντικείμενο γραφήματος και προσθέστε το στο GraphView

Η λίστα 5 δείχνει τη δημιουργία ενός απλού αντικειμένου γραφήματος - σε αυτήν την περίπτωση ένα αντικείμενο γραφήματος που χρησιμοποιεί όλες τις προεπιλεγμένες τιμές. Περιέχει ουσιαστικά μόνο ένα σύνολο Χ- και γ-αξίδες, όπου οι τιμές και στους δύο άξονες κυμαίνονται από 0 έως 10. Η λίστα ορίζει επίσης έναν τίτλο για την οθόνη και το κείμενο για την προβολή κειμένου κάτω από το γράφημα.

Λίστα 5. Δημιουργήστε ένα αντικείμενο γραφήματος και προσθέστε το στο GraphView

 Γράφημα γραφήματος = νέο Graph.Builder () .build (); GraphView graphView = findViewById (R.id.graph_view); graphView.setGraph (γράφημα); setTitle ("Κενό γράφημα"); TextView textView = findViewById (R.id.graph_view_label); textView.setText ("Γράφημα αξόνων"); 

Το σχήμα 2 δείχνει το αποτέλεσμα εκτέλεσης αυτής της εφαρμογής σε μια συσκευή Android.

Τζον Ι. Μουρ

Χρήση του GraphLib σε εφαρμογές Android

Για το υπόλοιπο του άρθρου θα επικεντρωθώ στις πραγματικές χρήσεις της βιβλιοθήκης GraphLib στην ανάπτυξη εφαρμογών Android. Θα παρουσιάσω επτά παραδείγματα με σύντομες περιγραφές και αποσπάσματα πηγαίου κώδικα. Σημειώστε ότι οι λίστες κώδικα Java για αυτά τα παραδείγματα επικεντρώνονται στη χρήση Γράφημα. Οικοδόμος για να δημιουργήσετε το κατάλληλο Γραφική παράσταση αντικείμενο. Κλήσεις προς findViewById (), setGraph (), setTitle (), κ.λπ., θα ήταν παρόμοια με αυτά που εμφανίζονται στην καταχώριση 5 και δεν περιλαμβάνονται στις καταχωρίσεις κώδικα.