1. Başlamadan önce
Bu codelab'de, özel renklerinizi dinamik bir temayla oluşturulan renklerle uyumlu hale getirmeyi öğreneceksiniz.
Ön koşullar
Geliştiriciler ise
- Android'deki temel tema oluşturma kavramlarına aşinayım.
- Android widget Görünümleri ve özellikleriyle çalışma
Neler öğreneceksiniz?
- Birden fazla yöntem kullanarak uygulamanızda renk uyumunu kullanma
- Uyumun işleyiş şekli ve rengi değiştirme şekli
Gerekenler
- Android yüklü bir bilgisayarla ilgili talimatları uygulayabilirsiniz.
2. Uygulamaya Genel Bakış
Voyaĝi, halihazırda dinamik tema kullanan bir toplu taşıma uygulamasıdır. Birçok toplu taşıma sisteminde renk, tren, otobüs veya tramvay için önemli bir göstergedir ve bunlar, mevcut dinamik birincil, ikincil veya üçüncül renklerle değiştirilemez. Çalışmamızda renkli toplu taşıma kartlarının RecyclerView üzerinde yoğunlaşacağız.
3. Tema Oluşturma
Material3 teması oluşturmak için ilk durağınız olarak Material Theme Builder aracımızı kullanmanızı öneririz. Özel sekmede artık temanıza daha fazla renk ekleyebilirsiniz. Sağ tarafta, bu renkler için renk rolleri ve ton paletleri gösterilir.
Genişletilmiş renk bölümünde, renkleri kaldırabilir veya yeniden adlandırabilirsiniz.
Dışa aktarma menüsünde çeşitli dışa aktarma seçenekleri gösterilir. Bu yazının yazıldığı sırada, Material Theme Builder'ın uyum ayarlarını özel olarak işleme özelliği yalnızca Android Görünümleri'nde kullanılabiliyor.
Yeni dışa aktarma değerlerini anlama
Uyumlaştırmayı tercih edip etmemenizden bağımsız olarak bu renkleri ve ilişkili renk rollerini temalarınızda kullanabilmeniz için, dışa aktarılan indirme artık her özel rengin renk rolü adlarını içeren bir attrs.xml dosyası içeriyor.
<resources>
<attr name="colorCustom1" format="color" />
<attr name="colorOnCustom1" format="color" />
<attr name="colorCustom1Container" format="color" />
<attr name="colorOnCustom1Container" format="color" />
<attr name="harmonizeCustom1" format="boolean" />
<attr name="colorCustom2" format="color" />
<attr name="colorOnCustom2" format="color" />
<attr name="colorCustom2Container" format="color" />
<attr name="colorOnCustom2Container" format="color" />
<attr name="harmonizeCustom2" format="boolean" />
</resources>
temalar.xml dosyasında her bir özel renk (color<name>, colorOn<name>, color<name>Container, and colorOn<nameContainer>
) için dört renk rolü oluşturduk. harmonize<name>
özellikleri, geliştiricinin Materyal Tema Oluşturucu'da ilgili seçeneği belirleyip belirlemediğini yansıtır. Temel temanın rengini kaydırmaz.
<resources>
<style name="AppTheme" parent="Theme.Material3.Light.NoActionBar">
<!--- Normal theme attributes ... -->
<item name="colorCustom1">#006876</item>
<item name="colorOnCustom1">#ffffff</item>
<item name="colorCustom1Container">#97f0ff</item>
<item name="colorOnCustom1Container">#001f24</item>
<item name="harmonizeCustom1">false</item>
<item name="colorCustom2">#016e00</item>
<item name="colorOnCustom2">#ffffff</item>
<item name="colorCustom2Container">#78ff57</item>
<item name="colorOnCustom2Container">#002200</item>
<item name="harmonizeCustom2">false</item>
</style>
</resources>
colors.xml
dosyasında, yukarıda listelenen renk rollerini oluşturmak için kullanılan çekirdek renkler ve rengin paletinin değiştirilip kaydırılmayacağına ilişkin Boole değerleri belirtilir.
<resources>
<!-- other colors used in theme -->
<color name="custom1">#1AC9E0</color>
<color name="custom2">#32D312</color>
</resources>
4. Özel Rengi inceleme
Material Theme Builder'ın yan paneline baktığımızda, özel bir renk eklendiğinde, açık ve koyu bir paletteki dört temel renk rolünün yer aldığı bir panelin gösterildiğini görebiliyoruz.
Android Görünümlerinde bu renkleri sizin için dışa aktarırız ancak perde arkasında ColorRoles
nesnesinin bir örneğiyle temsil edilebilirler.
ColorRoles sınıfının dört özelliği vardır: accent
, onAccent
, accentContainer
ve onAccentContainer
. Bu özellikler, dört onaltılık rengin tam sayı gösterimidir.
public final class ColorRoles {
private final int accent;
private final int onAccent;
private final int accentContainer;
private final int onAccentContainer;
// truncated code
}
getColorRoles
adlı MaterialColors sınıfında getColorRoles
kullanarak çalışma zamanında rastgele bir renkten dört temel renk rolünü alabilirsiniz. Bu rol, belirli bir çekirdek rengi verildiğinde çalışma zamanında dört renk rolü grubunu oluşturmanıza olanak tanır.
public static ColorRoles getColorRoles(
@NonNull Context context,
@ColorInt int color
) { /* implementation */ }
Benzer şekilde, çıkış değerleri de gerçek renk değerleridir, bunları işaret etmez.**
5. Renk Uyumu nedir?
Material'ın yeni renk sistemi, belirli bir çekirdek renginden birincil, ikincil, üçüncül ve nötr renkler oluşturarak algoritmik bir tasarıma sahiptir. Şirket içi ve şirket dışı iş ortaklarıyla konuşurken en çok karşılaştığımız konulardan biri, bazı renkler üzerinde kontrol sahibi olurken dinamik renklerin benimsenmesiydi.
Bu renkler genellikle uygulamada belirli bir anlam veya bağlam taşır ve rastgele bir renkle değiştirilmeleri durumunda kaybolur. Alternatif olarak, bu renkler olduğu gibi bırakıldığında, görsel olarak rahatsız edici veya alakasız görünebilir.
Material You'daki renk özelliği ton, renk ve tonla tanımlanır. Bir rengin tonu, kişinin o rengin bir başka renk aralığının üyesi olarak algılanmasıyla ilgilidir. Ton, rengin ne kadar açık veya koyu göründüğünü belirtir. Renk ise renk yoğunluğunu ifade eder. Ton algısı, kültürel ve dilsel faktörlerden etkilenebilir. Örneğin, antik kültürlerde mavi için çok az kelime kullanılması, mavi için yeşil olarak aynı ailede görülmesi gibi.
Ton spektrumunda bulunduğu yere bağlı olarak belirli bir ton sıcak veya soğuk olarak kabul edilebilir. Kırmızı, turuncu veya sarı tonlara geçiş yapmak genellikle rengi daha sıcak, mavi, yeşil veya mor tonlara geçmek rengin daha serin olduğu kabul edilir. Sıcak veya soğuk renklerde bile sıcak ve soğuk tonlar kullanılır. Altında, "sıcaklık" sarı daha turuncu, "soğutucu" ise daha tonludur. sarı, yeşilden daha fazla etkilenir.
Renk uyumlaştırma algoritması, uyumlu olan ancak temel renk niteliklerini değiştirmeyen bir tonu bulmak için, değişmemiş rengin ve uyumlu hale getirilmesi gereken rengin tonunu inceler. İlk grafikte, spektrumda çizilmiş daha az uyumlu yeşil, sarı ve turuncu tonlar var. Bir sonraki grafikte yeşil ve turuncu renk, sarı renkle uyumlu hale getirilmiş. Yeni yeşil daha sıcak, yeni turuncu ise daha havalı.
Turuncu ve yeşilin tonları değişmiştir ancak yine de turuncu ve yeşil olarak algılanabilir.
Tasarımla ilgili bazı kararlar, keşifler ve dikkat edilmesi gereken noktalar hakkında daha fazla bilgi edinmek isterseniz meslektaşlarım Ayan Daniels ve Andrew Lu, bu bölümden biraz daha ayrıntılı bir blog yayını yazmışlar.
6. Rengi manuel olarak uyumlu hale getirme
Tek bir tonu uyumlu hale getirmek için MaterialColors
, harmonize
ve harmonizeWithPrimary
olmak üzere iki işlevden yararlanabilirsiniz.
harmonizeWithPrimary
, mevcut temaya ve ardından da temadaki birincil renge erişmek için bir araç olarak Context
kullanır.
@ColorInt
public static int harmonizeWithPrimary(@NonNull Context context, @ColorInt int colorToHarmonize) {
return harmonize(
colorToHarmonize,
getColor(context, R.attr.colorPrimary, MaterialColors.class.getCanonicalName()));
}
@ColorInt
public static int harmonize(@ColorInt int colorToHarmonize, @ColorInt int colorToHarmonizeWith) {
return Blend.harmonize(colorToHarmonize, colorToHarmonizeWith);
}
Dört tonlu seti almak için biraz daha işlem yapmamız gerekiyor.
Kaynak rengi zaten mevcut olduğundan, şunları yapmamız gerekir:
- uyumlu hale getirilmesi gerekip gerekmediğini
- koyu modda olup olmadığımızı belirlemeli
- uyumlulaştırılmış veya uyumlu olmayan
ColorRoles
nesnesini döndürür.
Uyum sağlayıp sağlamayacağını belirleme
Material Theme Builder'dan dışa aktarılan temada, harmonize<Color>
terminolojisini kullanan boole özellikleri ekledik. Bu değere erişmek için kullanılan bir kolaylık işlevi aşağıda verilmiştir.
Bulunursa değerini döndürür; aksi takdirde rengi uyumlu hale getirmemesi gerektiğini belirler.
// Looks for associated harmonization attribute based on the color id
// custom1 ===> harmonizeCustom1
fun shouldHarmonize(context: Context, colorId: Int): Boolean {
val root = context.resources.getResourceEntryName(colorId)
val harmonizedId = "harmonize" + root.replaceFirstChar { it.uppercaseChar() }
val identifier = context.resources.getIdentifier(
harmonizedId, "bool", context.packageName)
return if (identifier != 0) context.resources.getBoolean(identifier) else false
}
Uyumlaştırılmış ColorRoles
nesnesi oluşturma
retrieveHarmonizedColorRoles
, yukarıda belirtilen tüm adımları birleştiren başka bir kolaylık işlevidir: adlandırılmış bir kaynağın renk değerini alma, harmonizasyonu belirlemek için bir boole özelliğini çözümlemeye çalışır ve orijinal veya karma renkten (açık veya koyu şema) türetilen bir ColorRoles
nesnesini döndürür.
fun retrieveHarmonizedColorRoles(
view: View,
customId: Int,
isLight: Boolean
): ColorRoles {
val context = view.context
val custom = context.getColor(customId);
val shouldHarmonize = shouldHarmonize(context, customId)
if (shouldHarmonize) {
val blended = MaterialColors.harmonizeWithPrimary(context, custom)
return MaterialColors.getColorRoles(blended, isLight)
} else return MaterialColors.getColorRoles(custom, isLight)
}
7. Toplu taşıma kartları dolduruluyor
Daha önce de belirtildiği gibi, toplu taşıma kartı koleksiyonunu doldurmak ve renklendirmek için bir RecyclerView ve adaptör kullanacağız.
Toplu taşıma verilerini depolama
Toplu taşıma kartlarıyla ilgili metin verilerini ve renk bilgilerini depolamak için adı, hedefi ve renk kaynağı kimliğini depolayan bir veri sınıfı kullanıyoruz.
data class TransitInfo(val name: String, val destination: String, val colorId: Int)
/* truncated code */
val transitItems = listOf(
TransitInfo("53", "Irvine", R.color.custom1),
TransitInfo("153", "Brea", R.color.custom1),
TransitInfo("Orange County Line", "Oceanside", R.color.custom2),
TransitInfo("Pacific Surfliner", "San Diego", R.color.custom2)
)
İhtiyacımız olan tonları gerçek zamanlı olarak oluşturmak için bu rengi kullanacağız.
Aşağıdaki onBindViewHolder
işleviyle çalışma zamanında uyumlu hale getirebilirsiniz.
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val transitInfo = list.get(position)
val color = transitInfo.colorId
if (!colorRolesMap.containsKey(color)) {
val roles = retrieveHarmonizedColorRoles(
holder.itemView, color,
!isNightMode(holder.itemView.context)
)
colorRolesMap.put(color, roles)
}
val card = holder.card
holder.transitName.text = transitInfo.name
holder.transitDestination.text = transitInfo.destination
val colorRoles = colorRolesMap.get(color)
if (colorRoles != null) {
holder.card.setCardBackgroundColor(colorRoles.accentContainer)
holder.transitName.setTextColor(colorRoles.onAccentContainer)
holder.transitDestination.setTextColor(colorRoles.onAccentContainer)
}
}
8. Renkleri otomatik olarak uyumlu hale getirme
Uyumlaştırmayı manuel olarak ele almaya alternatif olarak, sizin yerinize halledebilirsiniz. HarmonizedColorOptions, şu ana kadar elde ettiğimiz işlemlerin çoğunu belirtmenize olanak tanıyan bir oluşturucu sınıfıdır.
Geçerli dinamik şemaya erişebilmek için geçerli bağlamı aldıktan sonra, uyumlu hale getirmek istediğiniz temel renkleri belirtmeniz ve HarmonizedColorOptions nesnesine ve DynamicColors'ın etkinleştirildiği bağlama dayalı yeni bir bağlam oluşturmanız gerekir.
Bir rengi uyumlu hale getirmek istemiyorsanız, rengi harmonizedOptions'a dahil etmeyin.
val newContext = DynamicColors.wrapContextIfAvailable(requireContext())
val harmonizedOptions = HarmonizedColorsOptions.Builder()
.setColorResourceIds(intArrayOf(R.color.custom1, R.color.custom2))
.build();
harmonizedContext =
HarmonizedColors.wrapContextIfAvailable(dynamicColorsContext, harmonizedOptions)
Uyumlaştırılmış temel renk işlenmiş durumdayken onBindViewHolder'ınızı MaterialColors.getColorRoles
çağrısı yapacak şekilde güncelleyebilir ve döndürülen rollerin açık mı yoksa koyu mu olacağını belirtebilirsiniz.
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
/*...*/
val color = transitInfo.colorId
if (!colorRolesMap.containsKey(color)) {
val roles = MaterialColors.getColorRoles(context.getColor(color), !isNightMode(context))
)
colorRolesMap.put(color, roles)
}
val card = holder.card
holder.transitName.text = transitInfo.name
holder.transitDestination.text = transitInfo.destination
val colorRoles = colorRolesMap.get(color)
if (colorRoles != null) {
holder.card.setCardBackgroundColor(colorRoles.accentContainer)
holder.transitName.setTextColor(colorRoles.onAccentContainer)
holder.transitDestination.setTextColor(colorRoles.onAccentContainer)
}
}
9. Tema özelliklerini otomatik olarak uyumlu hale getirme
Şimdiye kadar gösterilen yöntemler, tek bir renkten renk rollerinin alınmasına dayanıyor. Bu, gerçek bir üslup oluşturulduğunu ancak mevcut uygulamaların çoğuna göre gerçekçi olmadığını göstermek için harika bir uygulamadır. Muhtemelen renk türünü doğrudan türetmek yerine mevcut bir tema özelliğini kullanırsınız.
Bu codelab'in önceki bölümlerinde tema özelliklerini dışa aktarma hakkında konuşmuştuk.
<resources>
<style name="AppTheme" parent="Theme.Material3.Light.NoActionBar">
<!--- Normal theme attributes ... -->
<item name="colorCustom1">#006876</item>
<item name="colorOnCustom1">#ffffff</item>
<item name="colorCustom1Container">#97f0ff</item>
<item name="colorOnCustom1Container">#001f24</item>
<item name="harmonizeCustom1">false</item>
<item name="colorCustom2">#016e00</item>
<item name="colorOnCustom2">#ffffff</item>
<item name="colorCustom2Container">#78ff57</item>
<item name="colorOnCustom2Container">#002200</item>
<item name="harmonizeCustom2">false</item>
</style>
</resources>
İlk otomatik yönteme benzer şekilde, HarmonizedColorOptions'a değerler sağlayabilir ve uyumlu renklerle Bağlam bilgisi almak için HarmonizedColors'ı kullanabiliriz. İki yöntem arasında temel bir fark vardır. Ayrıca, uyumlu hale getirilecek alanları içeren bir tema yer paylaşımı sağlamamız gerekir.
val dynamicColorsContext = DynamicColors.wrapContextIfAvailable(requireContext())
// Harmonizing individual attributes
val harmonizedColorAttributes = HarmonizedColorAttributes.create(
intArrayOf(
R.attr.colorCustom1,
R.attr.colorOnCustom1,
R.attr.colorCustom1Container,
R.attr.colorOnCustom1Container,
R.attr.colorCustom2,
R.attr.colorOnCustom2,
R.attr.colorCustom2Container,
R.attr.colorOnCustom2Container
), R.style.AppTheme_Overlay
)
val harmonizedOptions =
HarmonizedColorsOptions.Builder().setColorAttributes(harmonizedColorAttributes).build()
val harmonizedContext =
HarmonizedColors.wrapContextIfAvailable(dynamicColorsContext, harmonizedOptions)
Bağdaştırıcınız uyumlulaştırılmış bağlamı kullanır. Tema yer paylaşımındaki değerler, uyumlu olmayan açık veya koyu varyanta başvurmalıdır.
<style name="AppTheme.Overlay" parent="AppTheme">
<item name="colorCustom1">@color/harmonized_colorCustom1</item>
<item name="colorOnCustom1">@color/harmonized_colorOnCustom1</item>
<item name="colorCustom1Container">@color/harmonized_colorCustom1Container</item>
<item name="colorOnCustom1Container">@color/harmonized_colorOnCustom1Container</item>
<item name="colorCustom2">@color/harmonized_colorCustom2</item>
<item name="colorOnCustom2">@color/harmonized_colorOnCustom2</item>
<item name="colorCustom2Container">@color/harmonized_colorCustom2Container</item>
<item name="colorOnCustom2Container">@color/harmonized_colorOnCustom2Container</item>
</style>
XML düzen dosyasında, bu uyumlu özellikleri normal şekilde kullanabiliriz.
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
style="?attr/materialCardViewFilledStyle"
android:id="@+id/card"
android:layout_width="80dp"
android:layout_height="100dp"
android:layout_marginStart="8dp"
app:cardBackgroundColor="?attr/colorCustom1Container"
>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="8dp">
<TextView
android:id="@+id/transitName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="28sp"
android:textStyle="bold"
android:textColor="?attr/colorOnCustom1Container"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/transitDestination"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:textColor="?attr/colorOnCustom1Container"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
10. Kaynak Kodu
package com.example.voyagi.harmonization.ui.dashboard
import android.content.Context
import android.content.res.Configuration
import android.graphics.Typeface
import android.os.Bundle
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.voyagi.harmonization.R
import com.example.voyagi.harmonization.databinding.FragmentDashboardBinding
import com.example.voyagi.harmonization.ui.home.TransitCardAdapter
import com.example.voyagi.harmonization.ui.home.TransitInfo
import com.google.android.material.card.MaterialCardView
import com.google.android.material.color.ColorRoles
import com.google.android.material.color.DynamicColors
import com.google.android.material.color.HarmonizedColorAttributes
import com.google.android.material.color.HarmonizedColors
import com.google.android.material.color.HarmonizedColorsOptions
import com.google.android.material.color.MaterialColors
class DashboardFragment : Fragment() {
enum class TransitMode { BUS, TRAIN }
data class TransitInfo2(val name: String, val destination: String, val mode: TransitMode)
private lateinit var dashboardViewModel: DashboardViewModel
private var _binding: FragmentDashboardBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
dashboardViewModel =
ViewModelProvider(this).get(DashboardViewModel::class.java)
_binding = FragmentDashboardBinding.inflate(inflater, container, false)
val root: View = binding.root
val recyclerView = binding.recyclerView
val transitItems = listOf(
TransitInfo2("53", "Irvine", TransitMode.BUS),
TransitInfo2("153", "Brea", TransitMode.BUS),
TransitInfo2("Orange County Line", "Oceanside", TransitMode.TRAIN),
TransitInfo2("Pacific Surfliner", "San Diego", TransitMode.TRAIN)
)
val dynamicColorsContext = DynamicColors.wrapContextIfAvailable(requireContext())
// Harmonizing individual attributes
val harmonizedColorAttributes = HarmonizedColorAttributes.create(
intArrayOf(
R.attr.colorCustom1,
R.attr.colorOnCustom1,
R.attr.colorCustom1Container,
R.attr.colorOnCustom1Container,
R.attr.colorCustom2,
R.attr.colorOnCustom2,
R.attr.colorCustom2Container,
R.attr.colorOnCustom2Container
), R.style.AppTheme_Overlay
)
val harmonizedOptions =
HarmonizedColorsOptions.Builder().setColorAttributes(harmonizedColorAttributes).build()
val harmonizedContext =
HarmonizedColors.wrapContextIfAvailable(dynamicColorsContext, harmonizedOptions)
val adapter = TransitCardAdapterAttr(transitItems, harmonizedContext)
recyclerView.adapter = adapter
recyclerView.layoutManager =
LinearLayoutManager(harmonizedContext, RecyclerView.HORIZONTAL, false)
return root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
class TransitCardAdapterAttr(val list: List<DashboardFragment.TransitInfo2>, context: Context) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
val colorRolesMap = mutableMapOf<Int, ColorRoles>()
private var harmonizedContext: Context? = context
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): RecyclerView.ViewHolder {
return if (viewType == DashboardFragment.TransitMode.BUS.ordinal) {
BusViewHolder(LayoutInflater.from(harmonizedContext).inflate(R.layout.transit_item_bus, parent, false))
} else TrainViewHolder(LayoutInflater.from(harmonizedContext).inflate(R.layout.transit_item_train, parent, false))
}
override fun getItemCount(): Int {
return list.size
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val item = list[position]
if (item.mode.ordinal == DashboardFragment.TransitMode.BUS.ordinal) {
(holder as BusViewHolder).bind(item)
(holder as TransitBindable).adjustNameLength()
} else {
(holder as TrainViewHolder).bind(item)
(holder as TransitBindable).adjustNameLength()
}
}
override fun getItemViewType(position: Int): Int {
return list[position].mode.ordinal
}
interface TransitBindable {
val card: MaterialCardView
var transitName: TextView
var transitDestination: TextView
fun bind(item: DashboardFragment.TransitInfo2) {
transitName.text = item.name
transitDestination.text = item.destination
}
fun Float.toDp(context: Context) =
TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
this,
context.resources.displayMetrics
)
fun adjustNameLength(){
if (transitName.length() > 4) {
val layoutParams = card.layoutParams
layoutParams.width = 100f.toDp(card.context).toInt()
card.layoutParams = layoutParams
transitName.setTypeface(Typeface.DEFAULT_BOLD);
transitName.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16.0f)
}
}
}
inner class BusViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), TransitBindable {
override val card: MaterialCardView = itemView.findViewById(R.id.card)
override var transitName: TextView = itemView.findViewById(R.id.transitName)
override var transitDestination: TextView = itemView.findViewById(R.id.transitDestination)
}
inner class TrainViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), TransitBindable {
override val card: MaterialCardView = itemView.findViewById(R.id.card)
override var transitName: TextView = itemView.findViewById(R.id.transitName)
override var transitDestination: TextView = itemView.findViewById(R.id.transitDestination)
}
}
11. Örnek kullanıcı arayüzleri
Uyumlaştırmadan Varsayılan Tema Oluşturma ve Özel Renkler
Uyumlaştırılmış Özel Renkler
12. Özet
Bu codelab'de şunları öğrendiniz:
- Renk uyumlaştırma algoritmamızın temelleri
- Görülen belirli bir renkten renk rolleri oluşturma.
- Kullanıcı arayüzünde belirli bir rengi seçerek uyumlu hale getirme.
- Bir temada özellik grubunu uyumlu hale getirme.
Sorularınız varsa Twitter'da@MaterialDesign hesabını kullanarak dilediğiniz zaman bize sorabilirsiniz.
youtube.com/MaterialDesign adresinden daha fazla tasarım içeriği ve eğitici içerik için bizi takip etmeye devam edin.