Vuosien varrella olen nähnyt erilaisia Android-navigointimallin toteutuksia. Jotkut sovellukset käyttivät vain toimintoja, kun taas toiset aktiviteetit sekoitettiin katkelmiin ja / tai mukautettuihin näkymiin ( Mukautetut näkymät ).
Yksi suosikkini fragmenttimallitoteutuksistani perustuu filosofiaan 'Yhden toiminnan moninkertaiset fragmentit' (' Yhden toiminnan moninkertaiset fragmentit Tai yksinkertaisesti fragmentin navigointikuvio ( Katkelma Navigointikuvio ), jossa kukin sovelluksen ruutu on koko näytön fragmentti ja kaikki tai suurin osa näistä fragmenteista ovat toiminnassa.
Tämä lähestymistapa paitsi yksinkertaistaa navigoinnin toteuttamista, myös parantaa suorituskykyä ja tarjoaa siten paremman käyttökokemuksen.
Tässä artikkelissa tutkitaan joitain yleisiä Android-navigointimallien toteutuksia ja esitellään sitten Snippet-pohjainen navigointimalli. Tämän mallin toteuttava esimerkkisovellus löytyy osoitteesta GitHub .
Tyypillinen Android-sovellus, joka käyttää vain toimintoja, on järjestetty Puu-tyyppiseen rakenteeseen (tarkalleen suunnattuun kaavioon), jossa päätoiminnan aloittaa kantoraketti . Kun selaat sovellusta, näytössä näkyy takapino ”Operaatiosta, jota ylläpidetään käyttöjärjestelmän ansiosta.
Yksinkertainen esimerkki on esitetty seuraavassa kaaviossa:
Aktiviteetti A1 on sovelluksemme lähtökohta (esimerkiksi se edustaa aloitusnäyttöä tai päävalikkoa) ja siitä lähtien käyttäjä voi siirtyä kohtaan A2 tai A3. Kun sinun täytyy kommunikoida toimintojen välillä, voit käyttää startActivityForResult () Tai voit jakaa globaalisti saavutettavan liiketoiminnan loogisen objektin molempien toimintojen välillä.
Kun sinun on lisättävä uusi toiminto, sinun on noudatettava seuraavia vaiheita:
Vaikka tämä navigointikaavio on melko yksinkertaistettu lähestymistapa; mutta se voi tulla hyvin monimutkaiseksi, kun tarvitset manipuloida takapino tai kun sinun on käytettävä samaa toimintoa uudelleen useita kertoja, esimerkiksi kun haluat käyttäjän siirtyvän eri opetusnäytöissä, mutta jokainen näyttö käyttää samaa toimintaa pohjana.
Onneksi meillä on työkaluja näihin tapauksiin askareita ja joitain a navigointi takapino sopiva .
Sitten fragmentit saapuivat API-tason 11 kanssa ...
Android esittelee katkelmia Android 3.0: ssa (API-taso 11) ensisijaisesti tukeakseen dynaamisempia ja joustavampia käyttöliittymäsovelluksia suurilla näytöillä, kuten tableteilla. Koska tablet-laitteen näyttö on paljon suurempi kuin puhelimen näyttö, käyttöliittymän komponenttien sekoittamiseen on enemmän tilaa. Katkelmat tukevat näitä asetteluja ilman, että sinun on hallittava monimutkaisia muutoksia näkymähierarkiaan. Jakamalla aktiviteetin asettelun paloiksi voit muokata toiminnan ulkonäköä ajon aikana ja pitää nämä muutokset aktiviteetin hallinnoimassa aktiviteettipinossa. - lainaus Google-oppaasta Fragmenttien sovellusliittymä .
Tämän uuden lelun avulla kehittäjät voivat luoda monipaneelisen käyttöliittymän ja pystyä käyttämään komponentteja uudelleen muissa toiminnoissa. Jotkut kehittäjät rakastavat tätä, kun taas toiset Ei niin paljoa . Katkelmien käyttäminen on suosittua keskustelua, mutta luulen kaikkien olevan samaa mieltä siitä, että katkelmat toivat lisää monimutkaisuutta ja kehittäjien on ymmärrettävä ne oikein voidakseen käyttää niitä.
Aloin nähdä yhä enemmän esimerkkejä, joissa fragmentit eivät vain edustaneet osaa näytöstä, vaan koko näyttö oli fragmentti toiminnassa. Oli aika, jolloin näin asettelun, jossa kaikilla toiminnoilla oli täsmälleen yksi koko näytön kokoinen katkelma eikä mitään muuta, ja ainoa syy, miksi nämä toiminnot olivat olemassa, oli katkelmien tallentaminen. Suunnitteluvirheiden lisäksi tässä lähestymistavassa on toinen ongelma. Katso seuraava kaavio:
Kuinka A1 voi kommunikoida F1: n kanssa? Tapaus on, että A1 hallitsee täysin F1: tä, koska se loi F1: n. A1 voi ohittaa paketin esimerkiksi F1: n luomisessa tai käyttää julkisia menetelmiä. Kuinka F1 voi kommunikoida A1: n kanssa? No, se on monimutkaisempaa, se voidaan ratkaista mallilla takaisinsoitto / tarkkailija missä A1 tilaa F1 ja F1 ilmoittaa A1: lle.
Mutta miten A1 ja A2 voivat kommunikoida? Kuten edellä selitettiin, he voisivat kommunikoida startActivityForResult () .
Ja nyt todellinen kysymys: Kuinka F1 ja F2 voivat kommunikoida? Jopa tässä tapauksessa meillä voi olla liiketoimintalogiikan komponentti, joka on maailmanlaajuisesti käytettävissä ja jota voidaan käyttää tietojen välittämiseen. Mutta tämä komponentti ei aina vastaa hienoa suunnittelua. Entä jos F2 tarvitsee välittää tietoja F1: lle suoremmin? Tällöin kuviolla soita takaisin F2 voi ilmoittaa A2: lle, sitten A2 pääsee tulokseen ja A1 voi tallentaa tuloksen, joka voi ilmoittaa F1: lle.
Tämä lähestymistapa vaatii paljon koodia kattilalevy ja siitä tulee nopeasti vikoja , kipua ja vihaa.
Entä jos voisimme päästä eroon kaikesta toiminnasta ja pitää vain yhden niistä, mikä säilyttää loput palaset?
Ajan myötä aloin käyttää 'One-Activity-Multiple-Fragments' -mallia useimmissa sovelluksissani ja käytän sitä edelleen. Siellä on paljon keskusteluja esimerkiksi tästä lähestymistavasta tai filosofiasta tässä Y tässä . Kaipasin vain erityisen esimerkin, jonka voin nähdä ja testata itse.
Katsotaanpa hetken seuraavaa kaaviota:
Nyt meillä on vain yksi konttioperaatio ja meillä on useita fragmentteja, jotka ovat jälleen Tree-tyyppisessä rakenteessa. Niiden välinen navigointi on FragmentManager , tällä on oma takapino .
Huomaat, että nyt meillä ei ole startActivityForResult () mutta voimme toteuttaa mallin takaisinsoitto / tarkkailija . Katsotaan nyt tämän lähestymistavan joitain etuja ja haittoja:
Nyt kun meillä on vain yksi toiminto, meidän ei enää tarvitse päivittää luetteloa joka kerta, kun lisätään uusi näyttö. Toisin kuin toiminnoissa, meidän ei tarvitse ilmoittaa palasia.
Tämä saattaa tuntua pieneltä, mutta suuremmille sovelluksille, joissa on yli 50 aktiviteettia, tämä voisi merkittävästi parantaa AndroidManifest.xml tiedosto.
Katso esimerkkisovelluksen luettelotiedostoa, jolla on useita näyttöjä. Luettelotiedosto pidetään erittäin yksinkertaisena.
package='com.exarlabs.android.fragmentnavigationdemo.ui' >
Esimerkkikoodissani huomaat, että käytän NavigationManager joka tapauksessani injektoidaan jokaiseen fragmenttiin. Tätä johtajaa voidaan käyttää keskitetysti puunkorjuu , hallinta takapino muun muassa siten, että selauskäyttäytyminen on irrotettu muusta liiketoimintalogiikasta eikä levitä eri näyttöjen toteutuksiin.
Kuvitellaan tilanne, jossa haluamme aloittaa näytön, jossa käyttäjä voi valita joitain kohteita ihmisluettelosta. Haluat myös välittää joitain suodatusperusteita, kuten ikä, ammatti ja sukupuoli.
Aktiviteettien tapauksessa kirjoitat:
Intent intent = new Intent(); intent.putExtra('age', 40); intent.putExtra('occupation', 'developer'); intent.putExtra('gender', 'female'); startActivityForResult(intent, 100);
Sitten sinun on määriteltävä onActivityResult jonnekin alas ja käsittele tulosta.
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); }
Henkilökohtainen ongelmani tässä lähestymistavassa on se, että nämä argumentit ovat 'ekstroja' eikä niitä vaadita, joten minun on varmistettava, että vastaanottava toiminta käsittelee erilaisia tapauksia, kun ylimääräinen puuttuu. Myöhemmin, kun korjaus tehdään ja kun ylimääräistä, esimerkiksi 'ikä', ei enää tarvita, minun on etsittävä läpi kaikki koodit, joista tämä toiminta on alkanut, ja varmistettava, että kaikki lisäosat ovat oikein.
Eikö olisikaan parempi, jos tulos (ihmisluettelo) saapuisi nimellä _List_ eikä sarjamuodossa, joka sitten on deserialisoitava?
Katkelmapohjaisen selaamisen tapauksessa kaikki on suoraviivaisempaa. Sinun tarvitsee vain kirjoittaa menetelmä NavigationManager nimeltään startPersonSelectorFragment () tarvittavat perustelut ja toteutus soita takaisin .
mNavigationManager.startPersonSelectorFragment(40, 'developer', 'female', new PersonSelectorFragment.OnPersonSelectedListener() { @Override public boolean onPersonsSelected(List selection) { [do something] return false; } });
Tai kanssa RetroLambda
mNavigationManager.startPersonSelectorFragment(40, 'developer', 'female', selection -> [do something]);
Toimintojen välillä voimme jakaa vain paketin, joka sisältää primitiivisiä tai sarjoitettuja tietoja. Nyt fragmenttien avulla voimme toteuttaa mallin soita takaisin missä esimerkiksi F1 voi kuunnella F2 ohittavan mielivaltaisia objekteja. Tutustu edellisiin esimerkkeihin sovelluksesta soita takaisin , joka palauttaa _Listan_.
Tämä käy ilmeiseksi, kun käytät laatikkoa, jossa on esimerkiksi 5 valikkokohtaa, ja kullakin sivulla laatikon pitäisi näkyä uudelleen.
Puhtaassa toiminnassa selaamisen yhteydessä jokaisen sivun tulisi täyttyä ja käynnistää laatikko, mutta tietysti tämä on kallista.
Esitetyssä kaaviossa näet useita fragmentteja juuresta tai juurenpalaset (FR *), jotka ovat näytön katkelmia, joihin pääsee suoraan laatikosta, ja myös laatikkoon pääsee vain, kun nämä katkelmat näytetään. Kaaviossa kaikki merkityn viivan oikealla puolella on esimerkki mielivaltaisesta navigointijärjestelmästä.
Koska sisältävä aktiviteetti sisältää laatikon, meillä on vain yksi laatikon esiintymä, joten jokaisen navigointivaiheen, jossa laatikon pitäisi olla näkyvissä sinun ei tarvitse aloittaa sitä uudelleen . Etkö ole vieläkään vakuuttunut siitä, miten kaikki toimii? Katsokaa näytesovellustani, jossa näytetään laatikoiden käyttöä.
Suuri pelkoni on aina ollut, että jos käytän fragmenttien navigointimallia projektissa, kohtaan jossain vaiheessa tuntemattoman ongelman, jota on vaikea ratkaista fragmenttien, kolmannen osapuolen kirjastojen ja Systemin eri versioiden monimutkaisuuden ympärillä. Operatiivinen. Entä jos minun täytyisi taittaa kaikki mitä olen tähän mennessä tehnyt?
Itse asiassa sinun on ratkaistava ongelmat sisäkkäisiä fragmentteja , kolmannen osapuolen kirjastot, jotka käyttävät katkelmia, kuten ShinobiControls , ViewPagers Y FragmentStatePagerAdapterit .
Myönnän, että riittävä kokemus fragmenteista näiden ongelmien ratkaisemiseksi oli pitkä prosessi. Mutta kummassakin tapauksessa ongelma ei ollut siinä, että filosofia olisi huono, vaan siinä, että hän ei ymmärtänyt fragmentteja tarpeeksi. Mutta jos ymmärrät fragmentteja paremmin kuin minä tuolloin, sinulla ei ole mitään ongelmaa.
Ainoa miinus, jonka voin mainita nyt, on se, että löydämme ongelmia, jotka eivät ole triviaalia ratkaista, koska ei ole olemassa kypsiä kirjastoja, jotka näyttäisivät kaikki kompleksisen sovelluksen monimutkaiset skenaariot fragmenttipohjaisella navigoinnilla.
Tässä artikkelissa olemme nähneet vaihtoehdon navigoinnin toteuttamiseksi sovelluksessa Android . Mallia verrattiin perinteiseen navigointifilosofiaan, joka käyttää aktiviteetteja, ja näimme joitain erittäin hyviä syitä, miksi on edullista käyttää fragmentteja perinteisen lähestymistavan sijaan.
Jos et ole vielä tarkistanut sitä, tutustu esittelysovellukseen käyttöönotossa GitHub . Älä pelkää antaa hyviä esimerkkejä, jotka voisivat paremmin osoittaa sen käytön.
Liittyvät: Top 10 yleisintä virhettä, joita Android-kehittäjät tekevät