Kartları kullanmaya başlayın

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

Eski

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

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

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

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

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

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

Kotlin

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

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

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

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

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

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

Kart oluştur

Uygulamanızdan bir kutu sağlamak için TileService ve aşağıdaki kod örneğindeki 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()
       );
   }
}

Sonra, hizmet kodunuzun <application> etiketine bir hizmet ekleyin. AndroidManifest.xml dosya

<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 bir karo sağlayıcı olarak kaydeder.

Kartlar yapılandırıldığında simge, etiket ve açıklama kullanıcıya gösterilir tercih edebilir.

Düğmeyi yapılandırırken önizlemesini göstermek için önizleme meta veri etiketini kullanma telefonunuzda.

Kutu hizmeti yaşam döngüsüne genel bakış

Uygulama manifestinizde TileService oluşturup beyan ettikten sonra, kart hizmetinin durum değişikliklerine yanıt verebilir.

TileService bağlı bir hizmettir. Sonuç olarak TileService hesabınız bağlandı veya sistemin bununla iletişim kurması gerektiği konusunda stratejik davranmalısınız. Normal bound-hizmet yaşam döngüsü, aşağıdaki dört geri çağırma yöntemini içerir: onCreate(), onBind(), onUnbind() ve onDestroy(). Sistem her hizmet gerçekleştirdiğinde bu yöntemleri çağırır. yeni bir yaşam döngüsü aşamasına geçer.

Bağlı hizmet yaşam döngüsünü kontrol eden geri çağırmalara ek olarak şunları yapabilirsiniz: TileService yaşam döngüsüne özel diğer yöntemleri uygulayın. Tüm kutular Hizmetlerin onTileRequest() ve onTileResourcesRequest() uygulamalarını şu amaçla uygulaması gerekir: (sistem güncelleme isteklerine) yanıt vermek için de kullanılabilir.

  • onTileAddEvent(): Sistem bu yöntemi yalnızca kullanıcı ilk kez eklediğinde ve kullanıcı, yeniden tıklayın. Tek seferlik başlatma işlemi için en uygun zaman budur.

    onTileAddEvent(), yalnızca karo grubu yeniden yapılandırıldığında çağrılır. . Örneğin, cihaz yeniden başlatıldığında veya açılmışsa onTileAddEvent() kartlar için çağrılmaz . Şunu kullanabilirsiniz: getActiveTilesAsync() size ait kartların anlık görüntüsünü alabilirsiniz.

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

  • onTileEnterEvent(): Bir kutucuk olduğunda sistem bu yöntemi çağırır. ekranda gösterilir.

  • onTileLeaveEvent(): Bir kutucuk olduğunda sistem bu yöntemi çağırır. ekranda görünmediğinden emin olun.

  • onTileRequest(): Sistem, aşağıdaki işlemleri gerçekleştirdiğinde bu yöntemi çağırır: bu sağlayıcıdan yeni bir zaman çizelgesi istiyor.

  • onTileResourcesRequest(): sistem bu sağlayıcıdan bir kaynak paketi ister. Bu durum, şunlarla sonuçlanabilir: Kart yüklenirken veya kaynak sürümünde anlamına gelir.

ziyaret edin.

Etkin olan karoları sorgulama

Etkin kutular, kol saatinde gösterilmek üzere eklenen kartlardır. Tekliflerinizi otomatikleştirmek ve optimize etmek için Hangi karoları sorgulamak için TileService öğesinin getActiveTilesAsync() statik yöntemi uygulamanızın etkin olduğundan emin olun.

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

Karo düzeni, oluşturucu deseni kullanılarak yazılmıştır. Karo düzeni bir ağaç gibi yapılandırılmıştır. Bunlar, düzen kapsayıcıları ve temel düzenden oluşur. öğeler. Her düzen öğesinin çeşitli özellikleri vardır. Bunları belirleyici yöntemlerdir.

Temel düzen öğeleri

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

  • Text: oluşturur isteğe bağlı olarak sarmalanan bir metin dizesi ekleyin.
  • Image: bir resim oluşturur.
  • Spacer: öğeler arasında dolgu sağlar veya arka plan rengi.

Malzeme bileşenleri

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

  • Button: tıklanabilir bir simge içerecek şekilde tasarlanmış yuvarlak bileşen.
  • Chip: tıklanabilir stadyum şekilli bileşen iki satıra kadar metin ve bir isteğe bağlı simgesini.

  • CompactChip: bir metin satırı içerecek şekilde tasarlanmış stadyum şekilli tıklanabilir bileşen.

  • TitleChip: Chip benzeri, ancak daha büyük yüksekliğini ayarlayın.

  • CircularProgressIndicator: bir dairenin içine yerleştirilebilecek dairesel ilerleme göstergesi çizginin kenarlarındaki ilerlemeyi göstermek için EdgeContentLayout tıklayın.

Düzen kapsayıcıları

Material ile birlikte aşağıdaki kapsayıcılar desteklenir. düzenler:

  • Row: düzenler alt öğeleri yatay olarak yerleştirin.
  • Column: alt öğeleri dikey olarak üst üste yerleştirir.
  • Box: yer paylaşımları alt öğeleri birbirinin üstünde tutar.
  • Arc: düzenler alt öğelerin bir daire içinde görünmesini sağlar.
  • Spannable: belirli FontStyles eklenen metinler ve resimlerle birlikte metin bölümlerine ekleyin. Daha fazla Spannables konusuna bakın.

Her kapsayıcıda bir veya daha fazla alt öğe bulunabilir (bunlar kendileri de olabilir) container'lar. Örneğin, bir Column aşağıdaki gibi birden fazla Row öğesi içerebilir: Böylece ızgara benzeri bir düzen ortaya çıkar.

Örneğin, kapsayıcı düzeni içeren bir karo ve iki alt düzen öğesi şöyle 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ığında temel düzenlere ek olarak birkaç seçenek de sunulur. öğeleri belirli "alanlarda" tutmak için oluşturulan fikirli düzenler.

  • PrimaryLayout: en altta, tek bir birincil işlem CompactChip olarak konumlandırılır bir içeriği temsil eder.

  • MultiSlotLayout: ve arasında isteğe bağlı içeriğe sahip birincil ve ikincil etiketleri konumlandırır En altta isteğe bağlı olarak bir CompactChip ekleyin.

  • MultiButtonLayout: Malzeme'ye göre düzenlenmiş bir dizi düğme konumlandırır aykırıdır.

  • EdgeContentLayout: İçeriği ekranın kenarına yerleştirir (örneğin, CircularProgressIndicator. Bu düzeni kullanırken içindeki içerik uygun kenar boşlukları ve dolgu otomatik olarak uygulanır.

Yaylar

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

  • ArcLine: Yayın çevresinde eğri bir çizgi oluşturur.
  • ArcText: Yayında kavisli metin oluşturur.
  • ArcAdapter: yay içinde, yayına teğetle çizilmiş bir temel düzen öğesi oluşturur.
ziyaret edin.

Daha fazla bilgi için referans belgeleri onay kutusunu işaretleyin.

Değiştiriciler

Kullanılabilir her düzen öğesine isteğe bağlı olarak değiştiriciler uygulanabilir. Tekliflerinizi otomatikleştirmek ve optimize etmek için bu değiştiricileri şu amaçlarla kullanın:

  • Düzenin görsel görünümünü değiştirin. Örneğin, bir arka plan, kenarlığı veya dolgusu vardır.
  • Düzen hakkında meta veri ekleyin. Örneğin, anahtar/değer çiftlerine bir anlam değiştirici ekran okuyucularla kullanılan bir düzen öğesi seçin.
  • İşlevsellik ekleyin. Örneğin, düzeninize tıklanabilir bir değiştirici ekleyin etkileşimli bir görünüm elde edersiniz. Daha fazla bilgi için bkz. Kartlarla etkileşim kurun.

Örneğin, bir açılış sayfasının varsayılan görünümünü ve meta verilerini Gösterildiği şekliyle Image inceleyebilirsiniz:

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şletilebilir Öğeler

Spannable, öğeleri aşağıdakine benzer şekilde düzenleyen özel bir kapsayıcı türüdür: metin. Bu, yalnızca bir stile farklı bir stil uygulamak istediğinizde kullanışlıdır. büyük bir metin bloğunda alt dize olması, Text öğesi.

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

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

  • SpanText: belirli bir stile sahip metni oluşturur.
  • SpanImage: bir resmi metinle satır içi olarak oluşturur.

Örneğin, "world"ü italik yapabilirsiniz. "Merhaba dünya" Döşeyin ve resmi:

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ın, uygulamanızın hiçbir kaynağına erişimi yok. Bu, sizin için bir Image düzen öğesine Android resim kimliği iletilemiyor ve bundan çözer. Bunun yerine, onTileResourcesRequest() yöntemini kullanın ve kaynakları manuel olarak sağlayın.

onTileResourcesRequest() içinde resim sağlamanın iki yolu vardır yöntem:

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()
);
}
ziyaret edin.