Grafer og dataplots er vidunderlige værktøjer til at illustrere forhold, skildre datatendenser og spore mål i dine Android-applikationer. Jeg så dette for mig selv for flere år siden, da en tidligere studerende af mig vandt førstepladsen i en mobilappkonkurrence for studerende sponsoreret af Charleston Defense Contractors Association. Et nøglefunktion i den vindende app, "Diabetes og mig", var evnen til at tegne daglige sukkerindhold.
Som et andet eksempel kan du overveje en vægt-tracking-applikation, der tegner fremskridt i forhold til en målvægt. Figur 1 illustrerer, hvordan en sådan applikation kan se ud på en Android-telefon. Figuren bruger en rød linjegraf til at vise gennemsnitlige månedlige vægte for året 2017. Den viser målvægten som en grøn lige linje nær bunden. (Selvom dataværdierne vist i linjediagrammet er hypotetiske, er de realistiske for forfatteren af denne artikel.)
John I. MooreI denne artikel bruger jeg mit open source-bibliotek, GraphLib, til at demonstrere det grundlæggende ved graftegning af matematiske funktioner i Android. Det er ikke det samme grafbibliotek, som min studerende brugte til sin applikation. Faktisk er det meget enklere og lettere at bruge.
download Download GraphLib Få kildekoden til open source Android-grafbiblioteket, der blev introduceret i denne artikel. Oprettet af John I. Moore.Oversigt over GraphLib
GraphLib
består af en grænseflade og otte klasser. Tre af disse klasser er interne i biblioteket og har kun pakkeadgang, så du behøver ikke forstå dem for at kunne bruge GraphLib. To af de resterende klasser har meget enkel funktionalitet, og resten er ikke svært at hente.
Nedenfor vil jeg beskrive GraphLib-grænsefladen og hver af dens otte klasser. Bemærk, at jeg brugte Java 8-funktioner såsom funktionelle grænseflader og lambda-udtryk til at udvikle og teste biblioteket, men det er relativt ligetil at ændre disse funktioner til tidligere versioner af Java.
GraphLibs funktionelle interface
Som vist i liste 1, interface Fungere
har kun en abstrakt metode og er derfor en funktionel grænseflade. Bemærk, at denne grænseflade stort set svarer til Java 8'er DoubleUnaryOperator
, findes i pakken java.util.function
. Forskellen er, at Fungere
bruger ikke andre Java 8-funktioner end kommentaren @FunktionelInterface
. Fjernelse af denne kommentar er den eneste nødvendige ændring for at foretage Fungere
interface kompatibel med tidligere versioner af Java.
Notering 1. interface Funktion
pakke com.softmoore.android.graphlib; @FunctionalInterface offentlig grænseflade Funktion {offentlig dobbelt anvendelse (dobbelt x); }
At lære om lambda-udtryk
Lambda-udtryk, også kendt som lukninger, funktionsbogstaver eller blot lambdas, beskriver et sæt funktioner defineret i Java Specification Request (JSR) 335. Mindre formelle introduktioner til lambda-udtryk findes i et afsnit i den nyeste version af Java Tutorial; i JavaWorld-artiklen "Java-programmering med lambda-udtryk" og i et par artikler af Brian Goetz, "State of the lambda" og "State of the lambda: Libraries edition."
GraphLib klasser
Klasser Punkt
og Etiket
er relativt enkle: Punkt
indkapsler et par dobbeltværdier, der repræsenterer et punkt i x, y-plan, og Etiket
indkapsler en dobbelt værdi og en streng, hvor den dobbelte værdi repræsenterer et punkt på en akse, og strengen bruges til at mærke dette punkt. Eksemplet i figur 1 bruger punkter til at beskrive linjediagrammet og etiketterne for aksen i bunden, der viser forkortelser med et bogstav for månederne. Jeg giver flere eksempler, der illustrerer brugen af disse klasser senere i artiklen.
Klasser Graffunktion
, GraphPoints
og ScreenPoint
er ikke kun meget enkle, de er også interne i biblioteket og har kun pakkeadgang. Du behøver ikke rigtig forstå disse klasser for at bruge biblioteket, så jeg beskriver dem bare kort her:
Graffunktion
indkapsler en funktion (dvs. en klasse, der implementerer interfaceFungere
) og en farve, der bruges til at tegne denne funktion.GraphPoints
indkapsler en liste over punkter sammen med en farve, der bruges til at plotte dem. Denne klasse bruges internt til både tegning af punkter og tegning af linjegrafer.ScreenPoint
indkapsler et par heltalværdier, der repræsenterer pixelkoordinater på skærmen på en Android-enhed. Denne klasse ligner, men er enklere end Android-klassenPunkt
i pakkeandroid.graphics
.
Jeg har angivet kildekoden til disse klasser, hvis du er interesseret i detaljerne.
De tre resterende klasser i GraphLib-biblioteket er Kurve
, Graf.Bygger
og GraphView
. Det er vigtigt at forstå den rolle, som hver af dem spiller i en Android-applikation.
Klasse Kurve
indeholder oplysninger om farver, punkter, etiketter, grafer osv., der skal tegnes, men er i det væsentlige uafhængig af Android-grafikdetaljer. Mens Kurve
har mange felter, de har alle standardværdier, og derfor giver det mening at bruge Builder-mønsteret til at oprette forekomster af denne klasse. Klasse Kurve
indeholder en indlejret statisk underklasse navngivet Bygger
, som bruges til at oprette Kurve
genstande.
De to klasser Kurve
og Graf.Bygger
gå sammen fra en udviklers perspektiv og skal i det væsentlige forstås som en. I virkeligheden behøver du kun at forstå, hvordan du bruger den indlejrede klasse Bygger
at oprette en Kurve
objekt. Udviklere gør ikke rigtig noget direkte med en Kurve
objekt, efter at det er oprettet, bortset fra at videregive det til en GraphView
objekt, der gør arbejdet med at vise alt på en Android-enhed.
Liste 2 opsummerer de tilgængelige metoder i klassen Graf.Bygger
. Senere eksempler illustrerer, hvordan man bruger Builder-mønsteret til at oprette Kurve
genstande. For nu er det nok at bemærke, at andet end standardkonstruktøren (første linje i liste 2) og bygge ()
metode (sidste linje i liste 2), returnerer alle andre metoder Bygger
objekt. Dette gør det muligt at kæde opkald til byggemetoder.
Liste 2. Oversigt over metoder i klassen Graf.Bygger
public Builder () public Builder addFunction (Function function, int graphColor) public Builder addFunction (Function function) public Builder addPoints (Point [] points, int pointColor) public Builder addPoints (List points, int pointColor) public Builder addPoints (Point [] point) public Builder addPoints (List points) public Builder addLineGraph (Point [] points, int lineGraphColor) public Builder addLineGraph (List points, int lineGraphColor) public Builder addLineGraph (Point [] points) public Builder addLineGraph (List points) public 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 ) public Builder setXTicks (double [] xTicks) public Builder setXTicks (List xTicks) public Builder setYTicks (double [] yTicks) public Builder setYTicks (List yT icks) public Builder setXLabels (Label [] xLabels) public Builder setXLabels (List xLabels) public Builder setYLabels (Label [] yLabels) public Builder setYLabels (List yLabels) public Graph build ()
Du vil bemærke i Listing 2, at mange af metoderne er overbelastede til at acceptere enten arrays af objekter eller lister over objekter. Jeg foretrækker arrays frem for lister for eksempler i denne artikel, simpelthen fordi det er meget lettere at initialisere arrays, men GraphLib
understøtter begge dele. Java 9 vil imidlertid indeholde bekvemme fabriksmetoder til samlinger og derved fjerne denne lille fordel for arrays. Var Java 9 i udbredt anvendelse på tidspunktet for denne artikel, ville jeg have foretrukket lister frem for arrays i begge GraphLib
og de senere eksempler.
Builder-mønsteret
For at lære mere om Builder-mønsteret, se den anden udgave af Effective Java af Joshua Bloch eller JavaWorld-artiklen "For mange parametre i Java-metoder, del 3: Builder-mønster" af Dustin Marx.
Brugergrænsefladesklasser i Android kaldes synspunkterog klasse Udsigt
i pakke android.view
er den grundlæggende byggesten til brugergrænsefladekomponenter. En visning optager et rektangulært område på skærmen og er ansvarlig for tegning og håndtering af begivenheder. Fra et arveperspektiv klasse Udsigt
er en forfædre klasse ikke kun kontrolelementer til brugergrænseflader (knapper, tekstfelter osv.), men også layout, som er usynlige visningsgrupper, der primært er ansvarlige for at arrangere deres underordnede komponenter.
Klasse GraphView
udvider klassen Udsigt
og er ansvarlig for at vise de oplysninger, der er indkapslet i a Kurve
på skærmen på en Android-enhed. Således klasse GraphView
er hvor hele tegningen finder sted.
Brug af GraphLib
Der er to tilgange til oprettelse af brugergrænseflader til Android: en proceduremæssig tilgang (inden for Java-kildekoden) eller en deklarativ tilgang (i en XML-fil). Enten er gyldig, men konsensus er at bruge den deklarative tilgang så meget som muligt. Jeg har brugt en deklarativ tilgang til mine eksempler.
Der er fem grundlæggende trin til brug af GraphLib
bibliotek. Før du starter, skal du downloade den kompilerede Java-kildekode til GraphLib-biblioteket.
Trin 1. Gør graphlib.jar tilgængelig for dit Android-projekt
Opret et nyt projekt ved hjælp af Android Studio, og kopier JAR-filen graphlib.jar
til libs
underkatalog til dit projekts app
vejviser. Skift mappestrukturen fra i Android Studio Android til Projekt. Dernæst i libs
mappe (indlejret i app
mappe), højreklik på JAR-filen og klik på Tilføj som bibliotek. Denne sidste handling tilføjer JAR-filen i afhængighedsafsnittet i din app build.gradle
fil. Se "Sådan tilføjes en krukke i eksterne biblioteker i Android Studio", hvis du har brug for hjælp til dette trin.
Trin 2. Opret en Android-aktivitet, der bruger GraphLib
I Android-applikationer er en aktivitet repræsenterer en enkelt skærm med en brugergrænseflade. Aktiviteter defineres primært i to filer: en XML-fil, der erklærer UI-layoutet og komponenterne, og en Java-fil, der definerer runtime-funktionalitet såsom håndtering af begivenheder. Når et nyt projekt oprettes, opretter Android Studio normalt en standardaktivitet med navnet MainActivity
. Brug denne aktivitet, eller opret en ny til din applikation.
Trin 3. Tilføj en GraphView til layoutet for aktiviteten
I XML-filen for aktivitetens layout erklærer du en GraphView
modsætter sig på samme måde som du erklærer en knap eller en tekstvisning, bortset fra at du skal angive det fulde pakkenavn til GraphView
. Liste 3 viser et uddrag fra en layoutfil, der erklærer en GraphView
efterfulgt af en TextView
som en del af et lodret lineært layout. Efter anbefalet praksis skal de faktiske værdier for bredden og højden af GraphView
er defineret separat dimen
ressourcefiler, hvor forskellige ressourcefiler giver værdier for forskellige skærmstørrelser / densiteter. (Bemærk: Jeg brugte 325 til begge værdier i eksemplerne nedenfor.)
Fortegnelse 3. Erklæring om en GraphView og en TextView i en layout-XML-fil
Trin 4. Importer biblioteksklasser til aktiviteten
Fortegnelse 4 viser listen over importerklæringer til en applikation, hvis biblioteksklasserne importeres individuelt. Listen over import kan forkortes til en enkelt linje som importer com.softmoore.android.graphlib. *
hvis ønsket. Personligt foretrækker jeg at se den udvidede liste som vist i liste 4.
Fortegnelse 4. Importer bibliotekets klasser
import com.softmoore.android.graphlib.Function; import com.softmoore.android.graphlib.Graph; import com.softmoore.android.graphlib.GraphView; import com.softmoore.android.graphlib.Label; import com.softmoore.android.graphlib.Point;
Trin 5. Opret et grafobjekt, og tilføj det til GraphView
Liste 5 viser oprettelsen af et simpelt grafobjekt - i dette tilfælde et grafobjekt, der bruger alle standardværdierne. Det indeholder i det væsentlige kun et sæt x- og y-akser, hvor værdierne på begge akser spænder fra 0 til 10. Noteringen indstiller også en titel til skærmen og tekst til tekstvisningen under grafen.
Fortegnelse 5. Opret et grafobjekt, og føj det til GraphView
Grafgraf = ny Graph.Builder () .build (); GraphView graphView = findViewById (R.id.graph_view); graphView.setGraph (graf); setTitle ("Tom graf"); TextView textView = findViewById (R.id.graph_view_label); textView.setText ("Graf af akser");
Figur 2 viser resultatet af at køre denne applikation på en Android-enhed.
John I. MooreBrug af GraphLib i Android-applikationer
For resten af artiklen vil jeg fokusere på virkelige anvendelser af GraphLib-biblioteket i Android-applikationsudvikling. Jeg præsenterer syv eksempler med korte beskrivelser og kildekodeuddrag. Bemærk, at Java-kodelisterne for disse eksempler er fokuseret på brug Graf.Bygger
for at skabe det rette Kurve
objekt. Opfordrer til findViewById ()
, setGraph ()
, setTitle ()
osv. svarer til dem, der vises i liste 5 og er ikke inkluderet i kodelisterne.