Opprette Sammensatte Visninger på Android

Creating Sammensatte Visninger på Android
27
Del
3
Del

Dette Cyber ​​mandag Envato Tuts + kurs vil bli redusert til bare $ 3. Ikke gå glipp av.

Når du bygger komplekse applikasjoner, vil du ofte ønsker å gjenbruke den samme gruppen av synspunkter på forskjellige steder i programmet. En måte å løse dette problemet er ved å opprette en visning som innkapsler logikk og layout av en gruppe på visninger slik at du kan bruke dem uten å duplisere kode i ulike steder av prosjektet. I denne opplæringen vil du lære hvordan du bruker synspunkter sammensatte å opprette egendefinerte visninger som er lett gjenbrukes.

1. Innledning

På Android, er et syn bestående av en gruppe av synspunkter kalles et sammensatt syn eller en forbindelse komponent. I denne opplæringen, vil du bygge opp en kontroll for å velge en verdi fra en liste som ruller fra side til side. Vi vil kalle det sammensatte en side spinner siden standardvisningen av Android SDK for å plukke en verdi fra en liste som kalles en spinner. Følgende skjermbilde illustrerer hva vi skal opprette i denne opplæringen.

2. Prosjektet Setup

For å komme i gang, må du opprette en ny Android-prosjekt med Android 4.0 som minstekravet SDK nivå. Dette prosjektet skal kun inneholde en blank aktivitet kalt MainActivity. Aktiviteten gjør ingenting mer enn initialisering oppsettet som du kan se i følgende kodebiten
public class MainActivity strekker Aktivitet {Override beskyttet void onCreate (Bundle savedInstanceState) {super.onCreate (savedInstanceState.); setContentView (R.layout.activity_main); }}

Oppsettet for MainActivity ligger i /res/layout/activity_main.xml filen og det skal bare bare inneholde en tom RelativeLayout hvor forbindelsen visningen vil bli vist senere
< RelativeLayout xmlns:. android = "http://schemas.android.com/apk/res/android~~number=plural" xmlns: verktøy = "http://schemas.android.com/tools~~number=plural" Android: layout_width = "match_parent" android: layout_height = "match_parent" verktøy : kontekst = "MainActivity." > < /RelativeLayout >
3. Opprett en forbindelse Vis

For å lage et sammensatt syn, må du opprette en ny klasse som forvalter utsikten i forbindelse visning. For siden spinner, trenger du to knapper visninger for pilene og en TextView sikte på å vise den valgte verdien.

For å komme i gang, lage /res/layout/sidespinner_view.xml layout fil som vi bruker for side spinner klasse, og husk å pakke inn de tre visningene i en < flette > . tag
< fusjonere xmlns: android = "http://schemas.android.com/apk/res/android" > < Button android: id = "+ id /sidespinner_view_previous" android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: layout_toLeftOf = "+ id /sidespinner_view_value" /> < TextView android: id = "+ id /sidespinner_view_current_value" android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: Tekststørrelse = "24sp" /> < Button android: id = "+ id /sidespinner_view_next" android: layout_width = "wrap_content" android: layout_height = "wrap_content" /> < /fusjonere >

Deretter må vi lage SideSpinner klasse som utløses dette oppsettet og setter pilene som bakgrunnsbilder for knappene. . På dette punktet, betyr det sammensatte syn ikke gjøre noe siden det er ingenting å vise ennå public class SideSpinner strekker LinearLayout {private Button mPreviousButton; private Button mNextButton; offentlig SideSpinner (Context kontekst) {super (sammenheng); initializeViews (sammenheng); } Public SideSpinner (Context kontekst, AttributeSet attrs) {super (kontekst, attrs); initializeViews (sammenheng); } Offentlig SideSpinner (Context kontekst, AttributeSet attrs, int defStyle) {super (kontekst, attrs, defStyle); initializeViews (sammenheng); } /** * Blåses visningene i oppsettet. * *param Sammenheng * dagens kontekst for visningen. * /Private void initializeViews (Context kontekst) {LayoutInflater inflater = (LayoutInflater) sammenheng .getSystemService (Context.LAYOUT_INFLATER_SERVICE); inflater.inflate (R.layout.sidespinner_view, dette); }Override Beskyttet void onFinishInflate () {super.onFinishInflate (); //Setter bildene for forrige og neste knapper. Bruker //innebygde bilder, slik at du ikke trenger å legge til bilder, men i //en reell søknad bildene dine skal være i //programpakke, slik at de alltid er tilgjengelige. mPreviousButton = (Button) dette .findViewById (R.id.sidespinner_view_previous); mPreviousButton .setBackgroundResource (android.R.drawable.ic_media_previous); mNextButton = (Button) dette .findViewById (R.id.sidespinner_view_next); mNextButton .setBackgroundResource (android.R.drawable.ic_media_next); }}

Du vil merke at det sammensatte visningen utvider LinearLayout visning gruppen. Dette betyr at enhver layout ved anvendelse av forbindelsen visningen har tilgang til attributtene til lineær layout. Som et resultat av oppsettet for forbindelsen utsikten er litt annerledes enn vanlig, er roten tag en < flette > tag stedet for tag for en visning gruppe som < LinearLayout > eller < RelativeLayout >.

Når du legger det sammensatte tanke på utformingen av MainActivity vil signal for den sammensatte syn fungere som en < LinearLayout > tag. En forbindelse vis klasse kan være avledet fra en hvilken som helst klasse avledet fra ViewGroup, men i dette tilfelle den lineære oppsettet er det mest hensiktsmessige siden visningene er lagt ut horisontalt.

4. Tilsett Compound View to a Layout

På dette punktet, kompilerer prosjektet, men ingenting er synlig siden det sammensatte syn ikke er i utformingen av MainActivity. Den siden spinner syn må legges til utformingen av aktiviteten som alle andre vis. Navnet på koden er den fulle navn SideSpinner klassen, inkludert navnerommet.

Hvis du vil legge til side spinner til MainActivity, legge til følgende til den relative layout i /res/layout/activity_main.xml fil .
< com.cindypotvin.sidespinnerexample.SideSpinner android: id = "+ id /sidespinner_fruits" android: layout_width = "match_parent" android: layout_height = "wrap_content" android: orientering = "horisontal" android: vekt = " center "/>

De attributtene som er tilgjengelige i < SideSpinner > tag er attributter av den lineære layout siden SideSpinner klassen vi skapt forlenger LinearLayout klassen. Hvis du starter prosjektet, bør den siden spinner være synlig, men det inneholder ingen verdier ennå.

5. Legg Metoder til Compound Vis

Det er fortsatt et par ting mangler hvis vi ønsker å faktisk bruke den siden spinner. Vi bør være i stand til å legge til nye verdier til den spinner, velge en verdi, og få den valgte verdien.

Den enkleste måten å legge til ny atferd til en forbindelse syn er å legge til nye offentlige metoder til SideSpinner klassen. Disse metodene kan brukes av enhver aktivitet som har en referanse til visningen
private CharSequence [] mSpinnerValues ​​= null;. Private int mSelectedIndex = 1; /** * Setter listen over verdien i spinner, velge det første verdi * som standard. * *param Verdier * verdiene som ligger i den spinner. * /public void setValues ​​(CharSequence [] verdier) {mSpinnerValues ​​= verdier; //Velg det første elementet av streng rekke som standard siden //listen over verdien har endret seg. setSelectedIndex (0);} /** * Setter valgt indeks over spinner. * *param Index * indeksen til verdi å velge. * /public void setSelectedIndex (int indeks) {//Hvis ingen verdier er satt for den spinner, gjør ingenting. if (mSpinnerValues ​​== null || mSpinnerValues.length == 0) return; //Hvis indeksverdien er ugyldig, gjør ingenting. if (indeks < 0 || index > = mSpinnerValues.length) tilbake; //Sett den gjeldende indeksen og vise verdien. mSelectedIndex = index; TextView Current; Current = (TextView) dette .findViewById (R.id.sidespinner_view_current_value); currentValue.setText (mSpinnerValues ​​[index]); //Hvis den første verdien vises, skjule den forrige knappen. if (mSelectedIndex == 0) mPreviousButton.setVisibility (usynlig); annet mPreviousButton.setVisibility (SYNLIG); //Hvis den siste verdien vises, skjule neste knapp. if (mSelectedIndex == mSpinnerValues.length - 1) mNextButton.setVisibility (usynlig); annet mNextButton.setVisibility (synlig);} /** * Blir den valgte verdien av spinner, eller null hvis ingen gyldig * valgte indeksen er satt ennå. * *return Den valgte verdien for spinneanordningen. * /public CharSequence getSelectedValue () {//Hvis ingen verdier er satt for den spinner, returnerer en tom streng. if (mSpinnerValues ​​== null || mSpinnerValues.length == 0) return ""; //Hvis den gjeldende indeksen er ugyldig, returnerer en tom streng. if (mSelectedIndex < 0 || mSelectedIndex > = mSpinnerValues.length) return ""; returnere mSpinnerValues ​​[mSelectedIndex];} /** * Blir den valgte indeksen i spinner. * *return Valgt indeksen for spinneanordningen. * /public int getSelectedIndex () {return mSelectedIndex;}

onFinishInflate metoden i forbindelse visningen kalles når alle visninger i oppsettet blåses opp og klar til bruk. Dette er stedet å legge koden din hvis du trenger å endre visningene i forbindelse visningen.

Med de metoder du nettopp har lagt til SideSpinner klassen, atferd for knappene velge forrige og neste verdi kan nå legges . Erstatte den eksisterende koden i onFinishInflate metoden med følgende:
Overrideprotected void onFinishInflate () {//Når kontrollene i oppsettet gjør blir oppblåst, satt //de callbacks for side piler. super.onFinishInflate (); //Når den forrige knappen, velg den forrige verdien //i listen. mPreviousButton = (Button) dette .findViewById (R.id.sidespinner_view_previous); mPreviousButton .setBackgroundResource (android.R.drawable.ic_media_previous); mPreviousButton.setOnClickListener (ny OnClickListener () {public void onClick (Vis visning) {if (mSelectedIndex > 0) {int newSelectedIndex = mSelectedIndex - 1; setSelectedIndex (newSelectedIndex);}}}); //Når neste knappen, velge neste element i //listen. mNextButton = (Button) dette .findViewById (R.id.sidespinner_view_next); mNextButton .setBackgroundResource (android.R.drawable.ic_media_next); mNextButton.setOnClickListener (ny OnClickListener () {public void onClick (Vis visning) {if (mSpinnerValues ​​= null & & mSelectedIndex < mSpinnerValues.length - 1) {int newSelectedIndex = mSelectedIndex + 1;! setSelectedIndex (newSelectedIndex);} }}); //Velg den første verdien som standard. setSelectedIndex (0);}

Med de nyopprettede setValues ​​og setSelectedIndex metoder, kan vi nå initial siden spinner fra vår kode. Som med alle andre visning, må du finne den siden spinner visningen i layout med findViewById metoden. Vi kan da ringe noen offentlig metode på utsikten fra objektet tilbake, inkludert de som vi nettopp opprettet.

Følgende kodebit viser hvordan du oppdaterer onCreate metoden i MainActivity klassen for å vise en liste med verdier i sidespinneren, ved hjelp av setValues ​​metoden. Vi kan også velge andre verdien i listen som standard ved å påberope seg setSelectedIndex metoden
public class MainActivity strekker Aktivitet {Override beskyttet void onCreate (Bundle savedInstanceState) {super.onCreate (savedInstanceState.); setContentView (R.layout.activity_main); //Starter side spinner fra kode. SideSpinner fruitsSpinner; fruitsSpinner = (SideSpinner) dette .findViewById (R.id.sidespinner_fruits); CharSequence fruitList [] = {"Apple", "Orange", "Pear", "Grapes"}; fruitsSpinner.setValues ​​(fruitList); fruitsSpinner.setSelectedIndex (1); }}

Hvis du starter programmet siden spinner skal fungere som forventet. Listen over verdier vises og verdien Orange er valgt som standard.

6. Legg Layout attributter til Compound Vis

Utsikten tilgjengelig i Android SDK kan endres gjennom koden, men noen attributter kan også settes direkte i tilsvarende layout. La oss legge til et attributt til siden spinner som setter verdiene siden spinner trenger å vise.

Hvis du vil lage en egendefinert attributt for det sammensatte syn, må vi først definere attributtet i /res /verdier /attr XML-fil. Hver egenskap av det sammensatte syn bør grupperes i en styleable med en < erklære-styleable > tag. For siden spinner, er navnet på klassen brukes som vist nedenfor
. ≪ resources > < erklære-styleable name = "SideSpinner" > < attr name = "verdier" format = "referanse" /> < /erklære-styleable > < /ressurser >

I < attr > tag, inneholder navnet attributtet identifikatoren brukes for å referere til den nye attributtet i oppsettet og formatet attributt inneholder den typen det nye attributtet.

For en liste av verdier, er referansetypen brukt siden attributten vil referere til en liste over strenger som er definert som en ressurs. De verdityper som vanligvis brukes i oppsett kan brukes til egendefinerte attributter, inkludert boolean, farge, dimensjon, enum, heltall, float og streng.

Her er hvordan man skal definere en ressurs for et liste over strenger at verdiene egenskap av siden spinner vil referere til. Det må legges til /res/values/strings.xml filen som vist nedenfor
. ≪ resources > < string-matrise name = "vegetable_array" > < element > Cucumber < /element > < element > Potet < /element > < element > Tomato < /element > < element > Onion < /element > < element > Squash < /element > < /string-matrise > < /ressurser >

For å teste de nye verdiene attributt, opprette en side spinner visning i MainActivity oppsettet nedenfor den eksisterende side spinner. Attributtet må være prefiks med et navnerom lagt til RelativeLayout, for eksempel xmlns: sidespinner = "http://schemas.android.com/apk/res-auto". Dette er hva den endelige utformingen i /res/layout/activity_main.xml skal se ut
< RelativeLayout xmlns:. Android = "http://schemas.android.com/apk/res/android~~number=plural" xmlns: verktøy = "http://schemas.android.com/tools~~number=plural" xmlns: sidespinner = "http://schemas.android.com/apk/res-auto~~number=plural" Android: layout_width = "match_parent" Android: layout_height = "match_parent" verktøy: kontekst = "MainActivity." > < com.cindypotvin.sidespinnerexample.SideSpinner android: id = "+ id /sidespinner_fruits" android: layout_width = "match_parent" android: layout_height = "wrap_content" android: orientering = "horisontal" android: vekt = "center" /> < com.cindypotvin.sidespinnerexample.SideSpinner android: id = "+ id /sidespinner_vegetables" android: layout_width = "match_parent" android: layout_height = "wrap_content" android: orientering = "horisontal" android: vekt = "center" android: layout_below = "@ id /sidespinner_fruits" sidespinner: verdier = "@ matrise /vegetable_array" /> < /RelativeLayout >

Til slutt, SideSpinner klassen må endres for å lese verdiene attributtet. Verdien av hver egenskap av visningen er tilgjengelig i AttributeSet objekt som er gått inn som en parameter av utsikten konstruktør.

For å få verdien av egendefinerte verdier attributt, vi først ringe obtainStyledAttributes metoden i AttributeSet objekt med navnet på styleable inneholder attributtet. Dette returnerer en liste av attributter for at styleable som TypedArray objekt.

Vi kaller getter metoden i TypedArray objekt som har riktig type for attributtet du vil, passerer identifikatoren til attributt som et parameter . Følgende kode blokk viser hvordan du endrer konstruktøren av side spinner for å få en liste over verdier og sette dem i siden spinner
offentlig SideSpinner (Context kontekst) {super (sammenheng).; initializeViews (sammenheng);} public SideSpinner (Context kontekst, AttributeSet attrs) {super (kontekst, attrs); TypedArray typedArray; typedArray = kontekst .obtainStyledAttributes (attrs, R.styleable.SideSpinner); mSpinnerValues ​​= typedArray .getTextArray (R.styleable.SideSpinner_values); typedArray.recycle (); initializeViews (sammenheng);} public SideSpinner (Context kontekst, AttributeSet attrs, int defStyle) {super (kontekst, attrs, defStyle); TypedArray typedArray; typedArray = kontekst .obtainStyledAttributes (attrs, R.styleable.SideSpinner); mSpinnerValues ​​= typedArray .getTextArray (R.styleable.SideSpinner_values); typedArray.recycle (); initializeViews (sammenheng);}

Hvis du starter programmet, bør du se to side spinnere som fungerer uavhengig av hverandre

7.. Lagre og gjenopprette State

Det siste trinnet vi trenger for å fullføre er lagring og gjenoppretting av tilstanden i forbindelse visning. Når en aktivitet er ødelagt og gjenskapt, for eksempel når enheten roteres, verdiene av innfødte utsikt med en unik identifikator lagres automatisk og restaurert. Dette er foreløpig ikke tilfelle for den siden spinner.

Staten av visningene ikke reddes. Identifikatoren på visninger i SideSpinner klassen er ikke unikt siden det kan bli gjenbrukt mange ganger. Dette betyr at vi er ansvarlige for lagring og gjenoppretting av verdiene av visningene i forbindelse visning. Vi gjør dette ved å implementere onSaveInstanceState, onRestoreInstanceState, og dispatchSaveInstanceState metoder. Følgende kode blokk viser hvordan du gjør dette for siden spinner. Twitter /** * Identifier for staten å lagre den valgte indeksen for * siden spinner. * /private static String STATE_SELECTED_INDEX = "SelectedIndex"; /** * Identifier for tilstanden i super klassen. * /private static String STATE_SUPER_CLASS = "superklassen"; @ Overrideprotected Parcelable onSaveInstanceState () {Bundle bunt = new Bundle (); bundle.putParcelable (STATE_SUPER_CLASS, super.onSaveInstanceState ()); bundle.putInt (STATE_SELECTED_INDEX, mSelectedIndex); returnere bunt;} @ Overrideprotected void onRestoreInstanceState (Parcelable tilstand) {if (state instanceof Bundle) {Bundle pakke = (Bundle) state; super.onRestoreInstanceState (bundle .getParcelable (STATE_SUPER_CLASS)); setSelectedIndex (bundle.getInt (STATE_SELECTED_INDEX)); } Else super.onRestoreInstanceState (stat); }Overrideprotected Void dispatchSaveInstanceState (SparseArray < Parcelable > beholder) {//gjør at staten av visningene barnet i side //spinner ikke lagres siden vi håndtere staten i //onSaveInstanceState. super.dispatchFreezeSelfOnly (container);} @ Overrideprotected void dispatchRestoreInstanceState (SparseArray < Parcelable > beholder) {//gjør at staten av visningene barnet i side //spinner ikke er gjenopprettet siden vi håndtere staten i //onSaveInstanceState . super.dispatchThawSelfOnly (container);}
Konklusjon

Den siden spinner er nå fullført. Begge side spinnere fungerer som forventet, og deres verdier er gjenopprettet dersom aktiviteten er ødelagt og gjenskapes. Nå kan du bruke det du har lært å bruke hvilken som helst gruppe av synspunkter i en Android-applikasjon ved hjelp utsikt sammensatte.



Previous:
Next Page: