Zmapuj komponenty na istniejący kod

Deweloperzy mogą dostosować proces generowania kodu, podając mapowanie między pakietem interfejsu użytkownika a istniejącym komponentem kodu zamiast wygenerowanego kodu. Jest to przydatne, gdy istniejąca implementacja zawiera funkcje, których nie można uzyskać za pomocą wygenerowanego kodu, np. animację lub złożone zachowanie (np. menu rozwijane).

Deweloperzy określają sposób mapowania komponentów za pomocą pliku mapowania. Plik mapowania informuje generator kodu co najmniej o tym, jak dotrzeć do docelowej funkcji kompozytowej, aby można było utworzyć odpowiedni kod klienta.

Diagram z omówieniem zmapowanego komponentu

Oto przykład:

W Figmie projektant tworzy komponent Karta, który zawiera instancję komponentu Pasek odtwarzania, pakuje oba komponenty i wysyła je do dewelopera.

Gdy deweloper importuje pakiety interfejsu z Figmy, w folderze ui-packages tworzone są 2 katalogi: cardplay_bar. Podczas tworzenia projektu tworzone są 2 funkcje składane: CardPlayBar. Zwykle, ponieważ Karta zawiera instancję paska odtwarzania w Figmie, w kodzie funkcja składanego Card zawiera wywołanie składanego PlayBar.

Projektant i programista chcą jednak, aby Card używał istniejącego komponentu MyExistingPlaybar, który ma funkcje, które trudno opisać w Figmie. Dlatego deweloper dodaje plik mapowania o nazwie play_bar.json, który mapuje pakiet interfejsu użytkownika play_bar na MyExistingPlaybar:

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

Teraz, gdy deweloper kompiluje projekt, funkcja Card wywołuje funkcję MyExistingPlaybar zamiast PlayBar. Pamiętaj, że dyrektywa MyExistingPlaybar musi mieć te same parametry co dyrektywa PlayBar (chociaż może się to różnić w niektórych aspektach, jak opisano w sekcji Dodatkowe dyrektywy).

Plik mapowania

W projektach w Android Studio pliki mapowania są dodawane w folderze ui-package-resources/mappings obok folderu ui-packages. Relay szuka plików mapowania podczas kompilacji.

Plik mapowania w widoku projektu

Generowanie pliku mapowania

Relay może wygenerować plik mapowania dla dowolnego zaimportowanego pakietu interfejsu. Wykonaj te czynności:

  1. Kliknij prawym przyciskiem myszy folder pakietu lub dowolny plik w folderze docelowym ui-package Kliknij Wygeneruj plik mapowania.

    Generowanie pliku mapowania

  2. W oknie skonfiguruj te opcje:

    Okno generowania plików mapowania

    • Lokalizacja pliku: ustawia lokalizację wygenerowanego pliku mapowania.

    • Docelowy komponent składany: ustawia niestandardowy komponent składany, który jest używany zamiast wygenerowanego komponenta składanego. Możesz użyć istniejącego komponentu lub utworzyć nowy w oknie. Tworzenie nowego komponentu powoduje utworzenie komponentu z tymi samymi parametrami, które są zdefiniowane w pakiecie interfejsu użytkownika.

    • Wygenerowany plik: ustawia opcje generateImplementation i generatePreview w pliku mapowania. Więcej informacji znajdziesz w sekcji Mapowanie zawartości pliku.
  3. Kliknij Wygeneruj plik mapowania. W folderze ui-package-resources/mapping zostanie utworzony nowy plik mapowania ze wskazanymi konfiguracjami.

Możesz też otworzyć okno Generowanie pliku mapowania w interfejsie użytkownika modułu pakietu Relay, wykonując te czynności:

  1. Kliknij dowolny plik pakietu interfejsu w folderze docelowym ui-package.

  2. Jeśli okno narzędzia Relay nie otworzy się automatycznie, kliknij ikonę Relay, aby je otworzyć.

  3. W sekcji Opcje pakietu kliknij przycisk Wygeneruj plik mapowania.

    Generowanie pliku mapowania

Nazwa pliku mapowania

Nazwa danego pliku mapowania musi być zgodna z nazwą folderu pakietu interfejsu użytkownika dla zastępowanego komponentu. play_bar.json mapuje pakiet interfejsu użytkownika w folderze ui-packages/mappings na istniejący komponent kodu.

Mapowanie zawartości plików

Plik mapowania zawiera te właściwości:

  • target: (wymagany) nazwa niestandardowej funkcji składanej. Domyślnie jest to nazwa funkcji utworzonej przez wygenerowany kod.

    "target" : "CustomComposableName"
    
  • package: (wymagany) nazwa pakietu, w którym znajduje się niestandardowy komponent. Domyślnie jest to pakiet funkcji utworzonej przez wygenerowany kod.

    "package" : "com.example.podcastapp.ui.components"
    
  • generateImplementation: (opcjonalnie) wartość true lub false. Jeśli to pole ma wartość Prawda, w wygenerowanym pliku z kodem nadal tworzona jest implementacja tego pakietu interfejsu użytkownika. Jeśli ma wartość Fałsz, implementacja nie jest tworzona. Domyślnie ma wartość prawda.

    "generateImplementation" : true
    
  • generatePreviews: (opcjonalnie) wartość true lub false. Jeśli jest ustawiona wartość true, w wygenerowanym pliku kodu jest tworzony podgląd mapowanego komponentu niestandardowego. Jeśli wartość jest równa fałsz, nie jest tworzony podgląd. Domyślnie ma wartość prawda.

    "generatePreviews" : true
    

Zmapowane warianty

Jeśli komponent Figmy ma warianty, wygenerowany element składany zawiera parametry enumeracji, które kodują wariant (jak opisano w samouczku Praca z wariantami projektu). Jeśli chcesz zmapować komponent Figmy z wariantami do istniejącego kodu, musisz go zmapować do komponentu, który przyjmuje te same parametry co wygenerowany komponent. Na przykład w przypadku komponentu Figma o nazwie Element z wariantem, którego właściwość to TypElementu, wygenerowana podpisywana sygnatura ma postać:

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

Jeśli chcesz, aby komponenty Chipa w Figma były mapowane na istniejące komponenty MyChip, podpis MyChip musi mieć ten sam podpis co wygenerowany komponent (zakładając, że nie są określone żadne dodatkowe dyrektywy). Oznacza to, że istniejący komponent kodu może obsługiwać te same warianty projektu co komponent Figmy.

Dodatkowe wskazówki

Jeśli na przykład funkcja składana, którą chcesz użyć jako celu, ma taki podpis:

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

Do pliku mapowania możesz dodać blok fieldMappings, który wpływa na sposób mapowania parametrów. W tym przypadku zawiera mapowanie parametru chipText w elementach Chip na parametr description w elementach MyChip.

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

Typy bloku fieldMappings:

  • parameter: mapowanie pola pakietu interfejsu na parametr kodu.
    • source: nazwa parametru określona w pakiecie interfejsu.
    • target: nazwa parametru określona w komponencie kodu docelowego.
  • lambda: mapuje pole pakietu interfejsu na funkcję lambda treści.
    • source: nazwa parametru określona w pakiecie interfejsu.
    • target: nazwa parametru określona w komponencie kodu docelowego.
  • modifier: mapuje pole pakietu interfejsu na metodę modifier.

    • source: nazwa parametru określona w pakiecie interfejsu.
    • method: metoda obiektu Modifier, która powinna być wywoływana w wygenerowanym kodzie.
    • parameter: nazwa parametru w określonej metodzie Modifier.
    • library: nazwa pakietu z kwalifikacją do zaimportowania, aby uzyskać dostęp do metody Modifier.
    • scope: jedna z 2 wartości określających zakres modyfikatora:
    • any: modyfikator może być używany w dowolnym zakresie odbiornika.
    • relay: modyfikator musi być używany w zakresie odbiornika obiektu RelayContainer obiektu Relay.