Czy zdarzało Ci się tworzyć ten sam kod kilka razy? A może kopiujesz kod między projektami, klasami i zmieniasz tylko kilka rzeczy, a mimo to tracisz sporo czasu. A może Ty i twój zespół używacie pewnego wzorca w pisaniu kodu? A może dostarczone szablony w Android Studio nie pasuje do tego, czego potrzebujesz?
Mam dla Ciebie świetną informacje!Powiem Ci, że możesz tworzyć własne szablony kodu w IDE i wykorzystywać je wielokrotnie. Brzmi ciekawie? Czytaj dalej.
Szablony w Android Studio
Ogólnie rzecz biorąc, w Android Studio już masz zdefiniowane szablony i korzystasz z nich (nie)świadomie.
Szablon to plik źródłowy, który zawiera jakiś kod. Za pomocą takich plików można tworzyć nowe moduły aplikacji, aktywności, fragmenty lub inne specyficzne składniki aplikacji na system Android. Poniżej znajdują się domyslne kategorie szablonów w programie Android Studio.
Który język jest używany do tworzenia szablonów Android Studio? Jest to silnik szablonów Apache FreeMarker.
Przygotowałem specjalnie dla Ciebie kurs RecyclerView w Androidzie. Wdziałeś go?
Prosty szablon w Android Studio
Poniżej znajduje się przykład prostego szablonu opartego na jednym pliku.
W pierwszej kolejności naciśnij CTRL (CMD) + SHIFT + A, aby znaleźć akcję, wprowadź „Add Template” i naciśnij przycisk Enter. Zostanie otwarte okno ustawień Android Studio z zakładką „File and Code Template„.
Możesz także iść do tego okna poprzez ustawienia (CTRL+ ALT + S) lub naciśnij prawym przyciskiem myszy na folderze „app” w oknie Project (domyślnie po lewej stronie) i wybierając New -> Edit File Templates.
Naciśnij teraz plusik, aby dodać nowy szablon. Nazwij go „RecyclerView Adapter & ViewHolder”, a rozszerzenie daj jako „.kt” (ponieważ korzystamy z języka Kotlin) i dodaj następujący kod:
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end class ${NAME} (val context: Context, val items : ArrayList<${LIST_MODEL}> ) : RecyclerView.Adapter<${NAME}.${VIEWHOLDER_CLASS}>() { override fun getItemCount() = items.size override fun onCreateViewHolder(parent: ViewGroup,viewType: Int): ${VIEWHOLDER_CLASS} { val view = LayoutInflater.from(parent.context) .inflate(R.layout.${LAYOUT_RES_ID}, parent, false) return ${VIEWHOLDER_CLASS}(view) } override fun onBindViewHolder(myHolder: ${VIEWHOLDER_CLASS}, position: Int) { myHolder.name.text = items.get(position).name myHolder.city.setText(items.get(position).city) myHolder.color.setBackgroundColor(Color.parseColor(items.get(position).color)) myHolder.color.text = position.toString() } inner class ${VIEWHOLDER_CLASS} (view: View) : RecyclerView.ViewHolder(view) { val name = view.name val city = view.city val color = view.color } }
Naciśnij Apply i Ok. Teraz wywołaj menu kontekstowe na pakiecie, w którym chcesz utworzyć plik.
Przed dodaniem pliku do projektu, pojawi się okno dialogowe, w którym można zdefiniować określone wartości dla wszystkich zmiennych niestandardowych.
Jak widać, piszemy standardowy kod, który jest uzupełniony o dodatkowe zmienne. Wraz ze statycznym kodem i komentarzami można również użyć predefiniowanych zmiennych. Możliwe jest również określenie niestandardowych zmiennych w formacie ${…}.
Predefiniowane zmienne szablonu w Android Studio
Predefiniowane zmienne przyjmą następujące wartości:
- ${PACKAGE_NAME} – nazwa pakietu, w którym tworzony jest nowy plik.
- ${NAME} – nazwa nowego pliku określony w oknie dialogowym.
- ${USER} – bieżąca nazwa użytkownika systemu.
- ${DATE} – aktualna data systemowa.
- ${TIME} – aktualny czas systemowy.
- ${YEAR} – rok bieżący.
- ${MONTH} – obecny miesiąc.
- ${MONTH_NAME_SHORT} -pierwsze 3 litery nazwy bieżącego miesiąca.
- ${MONTH_NAME_FULL} – pełna nazwa bieżącego miesiąca.
- ${DAY} – bieżący dzień miesiąca.
- ${DAY_NAME_SHORT} -pierwsze 3 litery nazwy bieżącego dnia.
- ${DAY_NAME_FULL} – pełna nazwa bieżącego dnia.
- ${HOUR} – aktualna godzina.
- ${MINUTE} – aktualna minuta.
- ${PROJECT_NAME} – nazwa bieżącego projektu.
W naszym szablonie Android Studio dyrektywa if w naszym przypadku służy do sprawdzenia, czy nazwa pakietu nie jest pusta. Używając dyrektywy #parse, możesz dołączyć szablony z karty Includes. Na przykład: #parse („File Header.kt”). Szablony dołączone służą do definiowania fragmentów kodu wielokrotnego użytku. Na przykład standardowych nagłówków, oświadczeń o prawach autorskich itp.
Niestandardowe zmienne szablonu
Oprócz predefiniowanych zmiennych szablonów możliwe jest określenie zmiennych niestandardowych. Jeśli to konieczne, możesz zdefiniować wartości zmiennych bezpośrednio w szablonie za pomocą dyrektywy #set.
#set( $WWW = "myenv.net" )
Gdzie są zapisane szablony?
Szablony możesz znaleźć w lokalizacji:
C:\Users\{USER}\.AndroidStudio{VERSION}\config\fileTemplates\
Rozbudowany przykład
Powyżej został przedstawiony prosty przykład z jednym plikiem. Powyższy sposób działa, ale ma jedną wadę. W naszym przypadku utworzenie samego adaptera nic nie da, ponieważ musimy sami stworzyć model danych, aktywność lub fragment gdzie inicjalizujemy RecyclerView. Do tego dochodzi także pliki z układałem widoków.
Aby utworzyć kompletny szablon, przejdź do folderu:
// Windows C:/Program Files/Android/Android Studio/plugins/android/lib/templates/activities/ // Mac /Applications/Android/Studio.app/Contents/plugins/android/lib/templates/activities/
Należy teraz utworzyć nowy katalog — ActivityWithRecyclerView, a następnie utwórz pliki template.xml i recipe.xml.ftl. Stwórz także folder o nazwie root, który będzie przechowywać nasze pliki szablonów.
Istnieje również plik globals.xml.ftl, który zawiera wszystkie zmienne globalne. Dobrą praktyką jest zdefiniowanie zmiennych dla ścieżki katalogu src i res. Jest to plik opcjonalny, dlatego w naszym przykładzie pomijamy go i ścieżki ustawimy na sztywno.
Struktura szablonu będzie przedstawiała sie w następujący sposób:
ActivityWithRecyclerView ./template.xml ./recipe.xml.ftl ./globals.xml.ftl (optional) ./ActivityWithRecyclerView.png ./root/src/app_package/RecyclerViewActivity.kt.ftl ./root/src/app_package/MyRecyclerViewAdapter.kt.ftl ./root/src/app_package/Profile.kt.ftl ./root/res/layout/activity_recycler_view.xml.ftl ./root/res/layout/recyclerview_item.xml.ftl
Plik template.xml
Plik template.xml — definiuje pola wejściowe użytkownika. Są to pola wyboru, listy rozwijane itp., które użytkownik widzi podczas dodawania szablonu do projektu.
<?xml version="1.0"?> <template format="5" revision="1" name="Activity with Recyclerview" description="Creates a new activity with Recyclerview"> <category value="Activity"/> <formfactor value="Mobile" /> <parameter id="activityClass" name="Activity Name" type="string" constraints="class|unique|nonempty" default="RecyclerViewActivity" help="The name of the activity class to create" /> <parameter id="activityLayout" name="Layout Name" type="string" constraints="layout|unique|nonempty" default="recyclerview_activity" help="The name of the layout to create for the activity" /> <parameter id="recyclerViewAdapterClass" name="RecyclerView Adapter Name" type="string" constraints="class|unique|nonempty" default="MyRecyclerViewAdapter" help="The name of the adapter class" /> <parameter id="recyclerviewItem" name="item Layout Name" type="string" constraints="layout|unique|nonempty" default="recyclerview_item" help="The name of the item layout" /> <parameter id="packageName" name="Package name" type="string" constraints="package" default="net.myenv.recyclerview" /> <thumbs> <!-- Default thumbnail. --> <thumb>ActivityWithRecyclerView.png</thumb> </thumbs> <!-- Optional global variables. --> <!-- <globals file="globals.xml.ftl" /> --> <!-- Required recipe (script) to run when instantiating the template. --> <execute file="recipe.xml.ftl" /> </template>
W tym pliku definiujemy takie wartości jak:
- format — wersja formatu szablonu.
- revision — wersja szablonu. Wraz z aktualizacją szablonu możemy zmieniać tą wartość.
- name — nazwa szablonu wyświetlanego w Android Studio.
- description — opis szablonu.
- minApi / minBuildApi (opcjonalny) — minimalny poziom API wymagany dla tego szablonu.
- category — do której kategorii szablon należy. Możemy utworzyć też własną kategorię. Na przykład umieść pliki w folderze Custom, a nie w Activity oraz kategorię wpisz jako „Custom”.
- formfactor — czy chcesz, aby szablon wyświetlał się, gdy tworzysz moduł aplikacji ( Wear, TV itp). Jeśli tak to w jakiej sekcji. Patrz obrazek poniżej.
- Atrybut parameter zawiera:
- id — unikalny identyfikator elementu.
- name — nazwa pola szablonu.
- type — typ danych elementu.
- constraints (opcjonalny) — ograniczenia do wpisywanych wartości. Działa jak inputType w edittext.
- default — wartością domyślną w przypadku, gdy użytkownik pozostawia puste pole.
- help — informacja dla użytkownika, co dany element reprezentuje.
- thumb — podgląd szablonu.
- globals i atrybuty execute łączą nasze pliki globalne i pliki receptur.
Plik recipe.xml.ftl
W pliku recipe.xml.ftl umieszczamy akcję, jakie mają się wykonać. W naszym przypadku pliki z folderu głównego (root) są konwertowane na rzeczywiste pliki Java lub Kotlin. Wskazujemy również jakie pliki powinny zostać otwarte po utworzeniu szablonu w Android Studio.
Możesz również kopiować kod z innych szablonów. Tutaj też defilujesz czy dodać jakieś zależności w pliku gradle. Jeżeli dodajesz aktywność do projektu to musisz także utworzyć odpowiedni wpis w manifeście. Właśnie w tym pliku musisz te informacje zawrzeć.
<?xml version="1.0"?> <recipe> <instantiate from="root/src/app_package/RecyclerViewActivity.kt.ftl" to="${escapeXmlAttribute(srcOut)}/${activityClass}.kt" /> <instantiate from="root/res/layout/activity_recycler_view.xml.ftl" to="${escapeXmlAttribute(resOut)}/layout/${activityLayout}.xml" /> <instantiate from="root/src/app_package/MyRecyclerViewAdapter.kt.ftl" to="${escapeXmlAttribute(srcOut)}/${recyclerViewAdapterClass}.kt" /> <instantiate from="root/res/layout/recyclerview_item.xml.ftl" to="${escapeXmlAttribute(resOut)}/layout/${recyclerviewItem}.xml" /> <instantiate from="root/src/app_package/Profile.kt.ftl" to="${escapeXmlAttribute(srcOut)}/Model/Profile.kt" /> <open file="${escapeXmlAttribute(resOut)}/layout/${activityLayout}.xml" /> <open file="${escapeXmlAttribute(srcOut)}/${activityClass}.kt" /> <open file="${escapeXmlAttribute(resOut)}/layout/${recyclerviewItem}.xml" /> <open file="${escapeXmlAttribute(srcOut)}/${recyclerViewAdapterClass}.kt" /> <open file="${escapeXmlAttribute(srcOut)}/Model/Profile.kt" /> </recipe>
W przykładzie nie ma zapisu jak dodać aktywność do manifestu. To jest Twoje zadanie 🙂 Jeżeli wiesz jak to zrobić, podziel się tą informacją w komentarzu!
Folder root
W tym folderze będziemy mieć dwa katalogi res i src. W folderze res umieszczamy pliki z zasobami. Natomiast w drugim katalogu będą pliki z kodem źródłowym.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/myRC" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" xmlns:android="http://schemas.android.com/apk/res/android"> <TextView android:layout_width="36dp" android:layout_height="34dp" android:id="@+id/color" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginRight="16dp" android:clickable="true" android:gravity="center" android:text="1" android:textSize="25dp" android:textStyle="bold" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/name" android:layout_toRightOf="@+id/color" android:layout_alignParentTop="true" android:textSize="30sp" android:clickable="true" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/city" android:layout_toRightOf="@+id/color" android:layout_below="@+id/name" android:clickable="true" /> <Button android:layout_width="24dp" android:layout_height="24dp" android:id="@+id/delete" android:src="@android:drawable/ic_delete" android:layout_alignParentEnd="true" android:layout_alignParentBottom="true" android:layout_marginStart="16dp" android:visibility="invisible" /> </RelativeLayout>
package ${packageName} import android.content.Context import android.graphics.Color import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import kotlinx.android.synthetic.main.${recyclerviewItem}.view.* class ${recyclerViewAdapterClass} (val context: Context, val items : ArrayList<Profile> ) : RecyclerView.Adapter< ${recyclerViewAdapterClass}.MyViewHolder>() { override fun getItemCount() = items.size override fun onCreateViewHolder(parent: ViewGroup,viewType: Int): MyViewHolder { val view = LayoutInflater.from(parent.context) .inflate(R.layout.recyclerview_item, parent, false) return MyViewHolder(view) } override fun onBindViewHolder(myHolder: MyViewHolder, position: Int) { myHolder.name.text = items.get(position).name myHolder.city.setText(items.get(position).city) myHolder.color.setBackgroundColor(Color.parseColor(items.get(position).color)) myHolder.color.text = position.toString() } inner class MyViewHolder (view: View) : RecyclerView.ViewHolder(view) { val name = view.name val city = view.city val color = view.color } }
package ${packageName} import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import androidx.recyclerview.widget.LinearLayoutManager import io.bloco.faker.Faker import kotlinx.android.synthetic.main.${activityLayout}.* class ${activityClass} : AppCompatActivity() { private var profiles: ArrayList<Profile> = ArrayList() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.${activityLayout}) generateProfiles() } private fun generateProfiles(){ val thread = object : Thread() { override fun run() { val faker = Faker() for (x in 0 until 20) { profiles.add(Profile( x, faker.name.name(), faker.address.city(), faker.color.hexColor() ) ) } runOnUiThread { initRecyclerView() } } } thread.start() } private fun initRecyclerView() { myRC.layoutManager = LinearLayoutManager(this) myRC.setHasFixedSize(true) val adapter = MyRecyclerViewAdapter(this, profiles ) myRC.adapter = adapter } }
package ${packageName} data class Profile(var id: Int, var name: String, var city: String, var color: String )
Testowanie szablonu
Teraz, aby przetestować to, co zostało utworzone, wykonaj następujący kroki:
- Otwórz Android Studio lub, jeśli jest otwarte, uruchom go ponownie.
- Kliknij prawym przyciskiem myszy na pakiet, w którym chcesz utworzyć szablon i wybierz go z menu: New -> Activity -> ActivityWithRecyclerView.
- Wypełnij pola, o które jesteś proszony.
- Poczekaj, aż Android Studio zakończy generowanie plików.
- Gotowe!
Uważaj na aktualizacje Android Studio!
Kompletne szablony są świetne do stworzenia większej ilości kodu. Musisz jednak pamiętać, że możesz je stracić podczas aktualizacji Android Studio.
Gdy pojawi sie nowa wersja IDE możesz otrzymać poniższy komunikat.
Program daje warunek. Albo aktualizujesz, albo kasujesz szablony, które utworzyłeś. Przed aktualizacją wykonaj kopie szablonów Android Studio.
Niestety nie znalazłem sposobu, aby kompletne szablony trzymać w folderze z konfiguracją AD. Może masz na to sposób? Daj mi znać w komentarzu 🙂
Live Template
Jeżeli nie wystarczają Ci powyższe szablony, a mimo to chciałbyś jeszcze bardziej przyspieszyć swoją pracę — pisz skrótami. Po co pisać całą strukturę TextView, skoro można napisać tylko tv (lub inny skrót, który wymyślisz sobie).
Naciśnij znany Ci skrót — CTRL (CMD) + SHIFT + A, aby znaleźć akcję, wprowadź “Live Template” i wybierz odpowiednią opcję. Zostanie otwarte okno ustawień Android Studio z zakładką “Live Template“. Dodaj kod, tak jak zostało to przedstawione na poniższym obrazku.
Teraz wystarczy przejść do jakiegoś layoutu i wpisać tv i nacisnąć klawisz TAB. Kod sam się uzupełni. W naszym przypadku stworzyliśmy własną grupę „Custom”, a w niej odpowiedni rekord. Możesz również dodawać wpisy do już istniejących grup.
Szablony możesz znaleźć w lokalizacji:
C:\Users\<strong>{</strong>USER<strong>}</strong>\.AndroidStudio<strong>{</strong>VERSION<strong>}</strong>\config\ftemplates\
Podsumowanie
Używanie szablonów w Android Studio to potężne narzędzie, które przyspieszają proces tworzenia aplikacji na system Android. Szablony te możesz swobodnie przenosić między członkami zespołu, abyście mogli pracować zgodnie ze standardami.
Jeśli spodobał Ci się ten artykuł i uznałeś go za przydatny, nie zapomnij udostępnić go innym użytkownikom. Nie przegap kolejnych nowości na MYENV i bądźmy również w kontakcie. Zapisz się na [sc_signup_newsletter]newsletter[/sc_signup_newsletter], aby mieć jeszcze więcej fajnych materiałów takich jak ten 😉