Grafer og dataplott er fantastiske verktøy for å illustrere forhold, skildre datatrender og spore mål i Android-applikasjonene dine. Jeg så dette selv for flere år siden, da en tidligere student av meg vant førsteplassen i en mobilappkonkurranse for studenter sponset av Charleston Defense Contractors Association. Et sentralt trekk ved den vinnende appen, "Diabetes and Me", var muligheten til å tegne grafiske daglige sukkernivåer.
Som et annet eksempel kan du vurdere et vekt-sporingsprogram som planlegger fremgang mot en målvekt. Figur 1 illustrerer hvordan en slik applikasjon kan se ut på en Android-telefon. Figuren bruker en rød linjediagram for å vise gjennomsnittlige månedlige vekter for året 2017. Den viser målvekten som en grønn rett linje nær bunnen. (Selv om dataverdiene vist i linjediagrammet er hypotetiske, er de realistiske for forfatteren av denne artikkelen.)
John I. MooreI denne artikkelen bruker jeg open source-biblioteket, GraphLib, for å demonstrere det grunnleggende om å tegne matematiske funksjoner i Android. Det er ikke det samme grafbiblioteket som studenten min brukte til applikasjonen sin. Faktisk er det mye enklere og enklere å bruke.
last ned Last ned GraphLib Få kildekoden til open source Android-grafbiblioteket introdusert i denne artikkelen. Skapt av John I. Moore.Oversikt over GraphLib
GraphLib
består av ett grensesnitt og åtte klasser. Tre av disse klassene er interne i biblioteket og har bare pakketilgang, så du trenger ikke å forstå dem for å kunne bruke GraphLib. To av de resterende klassene har veldig enkel funksjonalitet, og resten er ikke vanskelig å hente.
Nedenfor vil jeg beskrive GraphLib-grensesnittet og hver av de åtte klassene. Merk at jeg brukte Java 8-funksjoner som funksjonelle grensesnitt og lambda-uttrykk for å utvikle og teste biblioteket, men det er relativt greit å endre disse funksjonene for tidligere versjoner av Java.
GraphLibs funksjonelle grensesnitt
Som vist i Oppføring 1, grensesnitt Funksjon
har bare en abstrakt metode og er derfor et funksjonelt grensesnitt. Merk at dette grensesnittet tilsvarer omtrent Java 8-er DoubleUnaryOperator
, funnet i pakken java.util.funksjon
. Forskjellen er at Funksjon
bruker ikke andre Java 8-funksjoner enn kommentaren @FunctionalInterface
. Å fjerne denne merknaden er den eneste endringen som er nødvendig for å gjøre Funksjon
grensesnitt kompatibelt med tidligere versjoner av Java.
Oppføring 1. grensesnitt Funksjon
pakke com.softmoore.android.graphlib; @FunctionalInterface public interface Funksjon {public double apply (double x); }
Lære om lambdauttrykk
Lambda-uttrykk, også kjent som lukkinger, funksjonsbokstaver eller bare lambdas, beskriver et sett med funksjoner definert i Java Specification Request (JSR) 335. Mindre formelle introduksjoner til lambda-uttrykk er gitt i en del av den siste versjonen av Java Tutorial; i JavaWorld-artikkelen "Java-programmering med lambdauttrykk", og i et par artikler av Brian Goetz, "State of the lambda" og "State of the lambda: Libraries edition."
GraphLib-klasser
Klasser Punkt
og Merkelapp
er relativt enkle: Punkt
innkapsler et par doble verdier som representerer et punkt i x, y-fly, og Merkelapp
innkapsler en dobbel verdi og en streng, der dobbeltverdien representerer et punkt på en akse og strengen brukes til å merke det punktet. Eksemplet i figur 1 bruker punkter for å beskrive linjediagrammet og etikettene for aksen nederst, og viser forkortelser med en bokstav for månedene. Jeg vil gi flere eksempler som illustrerer bruken av disse klassene senere i artikkelen.
Klasser Graffunksjon
, GraphPoints
, og ScreenPoint
er ikke bare veldig enkle, de er også interne i biblioteket og har bare pakke tilgang. Du trenger ikke egentlig forstå disse klassene for å bruke biblioteket, så jeg vil beskrive dem bare kort her:
Graffunksjon
innkapsler en funksjon (dvs. en klasse som implementerer grensesnittFunksjon
) og en farge som brukes til å tegne den funksjonen.GraphPoints
innkapsler en liste over punkter sammen med en farge som brukes til å plotte dem. Denne klassen brukes internt til å tegne punkter og tegne linjediagrammer.ScreenPoint
innkapsler et par heltallverdier som representerer pikselkoordinater på skjermen til en Android-enhet. Denne klassen ligner på, men enklere enn Android-klassenPunkt
i pakkeandroid.graphics
.
Jeg har gitt kildekoden for disse klassene i tilfelle du er interessert i detaljene.
De tre gjenværende klassene i GraphLib-biblioteket er Kurve
, Graf.Bygger
, og GraphView
. Det er viktig å forstå hvilken rolle hver av dem spiller i en Android-applikasjon.
Klasse Kurve
inneholder informasjon om farger, punkter, etiketter, grafer, etc., som skal tegnes, men er egentlig uavhengig av Android-grafikkdetaljer. Samtidig som Kurve
har mange felt, de har alle standardverdier, og derfor er det fornuftig å bruke Builder-mønsteret til å lage forekomster av denne klassen. Klasse Kurve
inneholder en nestet statisk underklasse med navnet Bygger
, som brukes til å lage Kurve
gjenstander.
De to klassene Kurve
og Graf.Bygger
gå sammen, fra en utviklers perspektiv, og bør forstås, i det vesentlige, som en. I sannhet trenger du bare å forstå hvordan du bruker den nestede klassen Bygger
å lage en Kurve
gjenstand. Utviklere gjør egentlig ikke noe direkte med en Kurve
gjenstand etter at den er opprettet, annet enn å sende den til en GraphView
objekt, som gjør jobben med å vise alt på en Android-enhet.
Oppføring 2 oppsummerer metodene som er tilgjengelige i klassen Graf.Bygger
. Senere eksempler vil illustrere hvordan du bruker Builder-mønsteret til å lage Kurve
gjenstander. For nå er det nok å merke seg at annet enn standardkonstruktøren (første linje i oppføring 2) og bygge()
metode (siste linje i liste 2), returnerer alle andre metoder Bygger
gjenstand. Dette gjør det mulig å kjede anrop til byggemetoder.
Oppføring 2. Oppsummering av metodene 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 [] poeng) public Builder addPoints (List poeng) public Builder addLineGraph (Point [] poeng, int lineGraphColor) public Builder addLineGraph (List poeng, int lineGraphColor) public Builder addLineGraph (Point [] poeng) public Builder addLineGraph (List poeng) 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 merke deg i oppføring 2 at mange av metodene er overbelastet for å godta enten matriser av objekter eller lister over objekter. Jeg foretrekker arrays fremfor lister for eksempler i denne artikkelen, rett og slett fordi det er mye lettere å initialisere arrays, men GraphLib
støtter begge deler. Imidlertid vil Java 9 inneholde enkle fabrikkmetoder for samlinger, og dermed fjerne denne lille fordelen for matriser. Var Java 9 i utbredt bruk på tidspunktet for denne artikkelen, ville jeg foretrukket lister fremfor matriser i begge GraphLib
og de senere eksemplene.
Byggmønsteret
For å lære mer om Builder-mønsteret, se den andre utgaven av Effective Java av Joshua Bloch eller JavaWorld-artikkelen "Too many parameters in Java methods, Part 3: Builder pattern" av Dustin Marx.
Brukergrensesnittklasser i Android kalles utsikt, og klasse Utsikt
i pakke android.view
er den grunnleggende byggesteinen for brukergrensesnittkomponenter. En visning opptar et rektangulært område på skjermen, og er ansvarlig for tegning og håndtering av hendelser. Fra et arveperspektiv, klasse Utsikt
er en forfedre klasse ikke bare av brukergrensesnittkontroller (knapper, tekstfelt osv.), men også av oppsett, som er usynlige visningsgrupper som først og fremst er ansvarlige for å ordne sine underkomponenter.
Klasse GraphView
utvider klassen Utsikt
og er ansvarlig for å vise informasjonen innkapslet i a Kurve
på skjermen til en Android-enhet. Dermed klasse GraphView
er der all tegningen foregår.
Bruke GraphLib
Det er to tilnærminger for å lage brukergrensesnitt for Android: en prosessuell tilnærming (innenfor Java-kildekoden) eller en deklarativ tilnærming (i en XML-fil). Enten er gyldig, men konsensus er å bruke den deklarative tilnærmingen så mye som mulig. Jeg har brukt en deklarativ tilnærming for eksemplene mine.
Det er fem grunnleggende trinn for å bruke GraphLib
bibliotek. Før du begynner, last ned den kompilerte Java-kildekoden for GraphLib-biblioteket.
Trinn 1. Gjør graphlib.jar tilgjengelig for Android-prosjektet ditt
Opprett et nytt prosjekt ved hjelp av Android Studio og kopier JAR-filen graphlib.jar
til libs
underkatalog til prosjektets app
katalog. Bytt mappestruktur fra i Android Studio Android til Prosjekt. Neste, i libs
mappe (nestet i app
mappe), høyreklikk på JAR-filen og klikk på Legg til som bibliotek. Denne siste handlingen vil legge til JAR-filen i avhengighetsdelen av appen din build.gradle
fil. Se "Slik legger du til en krukke i eksterne biblioteker i Android Studio" hvis du trenger hjelp med dette trinnet.
Trinn 2. Opprett en Android-aktivitet som vil bruke GraphLib
I Android-applikasjoner, en aktivitet representerer en enkelt skjerm med et brukergrensesnitt. Aktiviteter defineres primært i to filer: en XML-fil som deklarerer UI-layout og komponenter, og en Java-fil som definerer kjøretidsfunksjonalitet som hendelsesbehandling. Når et nytt prosjekt opprettes, oppretter Android Studio vanligvis en standardaktivitet som heter Hoved aktivitet
. Bruk denne aktiviteten eller lag en ny for applikasjonen din.
Trinn 3. Legg til en GraphView i oppsettet for aktiviteten
I XML-filen for aktivitetens oppsett, vil du erklære a GraphView
objekt på omtrent samme måte som du erklærer en knapp eller en tekstvisning, bortsett fra at du må oppgi hele pakkenavnet for GraphView
. Listing 3 viser et utdrag fra en layoutfil som erklærer a GraphView
etterfulgt av en TextView
som en del av et vertikalt lineært oppsett. Etter anbefalt praksis skal de faktiske verdiene for bredden og høyden på GraphView
er definert i separate dimen
ressursfiler, der forskjellige ressursfiler gir verdier for forskjellige skjermstørrelser / tettheter. (Merk: Jeg brukte 325 for begge verdiene i eksemplene nedenfor.)
Oppføring 3. Deklarere en GraphView og en TextView i en XML-fil
Trinn 4. Importer bibliotekstimene til aktiviteten
Oppføring 4 viser listen over importuttalelser for et program hvis biblioteklassene importeres individuelt. Listen over import kan forkortes til en enkelt linje som importere com.softmoore.android.graphlib. *
hvis ønsket. Personlig foretrekker jeg å se den utvidede listen som vist i Listing 4.
Oppføring 4. Importer bibliotekstimene
importere com.softmoore.android.graphlib.Function; importere com.softmoore.android.graphlib.Graph; importere com.softmoore.android.graphlib.GraphView; importere com.softmoore.android.graphlib.Label; importere com.softmoore.android.graphlib.Point;
Trinn 5. Opprett et grafobjekt og legg det til i GraphView
Oppføring 5 viser opprettelsen av et enkelt grafobjekt - i dette tilfellet et grafobjekt som bruker alle standardverdiene. Den inneholder i hovedsak bare et sett med x- og y-akser, der verdiene på begge akser varierer fra 0 til 10. Oppføringen setter også en tittel for skjermen og tekst for tekstvisningen under grafen.
Oppføring 5. Opprett et grafobjekt og legg det til i 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 av akser");
Figur 2 viser resultatet av å kjøre dette programmet på en Android-enhet.
John I. MooreBruke GraphLib i Android-applikasjoner
For resten av artikkelen vil jeg fokusere på den virkelige bruken av GraphLib-biblioteket i Android-applikasjonsutvikling. Jeg presenterer syv eksempler med korte beskrivelser og kildekodeutdrag. Merk at Java-kodelistene for disse eksemplene er fokusert på bruk Graf.Bygger
for å lage det passende Kurve
gjenstand. Ringer til findViewById ()
, setGraph ()
, setTitle ()
, etc., vil være lik de som vises i Listing 5 og er ikke inkludert i kodelistene.