Bu sayfada, mevcut Glance bileşenlerini kullanarak boyutların nasıl ele alınacağı ve Glance ile esnek ve duyarlı düzenlerin nasıl sağlanacağı açıklanmaktadır.
Box
, Column
ve Row
kullanın
Glance'ta composable üç ana sayfa düzeni bulunur:
Box
: Öğeleri başka bir öğenin üzerine yerleştirir.RelativeLayout
diline çevrilir.Column
: Öğeleri dikey eksende birbirinden sonra yerleştirir. Dikey yönlüLinearLayout
anlamına gelir.Row
: Öğeleri yatay eksende birbirinden sonra yerleştirir. Yatay yönlü birLinearLayout
anlamına gelir.
Glance, Scaffold
nesnelerini destekler. Column
, Row
ve Box
composable'larınızı belirli bir Scaffold
nesnesine yerleştirin.
Bu composable'ların her biri, içeriklerinin dikey ve yatay hizalamalarını ve değiştiricileri kullanarak genişlik, yükseklik, ağırlık veya dolgu kısıtlamalarını tanımlamanızı sağlar. Buna ek olarak, her alt öğe üst öğe içindeki alanı ve yerleşimi değiştirmek için değiştiricisini tanımlayabilir.
Aşağıdaki örnekte, Şekil 1'de görüldüğü gibi, alt öğelerini yatay olarak eşit bir şekilde dağıtan bir Row
öğesinin nasıl oluşturulacağı gösterilmektedir:
Row(modifier = GlanceModifier.fillMaxWidth().padding(16.dp)) { val modifier = GlanceModifier.defaultWeight() Text("first", modifier) Text("second", modifier) Text("third", modifier) }
Row
, kullanılabilir maksimum genişliği doldurur ve her alt öğe aynı ağırlığa sahip olduğundan kullanılabilir alanı eşit olarak paylaşır. Düzenleri ihtiyaçlarınıza göre uyarlamak için farklı ağırlıklar, boyutlar, dolgular veya hizalamalar tanımlayabilirsiniz.
Kaydırılabilir düzenler kullanma
Duyarlı içerik sağlamanın bir başka yolu da kaydırılabilir hale getirmektir. Bu, LazyColumn
composable ile yapılabilir. Bu composable, uygulama widget'ındaki kaydırılabilir bir kapsayıcıda görüntülenecek bir dizi öğe tanımlamanıza olanak sağlar.
Aşağıdaki snippet'ler, LazyColumn
içindeki öğeleri tanımlamanın farklı yollarını gösterir.
Öğe sayısını sağlayabilirsiniz:
// Remember to import Glance Composables // import androidx.glance.appwidget.layout.LazyColumn LazyColumn { items(10) { index: Int -> Text( text = "Item $index", modifier = GlanceModifier.fillMaxWidth() ) } }
Öğeleri tek tek girin:
LazyColumn { item { Text("First Item") } item { Text("Second Item") } }
Bir öğe listesi veya dizisi sağlayın:
LazyColumn { items(peopleNameList) { name -> Text(name) } }
Yukarıdaki örneklerin bir kombinasyonunu da kullanabilirsiniz:
LazyColumn { item { Text("Names:") } items(peopleNameList) { name -> Text(name) } // or in case you need the index: itemsIndexed(peopleNameList) { index, person -> Text("$person at index $index") } }
Önceki snippet'in itemId
değerini belirtmediğini unutmayın. itemId
öğesinin belirtilmesi, performansı iyileştirmeye ve Android 12 ve sonraki sürümlerden itibaren appWidget
güncellemelerine (örneğin, listeye öğe eklerken veya listeden öğe çıkarırken) ve listede kaydırma konumunun korunmasına yardımcı olur. Aşağıdaki örnekte itemId
öğesinin nasıl belirtileceği gösterilmektedir:
items(items = peopleList, key = { person -> person.id }) { person -> Text(person.name) }
SizeMode
tanımlayın
AppWidget
boyutları cihaza, kullanıcının tercihine veya başlatıcıya bağlı olarak farklılık gösterebilir. Bu nedenle, Esnek widget düzenleri sağlama sayfasında açıklandığı gibi esnek düzenler sağlamanız önemlidir. Glance, SizeMode
tanımı ve LocalSize
değeri ile bu işlemi basitleştirir. Aşağıdaki bölümlerde üç mod açıklanmaktadır.
SizeMode.Single
SizeMode.Single
varsayılan moddur. Yalnızca bir içerik türünün sağlandığını, yani AppWidget
kullanılabilir boyut değişse bile içerik boyutunun değişmediğini gösterir.
class MyAppWidget : GlanceAppWidget() { override val sizeMode = SizeMode.Single override suspend fun provideGlance(context: Context, id: GlanceId) { // ... provideContent { MyContent() } } @Composable private fun MyContent() { // Size will be the minimum size or resizable // size defined in the App Widget metadata val size = LocalSize.current // ... } }
Bu modu kullanırken şunlardan emin olun:
- Minimum ve maksimum boyut meta veri değerleri, içerik boyutuna göre doğru şekilde tanımlanır.
- İçerik, beklenen boyut aralığında yeterince esnek olmalıdır.
Genel olarak bu modu aşağıdaki durumlardan birinde kullanmalısınız:
a) AppWidget
sabit boyuttaysa veya
b) yeniden boyutlandırıldığında içeriğini değiştirmiyor.
SizeMode.Responsive
Bu mod, duyarlı düzenler sağlama ile eşdeğerdir. Bu mod, GlanceAppWidget
öğesinin belirli boyutlarla sınırlanmış bir dizi duyarlı düzen tanımlamasına olanak tanır. Tanımlanan her boyut için içerik oluşturulur ve AppWidget
oluşturulduğunda veya güncellendiğinde belirli boyutla eşlenir. Daha sonra sistem, mevcut boyuta göre en uygun boyutu seçer.
Örneğin, AppWidget
hedefimizde üç boyut ve içeriğini tanımlayabilirsiniz:
class MyAppWidget : GlanceAppWidget() { companion object { private val SMALL_SQUARE = DpSize(100.dp, 100.dp) private val HORIZONTAL_RECTANGLE = DpSize(250.dp, 100.dp) private val BIG_SQUARE = DpSize(250.dp, 250.dp) } override val sizeMode = SizeMode.Responsive( setOf( SMALL_SQUARE, HORIZONTAL_RECTANGLE, BIG_SQUARE ) ) override suspend fun provideGlance(context: Context, id: GlanceId) { // ... provideContent { MyContent() } } @Composable private fun MyContent() { // Size will be one of the sizes defined above. val size = LocalSize.current Column { if (size.height >= BIG_SQUARE.height) { Text(text = "Where to?", modifier = GlanceModifier.padding(12.dp)) } Row(horizontalAlignment = Alignment.CenterHorizontally) { Button() Button() if (size.width >= HORIZONTAL_RECTANGLE.width) { Button("School") } } if (size.height >= BIG_SQUARE.height) { Text(text = "provided by X") } } } }
Önceki örnekte, provideContent
yöntemi üç kez çağrılır ve tanımlanan boyutla eşlenir.
- İlk çağrıda boyut
100x100
olarak değerlendirilir. İçerik ekstra düğme veya üst ve alt metinler içermez. - İkinci çağrıda, boyut
250x100
olarak değerlendirilir. İçerikte ekstra düğme bulunur, ancak üst ve alt metinler içerikte yer almaz. - Üçüncü çağrıda boyut
250x250
olarak değerlendirilir. İçerikte ekstra düğme ve her iki metin de bulunuyor.
SizeMode.Responsive
, diğer iki modun kombinasyonudur ve önceden tanımlanmış sınırlar dahilinde duyarlı içerik tanımlayabilmenizi sağlar. Genel olarak bu mod, AppWidget
yeniden boyutlandırıldığında daha iyi performans gösterir ve daha yumuşak geçişler sağlar.
Aşağıdaki tabloda, SizeMode
ve AppWidget
kullanılabilir boyuta bağlı olarak boyut değeri gösterilmektedir:
Kullanılabilir boyut | 105 x 110 | 203 x 112 | 72 x 72 | 203 x 150 |
---|---|---|---|---|
SizeMode.Single |
110 x 110 | 110 x 110 | 110 x 110 | 110 x 110 |
SizeMode.Exact |
105 x 110 | 203 x 112 | 72 x 72 | 203 x 150 |
SizeMode.Responsive |
80 x 100 | 80 x 100 | 80 x 100 | 150 x 120 |
* Tam değerler yalnızca demo amaçlıdır. |
SizeMode.Exact
SizeMode.Exact
, tam düzenler sağlama ile eşdeğerdir. Bu işlem, mevcut AppWidget
boyutu her değiştiğinde (örneğin, kullanıcı ana ekranda AppWidget
öğesini yeniden boyutlandırdığında) GlanceAppWidget
içeriğini ister.
Örneğin, hedef widget'ta, kullanılabilen genişlik belirli bir değerden büyükse fazladan bir düğme eklenebilir.
class MyAppWidget : GlanceAppWidget() { override val sizeMode = SizeMode.Exact override suspend fun provideGlance(context: Context, id: GlanceId) { // ... provideContent { MyContent() } } @Composable private fun MyContent() { // Size will be the size of the AppWidget val size = LocalSize.current Column { Text(text = "Where to?", modifier = GlanceModifier.padding(12.dp)) Row(horizontalAlignment = Alignment.CenterHorizontally) { Button() Button() if (size.width > 250.dp) { Button("School") } } } } }
Bu mod diğerlerinden daha fazla esneklik sağlasa da dikkat edilmesi gereken birkaç nokta vardır:
- Boyut her değiştiğinde
AppWidget
tamamen yeniden oluşturulmalıdır. Bu durum, içerik karmaşık olduğunda performans sorunlarına ve kullanıcı arayüzünde atlamalara yol açabilir. - Kullanılabilir boyut, başlatıcının uygulamasına bağlı olarak farklılık gösterebilir. Örneğin, başlatıcı boyut listesi sağlamazsa mümkün olan minimum boyut kullanılır.
- Boyut hesaplama mantığı, Android 12 öncesi cihazlarda her durumda çalışmayabilir.
Genel olarak bu modu, SizeMode.Responsive
kullanılamıyorsa (yani küçük bir duyarlı düzen grubu uygun değilse) kullanmalısınız.
Kaynaklara erişin
Android kaynaklarına erişmek için aşağıdaki örnekte gösterildiği gibi LocalContext.current
kullanın:
LocalContext.current.getString(R.string.glance_title)
Nihai RemoteViews
nesnesinin boyutunu küçültmek ve dinamik renkler gibi dinamik kaynakları etkinleştirmek için doğrudan kaynak kimlikleri sağlamanızı öneririz.
Oluşturulabilirler ve yöntemler, ImageProvider
gibi bir "sağlayıcı" veya GlanceModifier.background(R.color.blue)
gibi bir aşırı yükleme yöntemi kullanan kaynakları kabul eder. Örnek:
Column( modifier = GlanceModifier.background(R.color.default_widget_background) ) { /**...*/ } Image( provider = ImageProvider(R.drawable.ic_logo), contentDescription = "My image", )
Herkese açık kullanıcı adı metni
Glance 1.1.0, metin stillerinizi ayarlayabileceğiniz bir API içerir. TextStyle sınıfının fontSize
, fontWeight
veya fontFamily
özelliklerini kullanarak metin stillerini ayarlayın.
fontFamily
, aşağıdaki örnekte gösterildiği gibi tüm sistem yazı tiplerini destekler, ancak uygulamalarda özel yazı tipleri desteklenmez:
Text(
style = TextStyle(
fontWeight = FontWeight.Bold,
fontSize = 18.sp,
fontFamily = FontFamily.Monospace
),
text = "Example Text"
)
Bileşik düğme ekle
Bileşik düğmeler Android 12'de kullanıma sunuldu. Bir Bakışta, aşağıdaki bileşik düğme türleri için geriye dönük uyumluluğu destekler:
Bu birleşik düğmelerin her biri, "işaretli" durumunu temsil eden tıklanabilir bir görünüm gösterir.
var isApplesChecked by remember { mutableStateOf(false) } var isEnabledSwitched by remember { mutableStateOf(false) } var isRadioChecked by remember { mutableStateOf(0) } CheckBox( checked = isApplesChecked, onCheckedChange = { isApplesChecked = !isApplesChecked }, text = "Apples" ) Switch( checked = isEnabledSwitched, onCheckedChange = { isEnabledSwitched = !isEnabledSwitched }, text = "Enabled" ) RadioButton( checked = isRadioChecked == 1, onClick = { isRadioChecked = 1 }, text = "Checked" )
Durum değiştiğinde, sağlanan lambda tetiklenir. Kontrol durumunu aşağıdaki örnekte gösterildiği gibi depolayabilirsiniz:
class MyAppWidget : GlanceAppWidget() { override suspend fun provideGlance(context: Context, id: GlanceId) { val myRepository = MyRepository.getInstance() provideContent { val scope = rememberCoroutineScope() val saveApple: (Boolean) -> Unit = { scope.launch { myRepository.saveApple(it) } } MyContent(saveApple) } } @Composable private fun MyContent(saveApple: (Boolean) -> Unit) { var isAppleChecked by remember { mutableStateOf(false) } Button( text = "Save", onClick = { saveApple(isAppleChecked) } ) } }
CheckBox
, Switch
ve RadioButton
renklerini özelleştirmek için colors
özelliğini de kullanabilirsiniz:
CheckBox( // ... colors = CheckboxDefaults.colors( checkedColor = ColorProvider(day = colorAccentDay, night = colorAccentNight), uncheckedColor = ColorProvider(day = Color.DarkGray, night = Color.LightGray) ), checked = isChecked, onCheckedChange = { isChecked = !isChecked } ) Switch( // ... colors = SwitchDefaults.colors( checkedThumbColor = ColorProvider(day = Color.Red, night = Color.Cyan), uncheckedThumbColor = ColorProvider(day = Color.Green, night = Color.Magenta), checkedTrackColor = ColorProvider(day = Color.Blue, night = Color.Yellow), uncheckedTrackColor = ColorProvider(day = Color.Magenta, night = Color.Green) ), checked = isChecked, onCheckedChange = { isChecked = !isChecked }, text = "Enabled" ) RadioButton( // ... colors = RadioButtonDefaults.colors( checkedColor = ColorProvider(day = Color.Cyan, night = Color.Yellow), uncheckedColor = ColorProvider(day = Color.Red, night = Color.Blue) ), )
Ek bileşenler
Glance 1.1.0, aşağıdaki tabloda açıklandığı gibi ek bileşenlerin kullanıma sunulmasını içerir:
Ad | Resim | Referans bağlantısı | Ek notlar |
---|---|---|---|
Doldurulmuş Düğme | Bileşen | ||
Dış Çizgi Düğmeler | Bileşen | ||
Simge Düğmeleri | Bileşen | Birincil / İkincil / Yalnızca simge | |
Başlık Çubuğu | Bileşen | ||
İskele | İskele ve Başlık çubuğu aynı demodadır. |
Tasarım ayrıntıları hakkında daha fazla bilgi için Figma'daki bu tasarım kitinde bileşen tasarımlarına bakın.