टाइल का इस्तेमाल शुरू करना

अपने ऐप्लिकेशन से टाइल उपलब्ध कराने के लिए, अपने ऐप्लिकेशन की build.gradle फ़ाइल में ये डिपेंडेंसी शामिल करें.

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")
}

टाइल बनाना

अपने ऐप्लिकेशन से टाइल उपलब्ध कराने के लिए, ऐसी क्लास बनाएं जो TileService को एक्सटेंड करती हो और नीचे दिए गए कोड सैंपल में दिखाए गए तरीके से, तरीकों को लागू करती हो:

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

इसके बाद, अपनी AndroidManifest.xml फ़ाइल के <application> टैग में कोई सेवा जोड़ें.

<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>

अनुमति और इंटेंट फ़िल्टर, इस सेवा को टाइल उपलब्ध कराने वाली कंपनी के तौर पर रजिस्टर करते हैं.

जब उपयोगकर्ता अपने फ़ोन या स्मार्टवॉच पर टाइल कॉन्फ़िगर करते हैं, तब उन्हें आइकॉन, लेबल, और ब्यौरा दिखता है.

अपने फ़ोन पर टाइल को कॉन्फ़िगर करते समय, उसकी झलक दिखाने के लिए झलक वाले मेटाडेटा टैग का इस्तेमाल करें.

टाइल सेवा के लाइफ़साइकल के बारे में खास जानकारी

अपने ऐप्लिकेशन मेनिफ़ेस्ट में TileService बनाने और उसके बारे में बताने के बाद, टाइल सेवा की स्थिति में हुए बदलावों का जवाब दिया जा सकता है.

TileService एक बाउंड सेवा है. आपका TileService, आपके ऐप्लिकेशन के अनुरोध के नतीजे के तौर पर या सिस्टम को उससे संपर्क करने की ज़रूरत पड़ने पर बाउंड होता है. आम तौर पर, बाउंड-सेवा के लाइफ़साइकल में ये चार कॉलबैक तरीके होते हैं: onCreate(), onBind(), onUnbind(), और onDestroy(). जब भी सेवा, लाइफ़साइकल के किसी नए चरण में प्रवेश करती है, तो सिस्टम इन तरीकों को लागू करता है.

बाउंड की गई सेवा के लाइफ़साइकल को कंट्रोल करने वाले कॉलबैक के अलावा, TileService लाइफ़साइकल के लिए खास तौर पर बनाए गए अन्य तरीके भी लागू किए जा सकते हैं. सिस्टम से अपडेट के अनुरोधों का जवाब देने के लिए, सभी टाइल सेवाओं को onTileRequest() और onTileResourcesRequest() को लागू करना ज़रूरी है.

  • onTileAddEvent(): सिस्टम इस तरीके को सिर्फ़ तब कॉल करता है, जब उपयोगकर्ता पहली बार आपकी टाइल जोड़ता है. साथ ही, अगर उपयोगकर्ता आपकी टाइल को हटाकर फिर से जोड़ता है, तो भी सिस्टम इस तरीके को कॉल करता है. एक बार होने वाले किसी भी इनिशिएलाइज़ेशन के लिए, यह सबसे सही समय है.

    onTileAddEvent() को सिर्फ़ तब कॉल किया जाता है, जब टाइल के सेट को फिर से कॉन्फ़िगर किया जाता है, न कि जब सिस्टम किसी टाइल को बनाता है. उदाहरण के लिए, जब डिवाइस को रीबूट किया जाता है या चालू किया जाता है, तो पहले से जोड़ी गई टाइल के लिए onTileAddEvent() को कॉल नहीं किया जाता. इसके बजाय, getActiveTilesAsync() का इस्तेमाल करके, यह पता लगाया जा सकता है कि आपके पास कौनसी टाइल चालू हैं.

  • onTileRemoveEvent(): सिस्टम इस तरीके को सिर्फ़ तब कॉल करता है, जब उपयोगकर्ता आपकी टाइल को हटाता है.

  • onTileEnterEvent(): सिस्टम इस तरीके को तब कॉल करता है, जब स्क्रीन पर इस सेवा देने वाली कंपनी की टाइल दिखती है.

  • onTileLeaveEvent(): सिस्टम इस तरीके को तब कॉल करता है, जब इस सेवा देने वाली कंपनी की दी गई टाइल, स्क्रीन पर दिखना बंद हो जाती है.

  • onTileRequest(): सिस्टम इस प्रोवाइडर से नई टाइमलाइन का अनुरोध करने पर, इस तरीके को कॉल करता है.

  • onTileResourcesRequest(): सिस्टम इस तरीके को तब कॉल करता है, जब वह इस सेवा देने वाली कंपनी से संसाधन बंडल का अनुरोध करता है. ऐसा तब हो सकता है, जब पहली बार कोई टाइल लोड की जा रही हो या रिसॉर्स का वर्शन बदला गया हो.

यह क्वेरी करना कि कौनसी टाइल चालू हैं

ऐक्टिव टाइल, वे टाइल होती हैं जिन्हें स्मार्टवॉच पर दिखाने के लिए जोड़ा गया है. TileService के स्टैटिक तरीके getActiveTilesAsync() का इस्तेमाल करके, यह पता लगाएं कि आपके ऐप्लिकेशन से जुड़ी कौनसी टाइल चालू हैं.

टाइल के लिए यूज़र इंटरफ़ेस (यूआई) बनाना

टाइल का लेआउट, बिल्डर पैटर्न का इस्तेमाल करके लिखा जाता है. टाइल का लेआउट, ट्री की तरह बनाया जाता है. इसमें लेआउट कंटेनर और बुनियादी लेआउट एलिमेंट होते हैं. हर लेआउट एलिमेंट में प्रॉपर्टी होती हैं, जिन्हें सेट करने के लिए अलग-अलग तरीकों का इस्तेमाल किया जा सकता है.

लेआउट के बुनियादी एलिमेंट

मटीरियल कॉम्पोनेंट के साथ-साथ, protolayout लाइब्रेरी के इन विज़ुअल एलिमेंट का इस्तेमाल किया जा सकता है:

  • Text: टेक्स्ट की स्ट्रिंग को रेंडर करता है. साथ ही, ज़रूरत पड़ने पर उसे रैप भी करता है.
  • Image: इमेज को रेंडर करता है.
  • Spacer: इससे एलिमेंट के बीच पैडिंग मिलती है. इसके अलावा, बैकग्राउंड का रंग सेट करने पर, यह डिवाइडर के तौर पर भी काम कर सकता है.

मटीरियल कॉम्पोनेंट

बुनियादी एलिमेंट के अलावा, protolayout-material लाइब्रेरी में ऐसे कॉम्पोनेंट भी होते हैं जिनसे यह पक्का होता है कि टाइल का डिज़ाइन, Material Design यूज़र इंटरफ़ेस के सुझावों के मुताबिक हो.

  • Button: क्लिक किया जा सकने वाला, आइकॉन के लिए डिज़ाइन किया गया सर्कुलर कॉम्पोनेंट.
  • Chip: क्लिक किए जा सकने वाला, स्टेडियम के आकार का कॉम्पोनेंट. इसमें दो लाइन तक टेक्स्ट और एक आइकॉन (ज़रूरी नहीं) शामिल किया जा सकता है.

  • CompactChip: स्टेडियम के आकार का क्लिक किया जा सकने वाला कॉम्पोनेंट, जिसे टेक्स्ट की एक लाइन के लिए डिज़ाइन किया गया है.

  • TitleChip: Chip की तरह ही, स्टेडियम के आकार का क्लिक किया जा सकने वाला कॉम्पोनेंट. हालांकि, इसमें टाइटल टेक्स्ट के लिए ज़्यादा जगह होती है.

  • CircularProgressIndicator: गतिविधि की स्थिति सर्कुलर फ़ॉर्मैट में दिखाने वाला इंडिकेटर. इसे EdgeContentLayout के अंदर रखा जा सकता है, ताकि स्क्रीन के किनारों पर प्रोग्रेस दिखे.

लेआउट कंटेनर

Material लेआउट के साथ-साथ, ये कंटेनर भी काम करते हैं:

  • Row: चाइल्ड एलिमेंट को एक के बाद एक, हॉरिज़ॉन्टल तौर पर दिखाता है.
  • Column: चाइल्ड एलिमेंट को एक के बाद एक वर्टिकल तौर पर दिखाता है.
  • Box: एक-दूसरे के ऊपर, चाइल्ड एलिमेंट को ओवरले करता है.
  • Arc: चाइल्ड एलिमेंट को सर्कल में दिखाता है.
  • Spannable: टेक्स्ट और इमेज को इंटरवेल करने के साथ-साथ, टेक्स्ट के सेक्शन पर खास FontStyles लागू करता है. ज़्यादा जानकारी के लिए, Spannable देखें.

हर कंटेनर में एक या उससे ज़्यादा चाइल्ड कंटेनर हो सकते हैं. ये चाइल्ड कंटेनर भी कंटेनर हो सकते हैं. उदाहरण के लिए, किसी Column में कई Row एलिमेंट, चाइल्ड के तौर पर हो सकते हैं. इससे ग्रिड जैसा लेआउट बनता है.

उदाहरण के लिए, कंटेनर लेआउट और दो चाइल्ड लेआउट एलिमेंट वाली टाइल कुछ इस तरह दिख सकती है:

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

मटीरियल लेआउट

बुनियादी लेआउट के अलावा, protolayout-material लाइब्रेरी में कुछ ऐसे लेआउट भी होते हैं जिनमें एलिमेंट को खास "स्लॉट" में रखा जाता है.

  • PrimaryLayout: यह एक प्राइमरी ऐक्शन CompactChip को सबसे नीचे रखता है और उसके ऊपर कॉन्टेंट को बीच में दिखाता है.

  • MultiSlotLayout: इसमें प्राइमरी और सेकंडरी लेबल के बीच वैकल्पिक कॉन्टेंट और सबसे नीचे वैकल्पिक CompactChip होता है.

  • MultiButtonLayout: Material के दिशा-निर्देशों के मुताबिक व्यवस्थित किए गए बटनों का एक सेट दिखाता है.

  • EdgeContentLayout: इसका इस्तेमाल करके, कॉन्टेंट को स्क्रीन के किनारे पर रखा जा सकता है, जैसे कि CircularProgressIndicator. इस लेआउट का इस्तेमाल करने पर, उसमें मौजूद कॉन्टेंट के लिए मार्जिन और पैडिंग अपने-आप लागू हो जाती है.

आर्क

Arc कंटेनर के ये चाइल्ड कंटेनर इस्तेमाल किए जा सकते हैं:

  • ArcLine: ऐर्क के चारों ओर एक घुमावदार लाइन रेंडर करता है.
  • ArcText: ऐर्क में टेक्स्ट को घुमाकर रेंडर करता है.
  • ArcAdapter: आर्क में एक बुनियादी लेआउट एलिमेंट रेंडर करता है, जो आर्क के स्पर्शरेखा पर खींचा जाता है.

ज़्यादा जानकारी के लिए, हर एलिमेंट टाइप के लिए रेफ़रंस दस्तावेज़ देखें.

मॉडिफ़ायर

हर उपलब्ध लेआउट एलिमेंट में, वैकल्पिक तौर पर मॉडिफ़ायर लागू किए जा सकते हैं. इन बदलाव करने वाले निर्देशों का इस्तेमाल इन कामों के लिए करें:

  • लेआउट के विज़ुअल लुक को बदलें. उदाहरण के लिए, अपने लेआउट एलिमेंट में बैकग्राउंड, बॉर्डर या पैडिंग जोड़ें.
  • लेआउट के बारे में मेटाडेटा जोड़ें. उदाहरण के लिए, स्क्रीन रीडर के साथ इस्तेमाल करने के लिए, अपने लेआउट एलिमेंट में सेमेटिक्स मॉडिफ़ायर जोड़ें.
  • फ़ंक्शन जोड़ें. उदाहरण के लिए, अपनी टाइल को इंटरैक्टिव बनाने के लिए, अपने लेआउट एलिमेंट में क्लिक किए जा सकने वाले मॉडिफ़ायर जोड़ें. ज़्यादा जानकारी के लिए, टाइल के साथ इंटरैक्ट करना लेख पढ़ें.

उदाहरण के लिए, हम किसी Image के डिफ़ॉल्ट लुक और मेटाडेटा को पसंद के मुताबिक बना सकते हैं. इस बारे में, नीचे दिए गए कोड सैंपल में बताया गया है:

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

स्पैन किए जा सकने वाले एलिमेंट

Spannable एक खास तरह का कंटेनर है, जो एलिमेंट को टेक्स्ट की तरह ही दिखाता है. यह तब काम आता है, जब आपको टेक्स्ट के बड़े ब्लॉक में सिर्फ़ एक सबस्ट्रिंग पर अलग स्टाइल लागू करना हो. ऐसा Text एलिमेंट की मदद से नहीं किया जा सकता.

Spannable कंटेनर में Span बच्चे हैं. अन्य चाइल्ड या नेस्ट किए गए Spannable इंस्टेंस की अनुमति नहीं है.

Span के बच्चे दो तरह के होते हैं:

  • SpanText: यह टेक्स्ट को किसी खास स्टाइल में रेंडर करता है.
  • SpanImage: टेक्स्ट के साथ-साथ इमेज को रेंडर करता है.

उदाहरण के लिए, "Hello world" टाइल में "world" को इटैलिक में लिखा जा सकता है और शब्दों के बीच इमेज डाली जा सकती है, जैसा कि यहां दिए गए कोड सैंपल में दिखाया गया है:

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

संसाधनों के साथ काम करना

टाइल के पास आपके ऐप्लिकेशन के किसी भी संसाधन का ऐक्सेस नहीं होता. इसका मतलब है कि Image लेआउट एलिमेंट में Android इमेज आईडी पास करने पर, उसे ठीक नहीं किया जा सकता. इसके बजाय, onTileResourcesRequest() के तरीके को बदलें और मैन्युअल तरीके से रिसॉर्स दें.

onTileResourcesRequest() तरीके में इमेज देने के दो तरीके हैं:

  • setAndroidResourceByResId() का इस्तेमाल करके, ड्रॉ किया जा सकने वाला रिसॉर्स दें.
  • setInlineResource() का इस्तेमाल करके, ByteArray के तौर पर डाइनैमिक इमेज दें.

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