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.
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: card
i play_bar
. Podczas tworzenia projektu tworzone są 2 funkcje składane: Card
i PlayBar
. 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.
Generowanie pliku mapowania
Relay może wygenerować plik mapowania dla dowolnego zaimportowanego pakietu interfejsu. Wykonaj te czynności:
Kliknij prawym przyciskiem myszy folder pakietu lub dowolny plik w folderze docelowym
ui-package
Kliknij Wygeneruj plik mapowania.W oknie skonfiguruj te opcje:
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
igeneratePreview
w pliku mapowania. Więcej informacji znajdziesz w sekcji Mapowanie zawartości pliku.
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:
Kliknij dowolny plik pakietu interfejsu w folderze docelowym
ui-package
.Jeśli okno narzędzia Relay nie otworzy się automatycznie, kliknij ikonę Relay, aby je otworzyć.
W sekcji Opcje pakietu kliknij przycisk Wygeneruj plik 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 obiektuRelayContainer
obiektu Relay.