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.

Modern

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

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

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

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

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

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

Kotlin

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

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

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

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

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

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

Kart oluştur

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

Kotlin

// Uses the ProtoLayout namespace for tile timeline objects.
// If you haven't done so already, migrate to the ProtoLayout namespace.
import androidx.wear.protolayout.TimelineBuilders.Timeline
import androidx.wear.protolayout.material.Text
import androidx.wear.tiles.TileBuilders.Tile

private val RESOURCES_VERSION = "1"
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_DISPLAY1)
                        .setColor(argb(0xFF000000.toInt()))
                        .build()))
            .build())

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

Java

// Uses the ProtoLayout namespace for tile timeline objects.
// If you haven't done so already, migrate to the ProtoLayout namespace.
import androidx.wear.protolayout.TimelineBuilders.Timeline;
import androidx.wear.protolayout.material.Text;
import androidx.wear.tiles.TileBuilders.Tile;

public class MyTileService extends TileService {
    private static final String RESOURCES_VERSION = "1";

    @NonNull
    @Override
    protected ListenableFuture<Tile> onTileRequest(
        @NonNull TileRequest requestParams
    ) {
        return Futures.immediateFuture(new Tile.Builder()
            .setResourcesVersion(RESOURCES_VERSION)
            .setTileTimeline(
                Timeline.fromLayoutElement(
                    new Text.Builder(this, "Hello world!")
                        .setTypography(Typography.TYPOGRAPHY_DISPLAY1)
                        .setColor(ColorBuilders.argb(0xFF000000))
                        .build()))
            .build()
        );
   }

   @NonNull
   @Override
   protected ListenableFuture<Resources> onTileResourcesRequest(
       @NonNull ResourcesRequest requestParams
   ) {
       return Futures.immediateFuture(new Resources.Builder()
               .setVersion(RESOURCES_VERSION)
               .build()
       );
   }
}

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

<service
   android:name=".MyTileService"
   android:label="@string/tile_label"
   android:description="@string/tile_description"
   android:icon="@drawable/tile_icon_round"
   android:roundIcon="@drawable/tile_icon_round"
   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 kutu sağlayıcı olarak kaydeder.

Kullanıcı, telefonunda veya kol saatinde kartları yapılandırdığında simge, etiket ve açıklama gösterilir.

Karonu telefonunuzda yapılandırırken önizlemesini göstermek için önizleme meta veri etiketini kullanın.

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

Uygulama manifestinizde TileService oluşturup beyan ettikten sonra parça hizmetinin durum değişikliklerine yanıt verebilirsiniz.

TileService bağlı bir hizmettir. Uygulama isteğinizin sonucu veya sistemin sizinle iletişim kurması gerektiğinde TileService ürününüz bağlanır. Tipik bir bağlı hizmet yaşam döngüsü şu dört geri çağırma yöntemini içerir: onCreate(), onBind(), onUnbind() ve onDestroy(). Hizmet yeni bir yaşam döngüsü aşamasına her girdiğinde sistem bu yöntemleri çağırır.

Bağlı hizmetin yaşam döngüsünü kontrol eden geri çağırmalara ek olarak, TileService yaşam döngüsüne özel başka yöntemler de uygulayabilirsiniz. Tüm parça hizmetleri, sistemden gelen güncelleme isteklerine yanıt vermek için onTileRequest() ve onTileResourcesRequest() değerlerini uygulamalıdır.

  • onTileAddEvent(): Sistem bu yöntemi yalnızca kullanıcı karonuzu ilk kez eklediğinde ve karonuzu kaldırıp tekrar eklediğinde çağırır. Bu, tek seferlik başlatma yapmak için en iyi zamandır.

    onTileAddEvent(), yalnızca blok grubu yeniden yapılandırıldığında çağrılır, sistem tarafından bir kutu oluşturulduğunda çağrılmaz. Örneğin, cihaz yeniden başlatıldığında veya açıldığında, önceden eklenmiş olan kartlar için onTileAddEvent() çağrılmaz. Size ait hangi kutuların etkin olduğuna dair anlık görüntü almak yerine getActiveTilesAsync() öğesini kullanabilirsiniz.

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

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

  • onTileLeaveEvent(): Bu sağlayıcı tarafından sağlanan bir kutu ekranın dışına çıktığında sistem bu yöntemi çağırır.

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

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

Hangi kartların etkin olduğunu sorgulama

Etkin kutular, kol saatinde gösterilmek üzere eklenen kutulardır. Uygulamanıza ait hangi kartların etkin olduğunu sorgulamak için TileService uygulamasının getActiveTilesAsync() statik yöntemini kullanın.

Karolar için kullanıcı arayüzü oluştur

Karo düzeni, oluşturucu deseni kullanılarak yazılır. Karonun 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 belirleyici yöntemlerle 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 sarmalayarak bir metin dizesi oluşturur.
  • Image: Bir resim oluşturur.
  • Spacer: Öğeler arasında dolgu sağlar veya arka plan rengini ayarladığınızda ayırıcı görevi görebilir.

Malzeme bileşenleri

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

  • Button: Bir 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ış stadyum şeklindeki tıklanabilir bileşen.

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

  • TitleChip: Chip simgesine benzeyen ancak başlık metnine yerleştirilecek daha büyük bir yüksekliğe sahip olan tıklanabilir stadyum şeklindeki bileşen.

  • CircularProgressIndicator: Ekranın kenarları boyunca ilerleme durumunu görüntülemek için EdgeContentLayout içine yerleştirilebilen dairesel ilerleme göstergesi.

Düzen kapsayıcıları

Materyal düzenler ile birlikte aşağıdaki container'lar desteklenir:

  • Row: Alt öğeleri yatay olarak, art arda yerleştirir.
  • Column: Alt öğeleri dikey olarak, art arda yerleştirir.
  • Box: Alt öğeleri üst üste yerleştirir.
  • Arc: Alt öğeleri bir daire içine yerleştirir.
  • Spannable: Metin bölümlerine, araya eklenen metin ve resimlerle birlikte belirli FontStyles uygular. Daha fazla bilgi için Spannables konusuna bakın.

Her container, bir veya daha fazla alt öğe içerebilir. Bu alt öğeler aynı zamanda container olabilir. Örneğin, bir Column alt öğe olarak birden çok Row öğesi içerebilir. Bu da ızgara benzeri bir düzen elde edilmesini sağlar.

Örneğin, kapsayıcı düzeni ve iki alt düzen öğesi olan bir blok ş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 "slotlarda" tutmak için tasarlanmış, üzerinde düşünülmüş birkaç düzen sağlar.

  • PrimaryLayout: İçerik, üstünde ortalanmış şekilde tek bir birincil işlemi CompactChip en altta olacak şekilde konumlandırır.

  • MultiSlotLayout: Birincil ve ikincil etiketleri, aralarında isteğe bağlı içerik ve en altta isteğe bağlı CompactChip olacak şekilde yerleştirir.

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

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

Yaylar

Aşağıdaki Arc kapsayıcı alt öğeleri desteklenir:

  • ArcLine: Yar etrafında eğri bir çizgi oluşturur.
  • ArcText: Yar alanında eğri metin oluşturur.
  • ArcAdapter: Yark içinde, yayına teğetle çizilmiş bir temel düzen öğesi oluşturur.

Daha fazla bilgi için her öğe türünün referans belgelerine bakın.

Değiştiriciler

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

  • Düzenin görünümünü değiştirin. Örneğin, düzen öğenize arka plan, kenarlık veya dolgu ekleyin.
  • Düzen hakkında meta veri ekleyin. Örneğin, ekran okuyucularla kullanmak için düzen öğenize bir anlam değiştiricisi ekleyin.
  • İşlevsellik 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 bölümüne bakın.

Ö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();
}

Ulaşılabilir Öğeler

Spannable, öğeleri metne benzer şekilde düzenleyen özel bir kapsayıcı türüdür. Bu, daha büyük bir metin bloğunda yalnızca bir alt dizeye farklı bir stil uygulamak istediğinizde, Text öğesiyle mümkün olmayan bir şey olduğunda faydalıdır.

Bir Spannable kapsayıcısı, Span alt öğeleriyle 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: Metinle birlikte satır içi bir resim oluşturur.

Örneğin, aşağıdaki kod örneğinde gösterildiği gibi, "Merhaba dünya" parçasında "dünya" kelimesini italik yapabilir ve kelimelerin arasına bir resim ekleyebilirsiniz:

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

Kutular, uygulamanızın hiçbir kaynağına erişemez. Bu, Android resim kimliğini Image düzen öğesine geçiremeyeceğiniz ve çözümlenmesini bekleyemeyeceğiniz anlamına gelir. Bunun yerine onTileResourcesRequest() yöntemini geçersiz kılın ve kaynakları manuel olarak sağlayın.

onTileResourcesRequest() yönteminde görüntü 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()
);
}