Noul Fragment API pentru Android, introdus în versiunea Android 3.0, permite interfețe mai simple dinamice ale utilizatorilor. În acest tutorial, învățați cum să convertiți un flux de lucru ListView în WebView cu două ecrane într-un flux de lucru cu un singur ecran proiectat pentru ecrane mari, cum ar fi cele găsite pe tablete.
Anumite aspecte ale aplicațiilor sau tehnicilor utilizate în acest tutorial s-au schimbat de când au fost publicate inițial. Acest lucru ar putea face un pic dificil de urmat de-a lungul. Vă recomandăm să consultați aceste tutoriale mai recente pe același subiect:
Pacing-ul acestui tutorial va fi mai rapid decat unele dintre tutorialele noastre de incepatori; este posibil să fiți nevoit să revedeți câteva dintre celelalte tutoriale Android de pe acest site sau chiar în referința Android SDK dacă nu sunteți familiarizați cu oricare dintre conceptele și clasele de bază Android discutate în acest tutorial. Ultimul cod eșantion care însoțește acest tutorial este disponibil pentru descărcare ca sursă open-source de la găzduirea codului Google.
Înainte de a începe, să definim ceea ce este un fragment, la un nivel ridicat. Un fragment este, în general, o bucată de interfață cu propriul ciclu de viață. Dacă sună foarte mult o activitate, asta e pentru că este mult ca o Activitate. Cu toate acestea, un fragment este diferit de o activitate, prin faptul că un fragment trebuie să existe în cadrul unei activități. Un fragment nu trebuie să fie asociat cu aceeași activitate de fiecare dată când este instanțiat, ceea ce îi conferă o anumită flexibilitate. De asemenea, ca o Activitate, un Fragment nu trebuie să conțină nici o interfață de utilizator.
Acest tutorial presupune că veți începe în cazul în care tutorialul nostru ListView a rămas. Puteți descărca acel cod și construi de acolo, deși veți avea unele sarcini pe care trebuie să le faceți fără asistență sau puteți descărca codul pentru acest tutorial și urmați-l.
Următoarea figură ilustrează fluxul de lucru existent al aplicației noastre pentru cititoare de articole Mobiletuts + (tutorialul ListView) înainte ca un proiect Fragment să fie luat în considerare și aplicat:
Acest flux de lucru funcționează bine pe un ecran relativ mic de telefon. Cu toate acestea, pe un ecran mare, cum ar fi ecranul de 10 "al Motorola Xoom, și pe ecranul ListView există mult spațiu pierdut. Ecranul WebView arată bine, dacă este puțin plictisitor.
Aici găsim Fragmente: pe ecrane mai mari am putea oferi o interfață de utilizator mai eficientă dacă am putea afișa ListView pe același ecran ca WebView. Când utilizatorul face clic pe un element ListView specific în panoul din stânga ?, WebView din partea dreaptă actualizează pentru a afișa conținutul corespunzător. Acest tip de flux de lucru este frecvent utilizat în cititoarele de e-mail sau de feed-uri de documente. Figura următoare ilustrează doar o astfel de reproiectare:
Acum, când știm cum va fi proiectat noul flux de lucru al ecranului, știm de asemenea că cele două activități curente vor trebui convertite în fragmente. Vom face conversia în mai mulți pași. Primul pas presupune părăsirea ecranelor vizibil neschimbate, dar modificarea fiecărui ecran pentru a utiliza un fragment. Un fragment va conține lista curentă ListView, iar alta va conține WebView. Apoi, vom trece la o implementare a unui singur ecran, care implică modificarea mesageriei între activitățile ListView și WebView-fragmente transformate.
Mai întâi, totuși, schimbați obiectivul pentru construirea proiectului pentru aplicația dvs. Android 3.0. Pentru a face acest lucru din Eclipse, dați clic dreapta pe proiect și alegeți Proprietăți. Navigați la secțiunea Android și bifați caseta de selectare de lângă Android 3.0. Nu folosim niciun API Google, astfel încât versiunea Android Open Source Project este suficientă. Apoi faceți clic pe butonul OK.
Acum veți avea acces la noile API-uri, inclusiv API-ul Fragmente.
Notă: într-un tutorial viitor, vom vorbi despre utilizarea noului strat de compatibilitate pentru a permite tehnologiilor precum Fragment API să lucreze pe versiuni anterioare de Android. Pentru moment, însă, vor necesita un dispozitiv cu Android 3.0, Honeycomb.
Creați două noi clase Java pentru a reprezenta cele două fragmente: ecranele ListView și WebView. Denumiți-le TutListFragment și TutViewerFragment. TutListFragment va extinde clasa ListFragment iar TutViewerFragment va extinde clasa Fragment.
În cadrul clasei TutListFragment, trebuie să suprascrieți două metode: onListItemClick () și onCreate (). Conținutul acestor metode ar trebui să pară familiar; se potrivesc cu ceea ce am avut anterior în clasa TutListActivity. Acest lucru se va schimba în curând, dar nu încă. Iată o listă a clasei TutListFragment, deocamdată:
@Override public void onListItemClick (ListView l, Vizualizare v, poziție int, id lung) String [] links = getResources () getStringArray (R.array.tut_links); Conținut șir = link-uri [poziție]; Intent showContent = Intenție nouă (getApplicationContext (), TutViewerActivity.class); showContent.setData (Uri.parse (conținut)); startActivity (showContent); @Override publice void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setListAdapter (ArrayAdapter.createFromResource (getActivity () .getApplicationContext (), R.array.tut_titles, R.layout.list_item));
Clasa TutViewerFragment este puțin mai simplă. Folosim faptul că știm (deocamdată) că fragmentul rulează sub aceeași activitate pe care o obișnuia și să apucă datele de intenție direct din cadrul clasei Fragment. Adăugați o metodă de suprascriere pentru metoda onCreateView (). Aceste metode ar trebui să pară acum:
@Override publică Vizualizare onCreateView (LayoutInflater inflater, Container ViewGroup, Bundle savedInstanceState) Intent launchingIntent = getActivity () getIntent (); String content = lansareaIntent.getData (). ToString (); Vizualizatorul WebView = (WebView) inflater.inflate (R.layout.tut_view, container, false); viewer.loadUrl (conținut); retur;
Abilitatea de a accesa direct instanța de activitate este utilă, dar va crea o problemă mai târziu. Ce se întâmplă dacă acest fragment este pe ecran cu fragmentul de listă? În acest scenariu, nu va fi lansat intenția de a obține adresa URL. În mod similar, în TutListFragment, lansăm o nouă activitate direct ori de câte ori utilizatorul face clic pe un element din listă. Ce se întâmplă dacă TutViewFragment exista în cadrul aceleiași activități? Dacă da, lansarea unei noi activități nu are niciun sens. Vom reveni pentru a rezolva aceste probleme mai târziu în acest tutorial.
Acum creați un nou fișier de aspect denumit tutlist_fragment.xml pentru a reprezenta Fragmentul care conține lista articolelor. O resursă de aspect al fragmentei utilizează eticheta și trimite la clasa Fragment creată.
Apoi, creați un fișier de aspect similar numit tutview_fragment.xml:
Clasele TutListActivity și TutViewerActivity trebuie acum actualizate. Clasa TutListActivity are o singură metodă, onCreate (), care ar trebui acum actualizată pentru a încărca resursele adecvate pentru aspectul de fragmente pe care le-ați creat în etapa anterioară, cum ar fi:
@Override publice void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.tutlist_fragment);
De asemenea, trebuie remarcat faptul că TutListActivity ar trebui să moștenească din clasa Activity, nu ListActivity.
Clasa TutViewerActivity necesită o schimbare similară. Metoda sa onCreate () ar trebui să arate astfel:
@Override publice void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.tutview_fragment);
Încearcă să rulați aplicația acum. Veți observa că face exact ceea ce făcea. Nu este încă foarte interesant, nu-i așa? Cu toate acestea, întreaga interfață de utilizator este rulată acum folosind fragmente. Acest lucru va permite următoarele modificări pe care trebuie să le faceți pentru a merge fără probleme, adăugând un nou aspect pentru a combina cele două fragmente pentru afișajele mai mari, pentru a le afișa utilizatorului pe un singur ecran. Cu toate acestea, după cum probabil ați observat, comunicarea dintre fragmente este tratată identic cu modul în care comunicăm între activități. De fapt, am folosit cunoașterea că activitatea pe care fiecare fragment a fost asociată a rămas neschimbată. Acest lucru nu va fi cazul atunci când avem o singură activitate care conține și gestionează ambele fragmente. Să rezolvăm mai întâi asta.
După cum ați aflat în pasul 3, lansarea unei activități direct din obiectul TutListFragment nu mai are sens. Interfața WebView poate, de fapt, face parte din aceeași activitate ca și Lista - acesta este planul nostru oricum pentru ecrane mai mari. În acest caz, dorim doar să actualizăm adresa URL a WebView în al doilea fragment.
Pentru a face această schimbare, trebuie să facem mai multe lucruri. Mai întâi, să facem fragmentele independente de activitatea în care locuiesc. Pentru a face acest lucru, adăugați o interfață de ascultător la clasa TutListFragment, ca atare:
interfața publică OnTutSelectedListener public void onTutSelected (Uri tutUri);
Apoi activați-o actualizând metoda onListItemClickListener () după cum urmează:
@Override public void onListItemClick (ListView l, Vizualizare v, poziție int, id lung) String [] links = getResources () getStringArray (R.array.tut_links); Conținut șir = link-uri [poziție]; tutSelectedListener.onTutSelected (Uri.parse (conținut));
Apoi, au clasa TutListActivity să implementeze interfața OnTutSelectedListener, după cum urmează:
clasa publică TutListActivity se extinde Activitatea implementează TutListFragment.OnTutSelectedListener ? @Override publice void onTutSelected (Uri tutUri) Intent showContent = Intenție nouă (getApplicationContext (), TutViewerActivity.class); showContent.setData (tutUri); startActivity (showContent);
Deci, acum avem funcționalitatea împărțită între fragmentul care gestionează acțiunile interfeței utilizator și activitatea care poate fi un controler, transmiterea datelor către următoarea activitate. Vom modifica mai târziu metoda onTutSelected () pentru a decide dacă să lansăm sau nu o nouă instanță de activitate sau să actualizăm instanța fragmentului existent.
Acum, să ne îndreptăm atenția asupra clasei TutViewerFragment, care trebuie actualizată, de asemenea. În loc să interogați intenția de lansare pentru a afla ce adresă URL să se încarce, fragmentul va aștepta să se spună ce adresa URL să se încarce. În acest fel, putem actualiza direct WebView și nu putem recrea fragmentul cu fiecare încărcare.
Mai întâi, modificați clasa TutViewerFragment pentru a conține o nouă metodă numită updateUrl ():
public void updateUrl (String newUrl) dacă (viewer! = null) viewer.loadUrl (newUrl);
Apoi, eliminați toate funcționalitățile din metoda onCreateView (), cu excepția apelului inflat (). Peste în clasa TutViewerActivity, adăugați funcționalitatea înapoi pentru a prelua intenția și apoi apelați metoda updateUrl (), după cum urmează:
@Override publice void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.tutview_fragment); Intenția de lansareIntent = getIntent (); String content = lansareaIntent.getData (). ToString (); Vizualizarea TutViewerFragment = (TutViewerFragment) getFragmentManager () .findFragmentById (R.id.tutview_fragment); viewer.updateUrl (conținut);
În acest moment, comportamentul aplicației rămâne neschimbat. Fragmentele, totuși, pot exista acum în cadrul aceleiași activități sau separate, fără alte modificări de cod.
Acum, să creăm un aspect cu ambele fragmente, pentru a fi utilizat în anumite situații. În folderul layout-land (care ar putea fi necesar să creați), adăugați o copie a tutlist_fragment.xml. Acest lucru va provoca un aspect diferit pentru orientarea peisajului pe orice ecran de peisaj. Modul portret va rămâne neschimbat. Editați fișierul pentru a arăta ca aspectul următor cu ambele fragmente:
Aceasta va împărți ecranul orizontal între ambele fragmente.
Acum putem adăuga o anumită logică simplă aplicației pentru a alege între lansarea unei noi activități (fluxul de lucru al celor două ecrane) și actualizarea unui fragment existent (fluxul de lucru al unui singur ecran).
Pentru aceasta, actualizați metoda onTutSelected () din clasa TutListActivity după cum urmează:
@Override publice void onTutSelected (String tutUrl) TutViewerFragment viewer = (TutViewerFragment) getFragmentManager () .findFragmentById (R.id.tutview_fragment); dacă (viewer == null ||! viewer.isInLayout ()) Intent showContent = Intenție nouă (getApplicationContext (), TutViewerActivity.class); showContent.setData (Uri.parse (tutUrl)); startActivity (showContent); altceva viewer.updateUrl (tutUrl);
Toate acestea fac este să luați fragmentul și să verificați dacă acesta face parte din planul existent al Activității. Dacă nu, activitatea de vizualizare este lansată, altfel fragmentul existent este actualizat în schimb.
În acest moment, aplicația va funcționa acum în două moduri diferite: portretul este neschimbat, în timp ce peisajul afișează ListView la stânga WebView. Există câteva îmbunătățiri care ar putea fi făcute în acest moment, dar ele sunt de optimizare, de optimizare, și de nișă picking varietate și mai ales pentru poloneză. De exemplu, dacă sunteți în modul portret WebView și rotiți ecranul, rezultatul este totuși doar ecranul WebView. Trebuie să apăsați din nou pentru a ajunge la vederea duală. Lustruirea este dincolo de scopul acestui tutorial, dar puteți vedea cum, cu utilizarea judicioasă a layout-urilor și o mică logică a activității, puteți realiza fluxuri de lucru puternice, dar flexibile, pentru o varietate de ecrane și dispozitive.
API-ul Fragment contribuie la organizarea componentelor interfeței utilizator, astfel încât acestea să poată fi reutilizate în cadrul activităților. În acest fel, o aplicație își poate ajusta dinamic fluxurile de lucru și interfețele utilizator cu cheltuieli de codare relativ reduse. De asemenea, ați văzut că o aplicație care se bazează pe fragmente este mai ușor de reorganizat. Chiar mai bine, aproape orice aplicație poate pârghii fragmente acum că acestea sunt disponibile printr-o bibliotecă de compatibilitate oferită de Google care este compatibilă încă de la Android 1.6.
Acum, ieșiți și fragmentați interfața de utilizare a aplicațiilor și creați interfețe minunate de utilizator pentru fiecare dimensiune și formă a ecranului!
Dezvoltatorii mobili Lauren Darcey și Shane Conder au coautorizat mai multe cărți despre dezvoltarea Android: o carte de programare în profunzime intitulată Dezvoltarea aplicațiilor fără fir Android și Sams Învățați-vă dezvoltarea de aplicații Android în 24 de ore. Când nu scriu, își petrec timpul dezvoltând software-ul mobil la compania lor și oferind servicii de consultanță. Acestea pot fi obținute prin e-mail la androidwirelessdev@[email protected], prin intermediul blogului lor la androidbook.blogspot.com, și pe Twitter @ androidwireless.
я я