Kartları kullanmaya başlayın

Uygulamanızdan karo sağlamaya başlamak için uygulamanızın build.gradle dosyasına aşağıdaki bağımlılıkları ekleyin.

Groovy

dependencies {
    // Use to implement support for wear tiles
    implementation "androidx.wear.tiles:tiles:1.5.0-alpha04"

    // Use to utilize standard components and layouts in your tiles
    implementation "androidx.wear.protolayout:protolayout:1.3.0-alpha04"

    // Use to utilize components and layouts with Material Design in your tiles
    implementation "androidx.wear.protolayout:protolayout-material:1.3.0-alpha04"

    // Use to include dynamic expressions in your tiles
    implementation "androidx.wear.protolayout:protolayout-expression:1.3.0-alpha04"

    // Use to preview wear tiles in your own app
    debugImplementation "androidx.wear.tiles:tiles-renderer:1.5.0-alpha04"

    // Use to fetch tiles from a tile provider in your tests
    testImplementation "androidx.wear.tiles:tiles-testing:1.5.0-alpha04"
}

Kotlin

dependencies {
    // Use to implement support for wear tiles
    implementation("androidx.wear.tiles:tiles:1.5.0-alpha04")

    // Use to utilize standard components and layouts in your tiles
    implementation("androidx.wear.protolayout:protolayout:1.3.0-alpha04")

    // Use to utilize components and layouts with Material Design in your tiles
    implementation("androidx.wear.protolayout:protolayout-material:1.3.0-alpha04")

    // Use to include dynamic expressions in your tiles
    implementation("androidx.wear.protolayout:protolayout-expression:1.3.0-alpha04")

    // Use to preview wear tiles in your own app
    debugImplementation("androidx.wear.tiles:tiles-renderer:1.5.0-alpha04")

    // Use to fetch tiles from a tile provider in your tests
    testImplementation("androidx.wear.tiles:tiles-testing:1.5.0-alpha04")
}

Kart oluşturma

Uygulamanızdan bir kart sağlamak için TileService sınıfını genişleten ve aşağıdaki kod örneğinde gösterildiği gibi yöntemleri uygulayan bir sınıf oluşturun:

class MyTileService : TileService() {

    override fun onTileRequest(requestParams: RequestBuilders.TileRequest) =
        Futures.immediateFuture(
            Tile.Builder()
                .setResourcesVersion(RESOURCES_VERSION)
                .setTileTimeline(
                    Timeline.fromLayoutElement(
                        Text.Builder(this, "Hello World!")
                            .setTypography(Typography.TYPOGRAPHY_BODY1)
                            .setColor(argb(0xFFFFFFFF.toInt()))
                            .build()
                    )
                )
                .build()
        )

    override fun onTileResourcesRequest(requestParams: ResourcesRequest) =
        Futures.immediateFuture(
            Resources.Builder()
                .setVersion(RESOURCES_VERSION)
                .build()
        )
}

Ardından, AndroidManifest.xml dosyanızın <application> etiketine bir hizmet ekleyin.

<service
    android:name=".snippets.tile.MyTileService"
    android:label="@string/tile_label"
    android:description="@string/tile_description"
    android:icon="@mipmap/ic_launcher"
    android:exported="true"
    android:permission="com.google.android.wearable.permission.BIND_TILE_PROVIDER">
    <intent-filter>
        <action android:name="androidx.wear.tiles.action.BIND_TILE_PROVIDER" />
    </intent-filter>

    <meta-data android:name="androidx.wear.tiles.PREVIEW"
        android:resource="@drawable/tile_preview" />
</service>

İzin ve intent filtresi, bu hizmeti kart sağlayıcı olarak kaydeder.

Simge, etiket, açıklama ve önizleme kaynağı, kullanıcı telefonunda veya kol saatinde kartları yapılandırdığında gösterilir.

Parça hizmeti yaşam döngüsüne genel bakış

TileService öğenizi oluşturup uygulama manifest dosyanızda beyan ettikten sonra kart hizmetinin durum değişikliklerine yanıt verebilirsiniz.

TileService bir bağlama hizmetidir. TileService, uygulama isteğiniz sonucunda veya sistemin onunla iletişim kurması gerektiğinde bağlanır. Tipik bir bağlı hizmet yaşam döngüsü aşağıdaki dört geri çağırma yöntemini içerir: onCreate(), onBind(), onUnbind() ve onDestroy(). Sistem, hizmet yeni bir yaşam döngüsü aşamasına her girdiğinde bu yöntemleri çağırır.

Bağlı hizmet yaşam döngüsünü kontrol eden geri çağırmalara ek olarak, TileService yaşam döngüsüne özgü diğer yöntemleri de uygulayabilirsiniz. Tüm kart hizmetlerinin, sistemden gelen güncelleme isteklerine yanıt vermek için onTileRequest() ve onTileResourcesRequest()'i uygulaması gerekir.

  • onTileAddEvent(): Sistem bu yöntemi yalnızca kullanıcı kartınızı ilk kez eklediğinde ve kaldırıp tekrar eklediğinde çağırır. Tek seferlik başlatma işlemlerini bu sırada yapmanız önerilir.

    onTileAddEvent() yalnızca sistem tarafından bir kart oluşturulduğunda değil, kart grubu yeniden yapılandırıldığında çağrılır. Örneğin, cihaz yeniden başlatılırken veya açıldığında, daha önce eklenmiş kartlar için onTileAddEvent() çağrılmaz. Size ait hangi karoların etkin olduğunun anlık görüntüsünü almak için bunun yerine getActiveTilesAsync() kullanabilirsiniz.

  • onTileRemoveEvent(): Sistem bu yöntemi yalnızca kullanıcı kartınızı kaldırırsa çağırır.

  • onTileEnterEvent(): Sistem, bu sağlayıcı tarafından sağlanan bir kart ekranda göründüğünde bu yöntemi çağırır.

  • onTileLeaveEvent(): Sistem, bu sağlayıcı tarafından sağlanan bir kart ekranda görünmez hale geldiğinde bu yöntemi çağırır.

  • onTileRequest(): Sistem bu sağlayıcıdan yeni bir zaman çizelgesi istediğinde bu yöntem çağrılır.

  • onTileResourcesRequest(): Sistem bu sağlayıcıdan kaynak paketi istediğinde bu yöntem çağrılır. Bu durum, bir Kart ilk kez yüklenirken veya kaynak sürümü değiştiğinde ortaya çıkabilir.

Hangi karoların etkin olduğunu sorgulayın

Etkin kartlar, kol saatinde gösterilmek üzere eklenen kartlardır. Uygulamanıza ait hangi karoların etkin olduğunu sorgulamak için TileService'nin statik yöntemi getActiveTilesAsync()'i kullanın.

Kartlar için kullanıcı arayüzü oluşturma

Kartın düzeni, bir oluşturucu kalıbı kullanılarak yazılır. Kartların düzeni, düzen kapsayıcıları ve temel düzen öğelerinden oluşan bir ağaç gibi oluşturulur. Her düzen öğesinin, çeşitli ayarlayıcı yöntemleriyle ayarlayabileceğiniz özellikleri vardır.

Temel düzen öğeleri

Materyal bileşenleri ile birlikte protolayout kitaplığındaki aşağıdaki görsel öğeler desteklenir:

  • Text: İsteğe bağlı olarak kaydırarak bir metin dizesi oluşturur.
  • Image: Bir resmi oluşturur.
  • Spacer: Öğeler arasında dolgu sağlar veya arka plan rengini ayarladığınızda bölücü görevi görebilir.

Material bileşenleri

protolayout-material kitaplığı, temel öğelere ek olarak Materyal Tasarım kullanıcı arayüzü önerilerine uygun bir kart tasarımı sağlayan bileşenler sağlar.

  • Button: Simge içerecek şekilde tasarlanmış tıklanabilir dairesel bileşen.
  • Chip: En fazla iki satır metin ve isteğe bağlı bir simge içerecek şekilde tasarlanmış, tıklanabilir stadyum şeklindeki bileşen.

  • CompactChip: Bir satır metin içerecek şekilde tasarlanmış, tıklanabilir stadyum şeklindeki bileşen.

  • TitleChip: Chip'a benzer ancak başlık metnini barındırmak için daha yüksek bir yüksekliğe sahip, tıklanabilir stadyum şeklindeki bileşen.

  • CircularProgressIndicator: Ekranda ilerleme durumunu göstermek için EdgeContentLayout içine yerleştirilebilen dairesel ilerleme durumu göstergesi.

Düzen kapsayıcıları

Materyal düzenleri ile birlikte aşağıdaki kapsayıcılar desteklenir:

  • Row: alt öğeleri ardışık olarak yatay olarak düzenler.
  • Column: Alt öğeleri dikey olarak arka arkaya yerleştirir.
  • Box: Alt öğeleri birbirinin üzerine yerleştirir.
  • Arc: alt öğeleri daire şeklinde düzenler.
  • Spannable: metin ve resimlerin aralıklı olarak yerleştirilmesiyle birlikte belirli FontStyles metin bölümlerine uygulanır. Daha fazla bilgi için Spannables başlıklı makaleyi inceleyin.

Her kapsayıcı, bir veya daha fazla alt öğe içerebilir. Bu alt öğeler de kapsayıcı olabilir. Örneğin, bir Column öğesi alt öğe olarak birden fazla Row öğesi içerebilir. Bu da ızgara benzeri bir düzen oluşturur.

Örneğin, kapsayıcı düzeni ve iki alt düzen öğesi içeren bir kart şu şekilde görünebilir:

Kotlin

private fun myLayout(): LayoutElement =
    Row.Builder()
        .setWidth(wrap())
        .setHeight(expand())
        .setVerticalAlignment(VALIGN_BOTTOM)
        .addContent(Text.Builder()
            .setText("Hello world")
            .build()
        )
        .addContent(Image.Builder()
            .setResourceId("image_id")
            .setWidth(dp(24f))
            .setHeight(dp(24f))
            .build()
        ).build()

Java

private LayoutElement myLayout() {
    return new Row.Builder()
        .setWidth(wrap())
        .setHeight(expand())
        .setVerticalAlignment(VALIGN_BOTTOM)
        .addContent(new Text.Builder()
            .setText("Hello world")
            .build()
        )
        .addContent(new Image.Builder()
            .setResourceId("image_id")
            .setWidth(dp(24f))
            .setHeight(dp(24f))
            .build()
        ).build();
}

Materyal düzenleri

protolayout-material kitaplığı, temel düzenlere ek olarak öğeleri belirli "yuvalar"da tutmak için tasarlanmış birkaç özel düzen de sunar.

  • PrimaryLayout: Tek bir birincil işlemi CompactChip alt tarafa, içeriği ise ortasına yerleştirir.

  • MultiSlotLayout: Birincil ve ikincil etiketleri, isteğe bağlı içerikle ortada ve isteğe bağlı bir CompactChip ile altta olacak şekilde konumlandırır.

  • MultiButtonLayout: Material yönergelerine göre düzenlenmiş bir dizi düğmeyi yerleştirir.

  • EdgeContentLayout: CircularProgressIndicator gibi içerikleri ekranın kenarına yerleştirir. Bu düzen kullanıldığında, içindeki içeriğe otomatik olarak uygun kenar boşlukları ve dolgu uygulanır.

Yaylar

Aşağıdaki Arc kapsayıcı çocukları desteklenir:

  • ArcLine: Eğri etrafında eğri bir çizgi oluşturur.
  • ArcText: Eğri metni Arc'te oluşturur.
  • ArcAdapter: yay üzerinde, yaya teğet çizilen temel bir düzen öğesi oluşturur.

Daha fazla bilgi için her bir öğe türünün referans dokümanlarına bakın.

Değiştiriciler

Mevcut her düzen öğesine isteğe bağlı olarak değiştiriciler uygulanabilir. Bu değiştiricileri aşağıdaki amaçlarla kullanın:

  • Düzenin görsel görünümünü değiştirebilirsiniz. Örneğin, düzen öğenize arka plan, kenar veya dolgu ekleyin.
  • Düzenle ilgili meta veriler ekleyin. Örneğin, ekran okuyucularla kullanmak için düzen öğenize bir anlam değiştirici ekleyin.
  • İşlev ekleyin. Örneğin, karonuzu etkileşimli hale getirmek için düzen öğenize tıklanabilir bir değiştirici ekleyin. Daha fazla bilgi için Kartlarla etkileşim kurma başlıklı makaleyi inceleyin.

Örneğin, aşağıdaki kod örneğinde gösterildiği gibi bir Image öğesinin varsayılan görünümünü ve meta verilerini özelleştirebiliriz:

Kotlin

private fun myImage(): LayoutElement =
    Image.Builder()
        .setWidth(dp(24f))
        .setHeight(dp(24f))
        .setResourceId("image_id")
        .setModifiers(Modifiers.Builder()
            .setBackground(Background.Builder().setColor(argb(0xFFFF0000)).build())
            .setPadding(Padding.Builder().setStart(dp(12f)).build())
            .setSemantics(Semantics.builder()
                .setContentDescription("Image description")
                .build()
            ).build()
        ).build()

Java

private LayoutElement myImage() {
   return new Image.Builder()
           .setWidth(dp(24f))
           .setHeight(dp(24f))
           .setResourceId("image_id")
           .setModifiers(new Modifiers.Builder()
                   .setBackground(new Background.Builder().setColor(argb(0xFFFF0000)).build())
                   .setPadding(new Padding.Builder().setStart(dp(12f)).build())
                   .setSemantics(new Semantics.Builder()
                           .setContentDescription("Image description")
                           .build()
                   ).build()
           ).build();
}

Genişleyen

Spannable, öğeleri metne benzer şekilde düzenleyen özel bir kapsayıcı türüdür. Bu, daha büyük bir metin bloğundaki yalnızca bir alt dizeye farklı bir stil uygulamak istediğinizde kullanışlıdır. Text öğesiyle bu mümkün değildir.

Spannable kapsayıcısı Span çocukla doldurulur. Diğer alt öğelere veya iç içe yerleştirilmiş Spannable örneklerine izin verilmez.

İki tür Span alt öğesi vardır:

  • SpanText: Metni belirli bir stille oluşturur.
  • SpanImage: Bir resmi metinle satır içi olarak oluşturur.

Örneğin, "Merhaba dünya" karosunda "dünya" kelimesini italik hale getirebilir ve kelimelerin arasına bir resim ekleyebilirsiniz. Aşağıdaki kod örneğinde gösterildiği gibi:

Kotlin

private fun mySpannable(): LayoutElement =
    Spannable.Builder()
        .addSpan(SpanText.Builder()
            .setText("Hello ")
            .build()
        )
        .addSpan(SpanImage.Builder()
            .setWidth(dp(24f))
            .setHeight(dp(24f))
            .setResourceId("image_id")
            .build()
        )
        .addSpan(SpanText.Builder()
            .setText("world")
            .setFontStyle(FontStyle.Builder()
                .setItalic(true)
                .build())
            .build()
        ).build()

Java

private LayoutElement mySpannable() {
   return new Spannable.Builder()
        .addSpan(new SpanText.Builder()
            .setText("Hello ")
            .build()
        )
        .addSpan(new SpanImage.Builder()
            .setWidth(dp(24f))
            .setHeight(dp(24f))
            .setResourceId("image_id")
            .build()
        )
        .addSpan(new SpanText.Builder()
            .setText("world")
            .setFontStyle(newFontStyle.Builder()
                .setItalic(true)
                .build())
            .build()
        ).build();
}

Kaynaklarla çalışma

Kartların uygulamanızın kaynaklarına erişimi yoktur. Yani bir Image düzen öğesine Android resim kimliği gönderip çözülmesini bekleyemezsiniz. Bunun yerine, onTileResourcesRequest() yöntemini geçersiz kılın ve tüm kaynakları manuel olarak sağlayın.

onTileResourcesRequest() yönteminde resim sağlamanın iki yolu vardır:

Kotlin

override fun onTileResourcesRequest(
    requestParams: ResourcesRequest
) = Futures.immediateFuture(
Resources.Builder()
    .setVersion("1")
    .addIdToImageMapping("image_from_resource", ImageResource.Builder()
        .setAndroidResourceByResId(AndroidImageResourceByResId.Builder()
            .setResourceId(R.drawable.image_id)
            .build()
        ).build()
    )
    .addIdToImageMapping("image_inline", ImageResource.Builder()
        .setInlineResource(InlineImageResource.Builder()
            .setData(imageAsByteArray)
            .setWidthPx(48)
            .setHeightPx(48)
            .setFormat(ResourceBuilders.IMAGE_FORMAT_RGB_565)
            .build()
        ).build()
    ).build()
)

Java

@Override
protected ListenableFuture<Resources> onTileResourcesRequest(
       @NonNull ResourcesRequest requestParams
) {
return Futures.immediateFuture(
    new Resources.Builder()
        .setVersion("1")
        .addIdToImageMapping("image_from_resource", new ImageResource.Builder()
            .setAndroidResourceByResId(new AndroidImageResourceByResId.Builder()
                .setResourceId(R.drawable.image_id)
                .build()
            ).build()
        )
        .addIdToImageMapping("image_inline", new ImageResource.Builder()
            .setInlineResource(new InlineImageResource.Builder()
                .setData(imageAsByteArray)
                .setWidthPx(48)
                .setHeightPx(48)
                .setFormat(ResourceBuilders.IMAGE_FORMAT_RGB_565)
                .build()
            ).build()
        ).build()
);
}