Mappare i componenti al codice esistente

Gli sviluppatori possono personalizzare il processo di generazione del codice fornendo una mappatura tra un pacchetto UI e un componente di codice esistente, anziché il codice generato. Ciò è vantaggioso quando l'implementazione esistente presenta funzionalità non raggiungibili dal codice generato, come animazione o comportamenti complessi (come un menu a discesa).

Gli sviluppatori specificano come mappare i componenti utilizzando un file di mappatura. Un file di mapping indica al generatore di codice come raggiungere la funzione componibile di destinazione in modo che sia possibile creare il codice client corretto.

Diagramma panoramica
dei componenti mappati

Ecco un esempio:

In Figma, un designer crea un componente Card che contiene un'istanza di un componente Play Bar, pacchettizza entrambi i componenti e li invia a uno sviluppatore.

Quando lo sviluppatore importa i pacchetti UI da Figma, in ui-packages vengono create due directory: card e play_bar. Quando il progetto viene creato, vengono create due funzioni componibili: Card e PlayBar. In genere, poiché Card contiene un'istanza Play Bar in Figma, nel codice la funzione componibile Card contiene una chiamata all'elemento componibile PlayBar.

Tuttavia, il progettista e lo sviluppatore vogliono che Card utilizzi invece un componibile esistente, MyExistingPlaybar, che ha funzionalità difficili da descrivere in Figma. Lo sviluppatore aggiunge quindi un file di mappatura denominato play_bar.json che mappa il pacchetto UI play_bar a MyExistingPlaybar:

{
    "target": "MyExistingPlaybar",
    "package": "com.example.myApp"
}

Ora, quando lo sviluppatore crea il progetto, Card chiama MyExistingPlaybar anziché PlayBar. Tieni presente che MyExistingPlaybar deve avere gli stessi parametri di PlayBar (anche se possono esserci alcune differenze, come descritto nella sezione Direttive aggiuntive di seguito).

File di mapping

Nei tuoi progetti Android Studio, i file di mapping vengono aggiunti in ui-package-resources/mappings accanto alla cartella ui-packages. Relay cerca i file di mapping durante la build.

Il file di mapping nella visualizzazione
progetto

Generare un file di mappatura

L'inoltro può generare un file di mappatura per qualsiasi pacchetto UI importato. Segui questi passaggi:

  1. Fai clic con il pulsante destro del mouse sulla cartella del pacchetto o su qualsiasi file all'interno della cartella ui-package di destinazione. Seleziona Genera file di mappatura.

    Genera affinità file di mapping

  2. Configura le seguenti opzioni nella finestra di dialogo:

    Finestra di dialogo per generare
file di mapping

    • Posizione file:imposta la posizione del file di mappatura generato.

    • Componibile target: imposta il componibile personalizzato che viene utilizzato al posto dell'elemento componibile generato. Puoi utilizzare un elemento componibile esistente o crearne uno nuovo dalla finestra di dialogo. La creazione di un nuovo componibile crea un componibile con gli stessi parametri definiti nel pacchetto UI.

    • File generato: imposta le opzioni generateImplementation e generatePreview nel file di mappatura. Per ulteriori dettagli, consulta la sezione Mappatura dei contenuti dei file di seguito.
  3. Fai clic su Genera file di mappatura. All'interno della cartella ui-package-resources/mapping viene creato un nuovo file di mapping con le configurazioni specificate.

Puoi anche aprire la finestra di dialogo Genera file di mapping dall'interfaccia utente del modulo Pacchetto di inoltro seguendo questi passaggi:

  1. Fai clic su un file qualsiasi per un pacchetto UI all'interno della cartella ui-package di destinazione.

  2. Se la finestra dello strumento di inoltro non si apre automaticamente, fai clic sull'icona di inoltro per aprirla.

  3. Fai clic sul pulsante Genera file di mappatura in Opzioni pacchetto.

    Genera affinità file di mapping

Nome file di mappatura

Il nome di un determinato file di mapping deve corrispondere al nome della cartella del pacchetto UI relativo al componente che sostituisce. Di conseguenza, play_bar.json mappa il pacchetto UI nella cartella ui-packages/mappings a un componente di codice esistente.

Mappatura dei contenuti dei file

Il file di mapping contiene le seguenti proprietà:

  • target: (obbligatorio) il nome della funzione componibile personalizzata. Per impostazione predefinita, questo è il nome della funzione creata dal codice generato.

    "target" : "CustomComposableName"
    
  • package: (obbligatorio) il nome del pacchetto in cui si trova il componibile personalizzato. Per impostazione predefinita, questo è il pacchetto della funzione creata dal codice generato.

    "package" : "com.example.podcastapp.ui.components"
    
  • generateImplementation: (facoltativo) true o false. Se il valore è true, un'implementazione di questo pacchetto UI viene comunque creata nel file di codice generato. Se il valore è false, l'implementazione non viene creata. Questo è vero per impostazione predefinita.

    "generateImplementation" : true
    
  • generatePreviews: (facoltativo) per true o false. Se il valore è true, viene creata un'anteprima del componente personalizzato mappato nel file di codice generato. Se il valore è false, non viene creata alcuna anteprima. Questo è vero per impostazione predefinita.

    "generatePreviews" : true
    

Varianti mappate

Se un componente Figma ha varianti, il componibile generato contiene parametri di enum che codificano la variante (come descritto nel tutorial Gestione delle varianti di progettazione). Se vuoi mappare un componente Figma con varianti al codice esistente, deve essere mappato a un componibile che accetta gli stessi parametri del componibile generato. Ad esempio, per un componente Figma chiamato Chip con una variante la cui proprietà è ChipType, la firma componibile generata da Chip ha questo aspetto:

@Composable
fun Chip(
    modifier: Modifier = Modifier,
    chipType: ChipType = ChipType.Red,
    chipText: String
) { ... }

Se vuoi che il componente Chip Figma venga mappato a un componibile MyChip esistente, la firma per MyChip deve avere la stessa firma del componibile generato (supponendo che non vengano specificate istruzioni aggiuntive). Concettualmente, ciò suggerisce che il componente di codice esistente è in grado di utilizzare le stesse varianti di progettazione del componente Figma.

Istruzioni aggiuntive

Ad esempio, se la funzione componibile che vuoi scegliere come target ha la seguente firma:

@Composable
fun MyChip(
    modifier: Modifier = Modifier,
    chipType: ChipType = ChipType.Red,
    description: String  // instead of chipText
) { ... }

Puoi aggiungere un blocco fieldMappings al file di mappatura che influisce sulla modalità di mappatura dei parametri. In questo caso, contiene una mappatura dal parametro chipText nel parametro Chip al parametro description in MyChip.

{
    "target": "MyChip",
    "package": "com.example.myApp",
    "fieldMappings": [
        {
            "type": "parameter",
            "source": "chipText",
            "target": "description"
        }
    ]
}

I tipi di blocco fieldMappings includono:

  • parameter: mappa un campo di un pacchetto UI a un parametro di codice.
    • source: nome del parametro specificato nel pacchetto UI.
    • target: nome del parametro specificato nel componente di codice target.
  • lambda: mappa un campo di un pacchetto UI a un lambda di contenuti.
    • source: nome del parametro specificato nel pacchetto UI.
    • target: nome del parametro specificato nel componente di codice target.
  • modifier: mappa un campo di un pacchetto UI a un metodo modifier.

    • source: nome del parametro specificato nel pacchetto UI.
    • method: metodo nell'oggetto Modificatore che deve essere richiamato nel codice generato.
    • parameter: il nome del parametro all'interno del metodo di modifica specificato.
    • library: il nome del pacchetto qualificato da importare per accedere al metodo Modificatore.
    • scope: uno dei due valori per indicare l'ambito del modificatore:
    • any: il modificatore può essere utilizzato in qualsiasi ambito del ricevitore.
    • relay: il modificatore deve essere utilizzato nell'ambito del ricevitore dell'oggetto RelayContainer dell'inoltro.