Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Flex 4 e i Layout

Slegare la rappresentazione degli oggetti dalla logica applicativa
Slegare la rappresentazione degli oggetti dalla logica applicativa
Link copiato negli appunti

In attesa della prima release stabile di Flex 4 possiamo impratichirci con alcune delle novità già annunciate e disponibili nella beta dell'SDK. In questo articolo ci focalizzeremo sui layout, interessantissima funzionalità che introduce la possibilità (finalmente!) di scorporare completamente il layer di presentazione da quello di logica funzionale consentendoci perfino di incidere in modo marcato sulle metafore di interazione della nostra applicazione senza scomodarne le funzionalità.

La sessione sarà molto pratica e focalizzata sulla creazione di un certo numero di esempi, ognuno volto ad evidenziare alcune specifiche peculiarità di queste nuove API. È consigliata l'installazione dell'ultima versione di Flex Builder, ora rinominato in Flash Builder, la cui beta è disponibile per Mac e Windows.

La teoria dei Layout

Come potete aver intuito, anche perché questo termine è utilizzato con significato simile in altre tecnologie, un layout in Flex specifica come deve comportarsi il meccanismo di disposizione degli oggetti all'interno di un'applicazione. Questo però non si riduce al funzionamento classico, tipico del celeberrimo GridLayout delle awt di Java, che comporta solo l'imposizione di alcune costrizioni e automatismi nel posizionamento degli elementi ma ad un interessante e potentissimo meccanismo che nasce dalla combinazione di coordinate spaziali e variabili definite dall'utente, consentendoci di implementare logiche di collocazione che variano nel tempo o al variare di specifici parametri.

I layout che Flex mette a disposizione sono quattro, scorriamoli brevemente:

Layout Descrizione
BasicLayout viene implementato di default dall'applicazione e si comporta in modo completamente trasparente delegando ai posizionamenti assoluti dei singoli elementi l'onere di presiedere la disposizione dell'interfaccia
HorizontalLayout come suggerito dal nome, questo layout dispone gli elementi orizzontalmente uno a fianco del successivo ignorando le proprietà spaziali dei singoli oggetti, come ad esempio gli attributi 'x' e 'y'
VerticalLayout esattamente come il precedente ma questa volta la disposizione viene fatta automaticamente sull'asse delle ordinate
TileLayout equivale, nella sua implementazione standard, ad un HorizontalLayout con in più la peculiarità di andare a capo di riga nel momento in le dimensioni dell'oggetto da posizionare superino quelle dello spazio residuo nella riga corrente

Per testare questi quattro layout possiamo costruire una piccolissima applicazione (Flash Builder: File -> New -> Flex Project) contenente il seguente codice:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/halo" min min>
  <s:layout>
    <s:BasicLayout/>
  </s:layout>
  <s:Button label="prova layout 1"/>
  <s:Button label="prova layout 2"/>
  <s:Button label="prova layout 3"/>
</s:Application>

ed eseguirla sostituendo di volta in volta la dichiarazione sul layout da usare con una delle quattro a disposizione.

È anche possibile specificare un layout per una particolare porzione della nostra applicazione includendo gli oggetti che ci interessano e la dichiarazione del layout in un tag <s:group>.

Creare un layout da zero

Dopo questo breve intervallo teorico e introduttivo cominciamo ad approfondire il tema dei layout in Flex 4 creandone uno completamente nostro: PerspectiveLayout. L'obiettivo di questo layout è disporre gli elementi secondo una linea di fuga distanziandoli sull'asse z uno dall'altro con l'idea di ottenere un effetto di profondità esteticamente convincente.

Per prima cosa creiamo un nuovo progetto Flex e inseriamo nel file MXML alcuni elementi che fungeranno da cavie per il nostro esperimento: in questo caso si tratta di alcune immagini, scaricabili qui, all'interno di un tag <s:list>:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/halo"
               xmlns:flex4layouts="it.html.flash.flex4layouts.*">
  <s:List id="list"  
          labelField="label"
          itemRenderer="spark.skins.spark.DefaultComplexItemRenderer">
    <s:layout>
      <s:VerticalLayout/>
    </s:layout>
    <s:dataProvider>
      <s:ArrayList>
        <s:BitmapImage source="number1.jpg"/>
        <s:BitmapImage source="number2.jpg"/>
        <s:BitmapImage source="number3.jpg"/>
        <s:BitmapImage source="number4.jpg"/>
        <s:BitmapImage source="number5.jpg"/>
      </s:ArrayList>
    </s:dataProvider>
  </s:List>
</s:Application>

Prima di proseguire eseguiamo il progetto per certificare la disposizione verticale degli elementi.

Il prossimo passo consiste nel creare la classe che rappresenta il layout (Flash Builder: File -> New -> ActionScript Class); impostiamola con i seguenti parametri:

Parametro Valore
Package arbitrario, possiamo scegliere ad esempio it.html.flash.flex4layouts
Name PerspectiveLayout
Superclass spark.layouts.supportClasses.LayoutBase

Premendo il pulsante Finish verrà generato un nuovo file PerspectiveLayout.as contenente quel poco codice necessario a effettuare gli import necessari, dichiarare la classe e descriverne il costruttore. A questo punto non ci resta che sovrascrivere la funzione 'updateDisplayList' che abbiamo ereditato da LayoutBase modificandola a nostro piacimento in modo che operi sugli elementi suscettibili a questo layout.

Per ottenere l'effetto desiderato è necessario invocare su ogni oggetto in interesse il metodo setLayoutMatrix3D(m) specificando nella variabile m una matrice che descrive le trasformazioni che vogliamo applicare. A seguire il codice risultante:

package it.html.flash.flex4layouts
{
  import flash.geom.Matrix3D;
  import flash.geom.Vector3D;
  import mx.core.ILayoutElement;
  import mx.core.IVisualElement;
  import spark.layouts.supportClasses.LayoutBase;
  
  public class PerspectiveLayout extends LayoutBase
  {
    override public function updateDisplayList(width:Number, height:Number) : void
    {
      for (var i:int = 0; i < target.numElements; i++)
      {
        var element:ILayoutElement = target.getVirtualElementAt(i);
        var m3d:Matrix3D = new Matrix3D();
        
        m3d.appendTranslation(
          (target.numElements-i)*5 + 50,
          100,
          (target.numElements-i)*50
        );
        
        m3d.appendRotation(-30,Vector3D.X_AXIS);
        element.setLayoutMatrix3D(m3d,false);
      }
    }
  }
}

Come possiamo notare la variabile m3d, che contiene un'istanza della classe Matrix3D, mette a disposizione una serie di metodi (appendTranslation, appendRotation e appendScale) utilissimi nel mascherare la complessità che dovremmo affrontare impostando manualmente i valori di una matrice di trasformazione.

Per ammirare il risultato del nostro impegno non ci resta che modificare la dichiarazione di layout sostituendo a <s:VerticalLayout/> il nostro <flex4layouts:PerspectiveLayout/> ed eseguire il progetto.

Nella seconda parte dell'articolo vedremo come aggiungere un aspetto dinamico al nostro layout.

Un layout dinamico

In questo parte dell'articolo impareremo come rendere il nostro layout un pò più dinamico facendo in modo che uno slider posto sulla scena possa controllarne l'orientamento degli elementi. Incominciamo inserendo il componente HSlider all'interno del file MXML aggiungendo il seguente codice appena dopo la chiusura del tag </s:List>:

<s:HSlider 	id="axisSlider"
            minimum="-30"
            maximum="30"
            value="10"
            liveDragging="true"
             />

Il passo successivo consiste nel fare in modo che PerspectiveLayout possa essere influenzato da una variabile che poi andremo a gestire a livello di interfaccia; questo si traduce semplicemente nel creare una funzione setter che porti il nome che vogliamo dare all'attributo dinamico:

// Aggiungere questa funzione all'interno della classe PerspectiveLayout

private var _angle:Number = 0;
public function set axisAngle(value:Number):void
{
  _angle = value;
  
  var layoutTarget:GroupBase = target;
  if (layoutTarget)
  {
    layoutTarget.invalidateSize();
    layoutTarget.invalidateDisplayList();
  }
}

Le ultime due istruzioni di questa funzione obbligano l'interprete a ricalcolare il layout a fronte della modifica del valore dell'attributo che abbiamo deciso essere dinamico (il nome dell'attributo corrisponde al nome della funzione, in questo caso axisAngle); questa operazione contempla anche che l'interprete chiami la funzione updateDisplayList che ora andremo a modificare in modo che sia influenzata dalla variabile _angle appena valorizzata.

Per le semplici finalità di questo articolo, e per ottenere un effetto accattivante, è sufficiente sostituire con _angle il -30 passato come parametro alla funzione m3d.appendRotation ottenendo il seguente codice:

  m3d.appendRotation(_angle,Vector3D.X_AXIS);

Come ultimo tocco non ci resta che aggiungere la valorizzazione dell'attributo axisAngle all'interno della dichiarazione del layout nel file MXML, modifichiamo quindi il codice tra i tag <s:layout> in modo da ottenere:

<s:layout>
	<flex4layouts:PerspectiveLayout axisAngle="{axisSlider.value}"/>
</s:layout>

Eseguiamo il progetto e proviamo a spostare lo slider posizionato in alto per ammirare il frutto del nostro impegno:

Conclusioni

L'introduzione dei Layout ha segnato un grande passo avanti per quanto riguarda il paradigma di progettazione delle interfaccie nel mondo Flex, dall'anno prossimo sarà infatti possibile scorporare completamente la parte di presentazione da quella di business logic e, con l'aiuto di altre nuove features come ad esempio le Skin, riuscire finalmente a trasformare l'approccio a questa tecnologia ad oggi ancora troppo condizionata dai suoi passati come Flash.

Sono già disponibili sulla rete alcuni layout tridimensionali preconfezionati (ad esempio qui e qui) e spero che nel 2010 altri ne vengano creati fino alla realizzazione di un vero proprio database condiviso di layout e skin a disposizione della comunità di sviluppatori.

Prima di salutarvi vi ricordo che, allegato a questo articolo, troverete un archivio compresso contenente i sorgenti dell'applicativo descritto.

Ti consigliamo anche