2011-11-08 12 views
7

Prima di tutto il mio background: sono nuovo di Java che viene da Ruby. Se ciò aiuta.Perché i parametri di layout funzionano nella Programmazione Android?

Sono confuso su come funzionano i parametri di layout. Sto seguendo una presentazione base di Hello World per la creazione di un'app Android. Passaggio 1, estendere la classe Attività e il metodo onCreate() per accedere al layout XML. Ok, lo capisco.

Poi creare un layout (diciamo un RelativeLayout) nella main.xml. Quindi questo sta facendo uso della classe RelativeLayout che estende la classe ViewGroup, ok finora. Quindi diciamo che creo un pulsante all'interno di questo. È qui che inizia la mia domanda. Se guardo l'esempio che sto seguendo, vedo gli attributi assegnati al pulsante che appartengono alla classe RelativeLayout (ad es .: android: layout_alignParentRight = "true"). Questi sembrano essere i parametri di layout. Ma perché funziona? La classe del pulsante sembra ereditare dalla classe View. Perché un oggetto pulsante può accettare attributi per l'oggetto RelativeLayout? Forse la mia programmazione Ruby mi confonde ..

Grazie!

Aggiornamento: Per amor di poster: grazie a Slothsberry per indicare il collegamento XML Layouts, che sembra descrivere chiaramente la risposta in 2 sezioni la sezione "Attributi" e su "Parametri di layout". La sezione attributi legge:

ogni vista e l'oggetto ViewGroup supporta la propria gamma di XML attributi. Alcuni attributi sono specifici per un oggetto View (per esempio, TextView supporta l'attributo textSize), ma questi attributi sono anche ereditate da qualsiasi vista oggetti che possono estendersi questa classe . Alcuni sono comuni a tutti gli oggetti View, perché sono ereditati dalla classe View View (come l'attributo id), . E, altri attributi sono considerati "i parametri di layout", che sono attributi che descrivono certi orientamenti di layout dell'oggetto vista, come definite dalla oggetto principale ViewGroup di quell'oggetto.

La sezione dei parametri di layout è forse la sezione che risponde veramente a questa domanda. Dove si afferma:

classe Ogni ViewGroup implementa una classe annidata che si estende ViewGroup.LayoutParams. Questa sottoclasse contiene i tipi di proprietà che definiscono la dimensione e la posizione per ogni vista secondaria, come appropriato per il gruppo di viste . Come si può vedere nella figura 1, il gruppo di viste padre definisce i parametri di layout per ogni vista figlio (incluso il gruppo di viste figlio ).

Danno anche un bel diagramma. Sembra che un programmatore principiante debba riconoscere che mentre le classi Java sono referenziate, l'XML agisce più come un foglio CSS e che gli attributi vengono prima calcolati in modo annidato prima di essere calcolati e trasferiti alle loro controparti di classe Java. Questa è la mia attuale comprensione in ogni modo :)

+0

No, hai ragione di pensare che sia strano. Ho programmato in Java da oltre 5 anni, e questo è qualcosa che quando ho visto per la prima volta non aveva senso per me. Non sono ancora sicuro del perché funzioni così. Spero che otterremo una risposta. –

+0

https://developer.android.com/reference/android/view/View.html#Layout – samosaris

risposta

6

I parametri di layout non rispecchiano rigorosamente l'ereditarietà dell'oggetto (come avete notato). Il motivo è che ci sono due parti del layout: la configurazione di una vista e la parametrizzazione di un genitore della vista che utilizza tale vista come argomento.

Quindi parametri come android: layout_below verranno ignorati se il layout genitore non è un RelativeLayout. Potrebbe avere senso da una prospettiva OOP mettere tale parametro nell'oggetto RelativeLayout. Ma è così che lo faresti nel codice java.

Nel codice XML, assume l'approccio che l'informazione sul bambino è contenuta nel bambino. i parametri di layout che richiedono un genitore non presente saranno ignorati quando il layout viene gonfiato. È un buon sistema che Android utilizza per rendere l'XML più leggibile e portatile. E non si riferisce strettamente alla struttura del pacchetto di classe, ma piuttosto al modo intuitivo in cui gli umani pensano di posizionare le cose in un layout.

+0

Grazie, hai compreso chiaramente la mia incomprensione e hai dato un'ottima risposta. Ho aggiunto delle note nella mia domanda per l'amor di posterità basandomi su ulteriori letture. Apprezzalo. – Inc1982

+1

Comprendere l''inflazione' del layout sembra essere una chiave per capire ... un po 'più di lettura che ho trovato in base alla tua risposta: http://www.androidguys.com/2008/07/09/inflation-is-a-good -thing/ – Inc1982

+0

Credo che le proprietà di layout siano ereditate in modo rigoroso, simile all'ereditarietà delle classi.Tuttavia, ciò che Android fa con loro sembra variare, a seconda (almeno) dell'elemento genitore. In generale, dal momento che si creano layout dalla radice verso il basso (a meno che non si riutilizzino include, che hanno già le loro proprietà già impostate), è possibile ignorare le proprietà inappropriate per i propri elementi. Non avevo nemmeno notato che layout_below era sempre disponibile, dato che non l'ho mai guardato a meno che non fossi in un RelativeLayout –

1

si è un po 'confuso, il layout param non possiede un particolare oggetto XML. Se lo si inserisce in un figlio XML XXXView o XXXLAyout, capirà che il suo lato destro deve trovarsi nello stesso posto rispetto al padre.

Quindi se non si creano i parametri di layout per quel bambino, il bambino proverebbe ad ereditare quelli di suo padre.

+0

Grazie per la risposta. Forse puoi aiutarmi a capire da una prospettiva Android/Java. Gli oggetti in Android hanno attributi, sì? Suppongo che tutti gli attributi abbiano un oggetto proprietario, sì? Quando creo un tag button, stai dicendo che non tutti gli attributi definiti all'interno del tag button appartengono all'oggetto button. È corretto? – Inc1982

+0

dipende dal posto in cui lo metti. Devi pensare che l'oggetto stesso debba trovarsi in un altro contenitore. Quindi sei obbediente a dire all'oggetto la posizione relativa al suo genitore. Certo, stiamo parlando solo di un layout relativo. Non è così diverso dalla programmazione CSS. Inoltre, esistono anche altri tag XML che indicano al bambino come ordinare nel genitore. Il sistema è flessibile per queste cose. –

3

Tutti gli elementi di layout in Android ereditano dalla vista, anche se molti indirettamente.

La classe di vista generica ha proprietà (attributi) appropriate per QUALSIASI elemento di layout visibile. per il layout radice, alcune proprietà come Gravità layout, Dimensioni layout, ecc. sono impostate dal sistema (nella maggior parte dei casi, credo).

Se il mio layout di root è un layout lineare, Android mi permetterà di avere un layout relativo come un figlio nella radice. Android mi consentirà di impostare varie proprietà di layout sull'elemento nidificato, al fine di controllarne il rendering. Funziona allo stesso modo per Button e per qualsiasi altro layout Android.

Se non ti interessa una particolare proprietà, non impostarla. Sono presenti per consentire il controllo degli schermi della tua app. Guarda su XML Layouts o Hello Views per iniziare a leggere i dettagli.

+0

Grazie per aver aggiunto alla discussione. Mentre non riuscivo a eliminare il problema dalla tua risposta, il tuo link a XML Layouts mi dava quello di cui avevo bisogno. Ho aggiornato la mia domanda sopra per includere come ho risolto la mia comprensione. Puoi farmi sapere se sembra giusto. :) – Inc1982

0

Layout

layout è un processo a due passaggi: un passaggio di misurazione e un passaggio del layout. Il passaggio di misurazione è implementato in measure(int, int) ed è un attraversamento top-down dell'albero della vista. Ogni vista spinge le specifiche delle dimensioni lungo l'albero durante la ricorsione. Alla fine del passaggio di misura, ogni vista ha memorizzato le sue misure. Il secondo passaggio avviene in layout(int, int, int, int) ed è anche top-down. Durante questo passaggio ogni genitore è responsabile del posizionamento di tutti i suoi figli utilizzando le dimensioni calcolate nel passaggio di misura.

quando il metodo ritorna misura() di un'immagine, i suoi getMeasuredWidth() e getMeasuredHeight() valori devono essere regolati, insieme a quelli per tutti i discendenti di quella vista. La larghezza misurata di una vista e i valori di altezza misurati devono rispettare i vincoli imposti dai genitori della vista. Questo garantisce che alla fine del passaggio di misura, tutti i genitori accettano tutte le misurazioni dei loro figli. Una vista genitore può chiamare measure() più di una volta sui suoi figli. Ad esempio, il genitore può misurare ogni bambino una volta con dimensioni non specificate per scoprire quanto grande vuole essere, quindi chiamare misura() su di esse di nuovo con numeri reali se la somma di tutte le dimensioni non vincolate dei bambini è troppo grande o troppo piccola.

Il passaggio di misura utilizza due classi per comunicare le dimensioni. La classe View.MeasureSpec viene utilizzata dalle viste per comunicare ai genitori come vogliono essere misurati e posizionati. La classe di base LayoutParams descrive solo quanto grande deve essere la vista sia per la larghezza che per l'altezza.Per ogni dimensione, si può specificare una delle:

  • un numero esatto
  • MATCH_PARENT, il che significa che la vista vuole essere grande come suo genitore (meno imbottitura)
  • wrap_content, il che significa che il view vuole essere abbastanza grande per racchiudere il suo contenuto (più padding).

Esistono sottoclassi di LayoutParam per diverse sottoclassi di ViewGroup. Ad esempio, AbsoluteLayout ha una propria sottoclasse di LayoutParams che aggiunge un valore X e Y.

MeasureSpecs vengono utilizzati per spingere i requisiti lungo l'albero da padre a figlio. Un MeasureSpec può trovarsi in uno dei tre modi:

  • SPECIFICATO: Questo è usato da un genitore per determinare la desiderata dimensione di vista del bambino. Ad esempio, un LinearLayout può chiamare measure() sul suo child con l'altezza impostata su OFFLINE e una larghezza di EXACTLY 240 per scoprire quanto è alta la vista figlio che deve essere data una larghezza di 240 pixel.
  • ESATTAMENTE: viene utilizzato dal genitore per imporre una dimensione esatta sul figlio . Il bambino deve usare questa taglia e garantire che tutti i suoi discendenti si adattino a questa dimensione.
  • AT_MOST: utilizzato dal genitore per imporre una dimensione massima al figlio . Il bambino deve garantire che esso e tutti i suoi discendenti si adattino a questa dimensione.

Per avviare un layout, chiamata requestLayout(). Questo metodo viene in genere chiamato da una vista su se stesso quando ritiene che non sia più adatto ai limiti attuali.

Problemi correlati