Android brukergrensesnittdesign Arbeide med fragmenter

Den nye Fragment API for Android, introdusert i Android 3.0, muliggjør enklere dynamiske brukergrensesnitt. I denne veiledningen lærer du hvordan du konverterer en to-skjerm ListView til WebView-arbeidsflyten i en enkelt arbeidsflyt for en skjerm designet for store skjermer, som for eksempel de som finnes på nettbrett.

Senere endringer i teknikker og programvare

Visse aspekter av applikasjoner eller teknikker som brukes i denne opplæringen, har endret seg siden den ble opprinnelig publisert. Dette kan gjøre det litt vanskelig å følge med. Vi anbefaler å se på disse nyere opplæringsprogrammene på samme emne:

  • Android SDK: Bruke fragmenter

Pacingen av denne opplæringen kommer til å bli raskere enn noen av våre nybegynneropplæringer; Du må kanskje gå gjennom noen av de andre Android-veiledningene på dette nettstedet eller i Android SDK-referansen hvis du ikke er kjent med noen av de grunnleggende Android-konseptene og klassene som er omtalt i denne opplæringen. Den endelige prøvekoden som følger med denne opplæringen, er tilgjengelig for nedlasting som åpen kildekode fra Google-koden hosting.

Vi presenterer fragmenter

Før vi begynner, la oss definere hva et fragment er på høyt nivå. Et fragment er vanligvis en del av brukergrensesnittet med sin egen livssyklus. Hvis det høres mye ut som en aktivitet, er det fordi det er mye som en aktivitet. En fragment er imidlertid forskjellig fra en aktivitet, idet et fragment må eksistere innenfor en aktivitet. Et fragment trenger ikke å være paret med samme aktivitet hver gang det er instantiated, noe som gir det litt fleksibilitet. Også som en aktivitet trenger et fragment ikke å inneholde noe brukergrensesnitt.

Trinn 0: Komme i gang

Denne opplæringen forutsetter at du starter hvor vår ListView-veiledning slått av. Du kan laste ned koden og bygge derfra, men du vil ha noen oppgaver du må gjøre uten hjelp, eller du kan laste ned koden for denne opplæringen og følge med.

Trinn 1: Omformere skjermene

Følgende figur illustrerer den eksisterende arbeidsflyten i vår Mobiletuts + -leser-app (ListView-opplæringen) før et Fragment-design ble vurdert og anvendt:

Denne arbeidsflyten fungerer fint på en relativt liten telefonskjerm. Men på en stor skjerm, som 10-tommers skjermen på Motorola Xoom, og det er mye bortkastet plass på ListView-skjermen. WebView-skjermen ser bra ut, hvis det er litt kjedelig.

Dette er hvor Fragments kommer til spill: på større skjermer kan vi gi et mer effektivt brukergrensesnitt hvis vi kunne vise ListView på samme skjerm som WebView. Når brukeren klikker et bestemt ListView-element i lefthand? -Panelet? Oppdateres WebView på høyre side for å vise riktig innhold. Denne typen arbeidsflyt brukes ofte i e-post- eller dokumentmateslesere. Følgende figur illustrerer bare et slikt redesign:

Trinn 2: Konvertering til et fragmentbasert design

Nå som vi vet hvordan den nye skjermens arbeidsflyt skal utformes, vet vi også at de to nåværende aktivitetene må konverteres til fragmenter. Vi gjør konverteringen i flere trinn. Det første trinnet innebærer å forlate skjermene visuelt uendret, men å endre hver skjerm for å bruke et fragment. Ett fragment vil inneholde gjeldende ListView og en annen vil inneholde WebView. Så bytter vi til en enkelt skjermimplementering, som innebærer å endre meldingene mellom listevisning og webvisningsaktiviteter-sviktfragmenter.

Først, men endre prosjektet Bygg mål for søknaden din til Android 3.0. For å gjøre dette fra Eclipse, høyreklikk på prosjektet og velg Egenskaper. Naviger til Android-delen, og merk av i avkrysningsruten ved siden av Android 3.0. Vi bruker ikke noen Google-APIer, så Android Open Source Project-versjonen er tilstrekkelig. Klikk deretter OK-knappen.

Nå har du tilgang til de nye APIene, inkludert Fragments API.

Merk: I en fremtidig veiledning snakker vi om bruk av det nye kompatibilitetslaget for å aktivere teknologier som Fragment API for å fungere på tidligere versjoner av Android. For nå, skjønt, vil de kreve en enhet med Android 3.0, Honeycomb.

Trinn 3: Opprette fragmenteringsklassene

Opprett to nye Java-klasser for å representere de to fragmentene: ListView og WebView-skjermbildene. Gi dem navn TutListFragment og TutViewerFragment. TutListFragment vil utvide ListFragment-klassen og TutViewerFragment vil bare forlenge Fragment-klassen.

Innenfor klassen TutListFragment må vi overstyre to metoder: onListItemClick () og onCreate (). Innholdet i disse metodene skal se kjent ut; de samsvarer med det vi tidligere hadde i klassen TutListActivity. Dette vil endres kort, men ikke bare ennå. Her er en liste over klassen TutListFragment, for nå:

 @Override public void onListItemClick (Listevisning l, Vis v, int posisjon, lang id) String [] links = getResources (). GetStringArray (R.array.tut_links); Stringinnhold = lenker [posisjon]; Intent showContent = new Intent (getActivity (). GetApplicationContext (), TutViewerActivity.class); showContent.setData (Uri.parse (innhold)); startActivity (showContent);  @Override public void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setListAdapter (ArrayAdapter.createFromResource (getActivity () .getApplicationContext (), R.array.tut_titles, R.layout.list_item)); 

Klassen TutViewerFragment er litt enklere. Vi bruker det faktum at vi kjenner (for nå) at fragmentet kjører under samme aktivitet som det pleide å, og ta tak i hensiktsdataene direkte fra Fragment-klassen. Legg til en overstyringsmetode for metoden onCreateView (). Denne metoden bør nå se slik ut:

 @Override public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) Intent launchingIntent = getActivity (). GetIntent (); String content = launchingIntent.getData (). ToString (); WebView viewer = (WebView) inflater.inflate (R.layout.tut_view, container, false); viewer.loadUrl (innhold); returnere seer; 

Muligheten til å få tilgang til aktivitetseksemplet direkte, er nyttig, men vil senere opprette et problem. Hva om dette fragmentet er på skjermen med listefragmentet? I det scenariet vil det ikke bli introdusert Intent for å få nettadressen fra. På samme måte, i TutListFragment, lanserer vi en ny aktivitet direkte når brukeren klikker et element i listen. Hva om TutViewFragment eksisterte innenfor samme aktivitet? Hvis det er tilfelle, vil det ikke være fornuftig å starte en ny aktivitet. Vi kommer tilbake for å løse disse problemene senere i denne opplæringen.

Trinn 4: Legge til Fragment Layout Resources

Opprett nå en ny layoutfil kalt tutlist_fragment.xml for å representere fragmentet som inneholder listen over artikler. En Fragment layout ressurs bruker taggen og refererer til Fragment klassen du opprettet.

   

Deretter oppretter du en lignende layoutfil kalt tutview_fragment.xml:

   

Trinn 5: Oppdatere aktivitetsklassene

TutListActivity og TutViewerActivity-klassene må nå oppdateres. Klassen TutListActivity har en enkelt metode, onCreate (), som nå skal oppdateres for å laste den aktuelle Fragment Layout-ressursen du opprettet i forrige trinn, slik:

 @Override public void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.tutlist_fragment); 

I tillegg bør TutListActivity arve fra Aktivitetsklassen, ikke ListActivity.

Klassen TutViewerActivity krever en lignende endring. Metoden onCreate () skal nå se slik ut:

 @Override public void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.tutview_fragment); 

Trinn 6: Kontroller fremdriften din

Prøv å kjøre programmet nå. Du vil merke at det gjør akkurat hva det pleide å gjøre. Ikke veldig spennende ennå, er det? Men hele brukergrensesnittet blir nå kjørt ved hjelp av fragmenter. Dette vil tillate de neste endringene du trenger å gjøre for å gå greit når vi legger til et nytt layout for å kombinere de to fragmentene for større skjermer for å vise til brukeren på en enkelt skjerm. Som du kanskje har lagt merke til, håndteres kommunikasjonen mellom fragmenter identisk med hvordan vi kommuniserer mellom aktiviteter. Faktisk brukte vi kunnskapen om at aktiviteten hvert fragment var parret, forblev uendret. Dette vil ikke være tilfelle når vi har en enkelt aktivitet som inneholder og styrer begge fragmentene. La oss fikse dette først.

Trinn 7: Endre kommunikasjonen for TutListFragment

Som du har lært i trinn 3, er det ikke lurt å starte en aktivitet direkte fra objektet TutListFragment lenger. WebView brukergrensesnittet kan faktisk være en del av samme aktivitet som listen - det er vår plan uansett for større skjermer. I så fall vil vi bare oppdatere nettleseren til WebView i det andre fragmentet.

For å gjøre denne endringen må vi gjøre flere ting. La oss først lage fragmentene uavhengig av aktiviteten der de bor. For å gjøre dette, legg til et lyttergrensesnitt til klassen TutListFragment, som sådan:

 offentlig grensesnitt OnTutSelectedListener public void onTutSelected (Uri tutUri); 

Og utløs det ved å oppdatere onListItemClickListener () -metoden som følger:

 @Override public void onListItemClick (Listevisning l, Vis v, int posisjon, lang id) String [] links = getResources (). GetStringArray (R.array.tut_links); Stringinnhold = lenker [posisjon]; tutSelectedListener.onTutSelected (Uri.parse (innhold)); 

Deretter skal klassen TutListActivity implementere OnTutSelectedListener-grensesnittet slik:

 offentlig klasse TutListActivity utvider Aktivitetsverktøy TutListFragment.OnTutSelectedListener ? @Override public void onTutSelected (Uri tutUri) Intent showContent = new Intent (getApplicationContext (), TutViewerActivity.class); showContent.setData (tutUri); startActivity (showContent); 

Så nå har vi funksjonaliteten delt mellom fragmentet, som håndterer brukergrensesnitthandlingene, og aktiviteten, som kan være en kontroller, overfører data til neste aktivitet. Vi modifiserer onTutSelected () -metoden senere for å avgjøre om du vil starte en ny aktivitetseksempel eller oppdatere eksisterende fragmenteksempler.

Trinn 8: Endre kommunikasjonen for TutViewerFragment

La oss nå flytte oppmerksomheten til klassen TutViewerFragment, som også må oppdateres. I stedet for å spørre lanseringsintensjonen om å finne ut hvilken nettadresse som skal lastes, vil fragmentet vente å bli fortalt hvilken nettadresse som skal lastes. På denne måten kan vi oppdatere WebView direkte og ikke gjenskape fragmentet med hver last.

Først må du endre klassen TutViewerFragment for å inneholde en ny metode som heter updateUrl ():

 offentlig ugyldig oppdateringUrl (String newUrl) hvis (seer! = null) viewer.loadUrl (newUrl); 

Deretter fjerner du all funksjonalitet fra metoden onCreateView (), bortsett fra oppblåsingen (). Over i klassen TutViewerActivity legger du til funksjonaliteten tilbake for å hente Intent og deretter ringe oppdatoenUrvendig () -metoden, slik som:

 @Override public void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.tutview_fragment); Intent launchingIntent = getIntent (); String content = launchingIntent.getData (). ToString (); TutViewerFragment viewer = (TutViewerFragment) getFragmentManager () .findFragmentById (R.id.tutview_fragment); viewer.updateUrl (innhold); 

På dette tidspunktet forblir applikasjonsadferdensen uendret. Fragmentene kan imidlertid nå eksistere innenfor samme aktivitet eller separate dem uten ytterligere kodeendringer.

Trinn 9: Legge til en Dual Fragment Layout

La oss nå lage en layout med begge fragmentene, for bruk i visse situasjoner. Legg til en kopi av tutlist_fragment.xml i mappen Layout-land (som du kanskje må opprette). Dette vil vise seg å være et annet oppsett for landskapsretning på et hvilket som helst landskapsskjermbilde. Portrettmodus forblir uendret. Rediger filen slik at den ser ut som følgende layout med begge fragmentene:

       

Dette vil dele skjermen horisontalt mellom begge fragmentene.

Trinn 10: Legge til et dynamisk valg

Nå kan vi legge til litt enkel logikk i applikasjonen for å velge mellom å starte en ny aktivitet (de to arbeidsflytene på skjermen) og oppdatere et eksisterende fragment (den ene skjermens arbeidsflyt).

For å gjøre dette oppdaterer du metoden onTutSelected () i klassen TutListActivity som følger:

 @Override public void onTutSelected (String tutUrl) TutViewerFragment viewer = (TutViewerFragment) getFragmentManager () .findFragmentById (R.id.tutview_fragment); hvis (seer == null ||! viewer.isInLayout ()) Intent showContent = new Intent (getApplicationContext (), TutViewerActivity.class); showContent.setData (Uri.parse (tutUrl)); startActivity (showContent);  ellers viewer.updateUrl (tutUrl); 

Alt dette gjør er å gripe fragmentet og se om det er en del av det eksisterende oppsettet for aktiviteten. Hvis ikke, blir seeraktiviteten lansert, ellers blir det eksisterende fragmentet oppdatert i stedet.

Trinn 11: Kjører den nyeste versjonen av Fragment-Aware

På dette tidspunktet vil applikasjonen nå fungere i to forskjellige moduser: Stående er uendret, mens landskapet viser ListView til venstre for WebView. Det er flere forbedringer som kan gjøres på dette tidspunktet, men de er av tweaking, optimalisering og nit-picking variasjon og for det meste for polsk. For eksempel, hvis du er i portrett WebView-modus og roterer skjermen, er resultatet fortsatt bare WebView-skjermen. Du må trykke tilbake for å komme til dobbeltvisningen. Polering er utenfor omfanget av denne opplæringen, men du kan se hvordan med jødisk bruk av oppsett og litt aktivitetslogikk, kan du oppnå kraftige, men fleksible arbeidsflyt for en rekke skjermer og enheter.

Konklusjon

Fragment API hjelper deg med å organisere brukergrensesnittkomponenter slik at de kan gjenbrukes på tvers av aktiviteter. På denne måten kan en applikasjon dynamisk justere arbeidsflyten og brukergrensesnittene med relativt lite kodende overhead. Du har også sett at et program som bygger på fragmenter, er lettere å omorganisere. Enda bedre, omtrent alle applikasjoner kan utnytte fragmenter nå som de er tilgjengelige via et kompatibilitetsbibliotek levert av Google som er kompatibelt så langt bak som Android 1.6.
Nå går du ut og fragmenterer appgrensesnittet ditt og lager flotte brukergrensesnitt for hver skjermstørrelse og form!

Om forfatterne

Mobilutviklere Lauren Darcey og Shane Conder har medforfatter flere bøker om Android-utvikling: en grundig programmeringsbok med tittel Android Wireless Application Development og Sams Lær deg selv Android Application Development i 24 timer. Når de ikke skriver, bruker de sin tid på å utvikle mobil programvare hos deres firma og tilby konsulenttjenester. De kan nås via e-post til [email protected], via bloggen deres på androidbook.blogspot.com, og på Twitter @androidwireless.

Trenger du flere hjelpeskrivende Android-apper? Se våre nyeste bøker og ressurser!

я я