إنشاء واجهات للساعات WearOS - الجزء الثاني

إنشاء واجهات Watch Face لساعات WearOS بإستخدام Watch Face Format (WFF)

AbdulAlim Rajjoubمنذ يوم

سنستكمل في هذا الجزء شرح عن WFF لإنشاء واجهات Watch Face للساعات Wear OS.

سنشرح بعض العناصر في WFF 

 

OutGlow

تقوم بإضافة توهج خارجي للنص

    <PartText
         x="0"
         y="0"
         width="450"
         height="450">

         <Text >
             <Font family="rubik" size="30" color="#ffffffff">
                 <OutGlow  color="#ff0000" radius="2">
                     Hello 3alam Pro!
                 </OutGlow>
             </Font>
         </Text>

     </PartText>

بهذا الشكل

 

Outline

تقوم بإضافة خط خارجي "Stroke" 

<PartText
            height="450"
            width="450"
            x="0"
            y="0">

            <Text>
                <Font
                    color="#ffffffff"
                    family="rubik"
                    size="30">
                    <Outline
                        color="#ff0000"
                        width="float">
                        Hello 3alam Pro!
                    </Outline>
                </Font>
            </Text>

        </PartText>

 

Upper و Lower

تقوم بتحويل النص الى Uppercase و Lowercase

في هذا المثال قد لا يكون لها استخدام كبير, ولكن يمكنك تخيل استخدامها عند التعامل مع التطبيقات الأخرى او "Complications" التي توفر بيانات معينة مثل الطقس, البطارية, أوقات الصلاة وغيرها.

   <PartText
            height="450"
            width="450"
            x="0"
            y="0">

            <Text>
                <Font
                    color="#ffffffff"
                    family="rubik"
                    size="30">
                    <Upper>
                        Hello 3alam Pro!
                    </Upper>
                </Font>
            </Text>

        </PartText>

 

   <PartText
            height="450"
            width="450"
            x="0"
            y="0">

            <Text>
                <Font
                    color="#ffffffff"
                    family="rubik"
                    size="30">
                    <Lower>
                        Hello 3alam Pro!
                    </Lower>
                </Font>
            </Text>

        </PartText>

 

 

 

سنشرح الآن عن بعض العناصر الرسومية PartDraw

مثال

<PartDraw x="integer" y="integer" width="integer" height="integer"
           name="string" angle="float-degrees" pivotX="float" pivotY="float"
           alpha="integer"
           renderMode="[SOURCE | MASK | ALL]" 
           tintColor="argb-color | rgb-color">
    <!-- Only the most common inner element is shown here. -->
    <Line />
    ...
</PartDraw>

 

Line

     <PartDraw

            height="450"
            width="450"
            x="0"
            y="0">

            <Line startX="100" startY="100" endX="200" endY="200" >
                <Stroke
                    color="#ffffff"
                    thickness="3" />
            </Line>

        </PartDraw>

حيث أنه يمكننا وضع Stroke أو WeightedStroke

 

Rectangle

تستخدم لرسم مستطيل 

يمكننا استخدام Fill لتعبئة المستطيل

   <PartDraw

            height="450"
            width="450"
            x="0"
            y="0">

            <Rectangle
                height="100"
                width="100"
                x="200"
                y="100">

                <Fill color="#ff0000"/>
        </Rectangle>

    </PartDraw>

 

أو يمكننا إستخدام Stroke لرسم مستطيل Outlined بدون تعبئة

 

     <PartDraw

            height="450"
            width="450"
            x="0"
            y="0">

            <Line startX="100" startY="100" endX="200" endY="200" >
                <Stroke
                    color="#ffffff"
                    thickness="3" />
            </Line>

        </PartDraw>

 

RoundRectangle

يستخدم لرسم مستطيل بحواف مدورة

  <PartDraw

            height="450"
            width="450"
            x="0"
            y="0">

            <RoundRectangle
                height="100"
                width="100"
                x="200"
                y="100" cornerRadiusX="5" cornerRadiusY="5">

<!--                <Fill color="#ff0000" />-->
                <Stroke color="#ff0000" thickness="3"/>
        </RoundRectangle>

    </PartDraw>

 

يمكننا إستخدام Stroke or Fill

 

Ellipse

تستخدم لرسم دائرة

    <PartDraw

            height="450"
            width="450"
            x="0"
            y="0">

            <Ellipse
                height="100"
                width="100"
                x="200"
                y="100">

                <Fill color="#ff0000" />
<!--                <Stroke color="#ff0000" thickness="3"/>-->
        </Ellipse>

    </PartDraw>

 

Arc

يمكنك استخدامها لرسم خط منحني , شخصياً قمت باستخدامها لرسم Progress Bar لموعد الصلاة القادم.

 

    <PartDraw

            height="450"
            width="450"
            x="0"
            y="0">

            <Arc
                centerX="225"
                centerY="225"
                endAngle="180"
                height="100"
                startAngle="0"
                width="100">
                <Stroke
                    color="#ffffffff"
                    thickness="3" />
            </Arc>

        </PartDraw>

 

 

PartImage

تستخدم لعرض صورة / صور 
 

   <PartImage
            height="450"
            width="450"
            x="0"
            y="0">

            <Image resource="wallpaper_4" />

        </PartImage>

 

يجب العلم أنه يجب وضع الصورة داخل res/drawable

 

 

Paremeter & Expressions

تستخدم لعرض بيانات معينة الذي يقدمها النظام كإسم اليوم الحالي, التاريخ الحالي, نسبة البطارية, نبضات القلب وغيرها , بالإضافة الى بعض التطبيقات الأخرى ك Complications

 

 

 <PartText
            height="100"
            width="450"
            x="100"
            y="100">

            <Text>
                <Font
                    color="#FFFFFF"
                    family="rubik"
                    size="30">
                <Template>%s
                    <Parameter expression="[DAY_OF_WEEK_S]" />
                </Template>
                </Font>
            </Text>
        </PartText>
        <PartText
            height="100"
            width="450"
            x="100"
            y="200">

            <Text>
                <Font
                    color="#FFFFFF"
                    family="rubik"
                    size="30">
                    <Template>%s
                        <Parameter expression="[BATTERY_PERCENT]" />
                    </Template>
                </Font>
            </Text>

        </PartText>

 

في هذا المثال قمنا بوضع نصين, الأول لعرض إسم اليوم الحالي DAY_OF_WEEK_S

والآخر لعرض نسبة البطارية الحالية BATTERY_PERCENT

يمكنك رؤية Providers الموجودة في  الرابط

 

بعد أن تعرفنا على "معظم" العناصر الموجودة في WFF سنقوم الآن بإضافة بعض التخصيصات بالنسبة للمستخدم, مثل تغيير اللون, الخلفية وغيره.

سيستطيع المستخدم تغيير هذه الإعدادات من خلال الساعة نفسها (من خلال الضغط المطول على الواجهة) ثم اختيار تخصيص او Customize 

أو من خلال تطبيق الساعة على الهاتف مثل Galaxy Wearable

 

سنقوم بإضافة Toggle بسيط لإظهار او إخفاء نسبة البطارية

يجب علينا أولاً تعريف UserConfigurations والتي ستحتوي على كل  الإعدادات التي سنستخدمها سواءً Boolean,Color,List, الخ..

 

BooleanConfiguration

<UserConfigurations>
        <BooleanConfiguration
            defaultValue="FALSE"
            displayName="show_battery_percentage"
            id="show_battery"
            />
    </UserConfigurations>

 

وضعنا القيمة الإفتراضية FALSE

إسم العرض الذي سيظهر في الإعدادات , علماً أنه يجب وضع اسم key داخل strings.xml ك displayName

و ID 

حيث أن UserConfigurations سيكون خارج <Scene>

 

<WatchFace
    height="450"
    width="450">
    <Metadata
        key="CLOCK_TYPE"
        value="DIGITAL" />

    <UserConfigurations>
        <BooleanConfiguration
            defaultValue="FALSE"
            displayName="show_battery_percentage"
            id="show_battery"
            />
    </UserConfigurations>


    <Scene>

        <PartText
            height="100"
            width="450"
            x="100"
            y="100">

            <Text>
                <Font
                    color="#FFFFFF"
                    family="rubik"
                    size="30">
                <Template>%s
                    <Parameter expression="[DAY_OF_WEEK_S]" />
                </Template>
                </Font>
            </Text>
        </PartText>
        <PartText
            height="100"
            width="450"
            x="100"
            y="200">

            <Text>
                <Font
                    color="#FFFFFF"
                    family="rubik"
                    size="30">
                    <Template>%s
                        <Parameter expression="[BATTERY_PERCENT]" />
                    </Template>
                </Font>
            </Text>

        </PartText>
    </Scene>
</WatchFace>

 

ملاحظة: يجب التأكد من أن خيار 

<Editable value="true" />

موجود داخل xml/watch_face_info.xml

نقوم بتشغيل التطبيق لنرى الخيار

 

الآن سنقوم بوضع الكود اللازم للتحقق من حالة هذا الإعداد, وبناء عليه سنضيف خيار البطارية 


        <BooleanConfiguration id="show_battery">
            <BooleanOption id="TRUE">

                <PartText
                    height="100"
                    width="450"
                    x="100"
                    y="200">

                    <Text>
                        <Font
                            color="#FFFFFF"
                            family="rubik"
                            size="30">
                            <Template>%s
                                <Parameter expression="[BATTERY_PERCENT]" />
                            </Template>
                        </Font>
                    </Text>

                </PartText>
            </BooleanOption>
        </BooleanConfiguration>

 

عند استخدام Configuration  معين فإنه يجب علينا وضع BooleanConfiguration مع ID الخاص به

وثم تحديد القيمة التي نريد العمل عليه, مثلاً في حالة TRUE , سنقوم بوضع الPartText  

ونفس الفكرة يمكن تطبيقها في حال كان الخيار غير مفعل FALSE

نقوم بتشغيل التطبيق

 

 

ColorConfiguration 

سنقوم بوضع خيار للمستخدم لتغيير لون الخط عبر ColorConfiguration

 

<ColorConfiguration
            defaultValue="0"
            displayName="font_color"
            id="font_color">
            <ColorOption
                id="0"
                colors="#FFFFFF"
                displayName="white"/>
            <ColorOption
                id="1"
                colors="#FF0000"
                displayName="red"/>
            <ColorOption
                id="2"
                colors="#00FF00"
                displayName="green"/>
            <ColorOption
                id="3"
                colors="#0000FF"
                displayName="blue"/>
        </ColorConfiguration>

 

قمنا بوضع ColorConfiguration مع id الخاص ب defaultValue

وداخله الألوان الذي نريد إضافتها "ColorOption"

يمكننا استخدام عدة ألوان داخل colors  لتعمل ك theme ونفصل بينهم بمسافة, ولكن لتبسيط الشرح وضعنا كل لون كخيار منفصل

سنقوم الآن بتغيير ألوان النصوص على حسب خيار المستخدم

 

  <PartText
            height="100"
            width="450"
            x="100"
            y="100">

            <Text>
                <Font
                    color="[CONFIGURATION.font_color]"
                    family="rubik"
                    size="30">
                    <Template>%s
                        <Parameter expression="[DAY_OF_WEEK_S]" />
                    </Template>
                </Font>
            </Text>
        </PartText>

 

قمنا فقط بتغيير اللون من الأبيض "#ffffff" الى CONFIGURATION.font_color

ليصبح الملف كاملاً 

<WatchFace
    height="450"
    width="450">
    <Metadata
        key="CLOCK_TYPE"
        value="DIGITAL" />

    <UserConfigurations>
        <BooleanConfiguration
            defaultValue="FALSE"
            displayName="show_battery_percentage"
            id="show_battery" />

        <ColorConfiguration
            defaultValue="0"
            displayName="font_color"
            id="font_color">
            <ColorOption
                id="0"
                colors="#FFFFFF"
                displayName="white"/>
            <ColorOption
                id="1"
                colors="#FF0000"
                displayName="red"/>
            <ColorOption
                id="2"
                colors="#00FF00"
                displayName="green"/>
            <ColorOption
                id="3"
                colors="#0000FF"
                displayName="blue"/>
        </ColorConfiguration>
    </UserConfigurations>


    <Scene>

        <PartText
            height="100"
            width="450"
            x="100"
            y="100">

            <Text>
                <Font
                    color="[CONFIGURATION.font_color]"
                    family="rubik"
                    size="30">
                    <Template>%s
                        <Parameter expression="[DAY_OF_WEEK_S]" />
                    </Template>
                </Font>
            </Text>
        </PartText>

        <BooleanConfiguration id="show_battery">
            <BooleanOption id="TRUE">

                <PartText
                    height="100"
                    width="450"
                    x="100"
                    y="200">

                    <Text>
                        <Font
                            color="[CONFIGURATION.font_color]"
                            family="rubik"
                            size="30">
                            <Template>%s
                                <Parameter expression="[BATTERY_PERCENT]" />
                            </Template>
                        </Font>
                    </Text>

                </PartText>
            </BooleanOption>
        </BooleanConfiguration>

    </Scene>
</WatchFace>

 

 نقوم بتشغيل التطبيق

 

 

ListConfiguration

تستخدم للاختيار من عدة خيارات, سنستخدمها لوضع خلفية بين الخلفيات الموجودة في drawable

قمت بوضع عدة خلفيات في مجلد drawable

 

 

سنقوم بتعريف الخيارات على حسب عدد الخلفيات الموجودة

<ListConfiguration
            id="wallpaper"
            displayName="wallpaper"
            defaultValue="0">

            <ListOption id="0"  />
            <ListOption id="1"  />
            <ListOption id="2"  />
            <ListOption id="3"  />

        </ListConfiguration>

 

 

سنقوم الآن بعرض الخلفية بناءً على اختيار المستخدم

 

 <ListConfiguration id="wallpaper">
            <ListOption id="0">
                <PartImage
                    height="450"
                    width="450"
                    x="0"
                    y="0">
                    <Image
                        resource="wallpaper_1" />
                </PartImage>
            </ListOption>

            <ListOption id="1">
                <PartImage
                    height="450"
                    width="450"
                    x="0"
                    y="0">
                    <Image
                        resource="wallpaper_2" />
                </PartImage>
            </ListOption>

            <ListOption id="2">
                <PartImage
                    height="450"
                    width="450"
                    x="0"
                    y="0">
                    <Image
                        resource="wallpaper_3" />
                </PartImage>
            </ListOption>

            <ListOption id="3">
                <PartImage
                    height="450"
                    width="450"
                    x="0"
                    y="0">
                    <Image
                        resource="wallpaper_4" />
                </PartImage>
            </ListOption>
        </ListConfiguration>

 

يمكنك إعتبار الكود السابق ك "switch statement" , اذا كان الخيار رقم ١ اعرض الخلفية رقم ١, وهكذا...

نقوم بتشغيل التطبيق

 

 

Complications

تستخدم لعرض بيانات يقدمها النظام أو تطبيق معين ويمكن تخصيصها من قبل المستخدم لاختيار Complication الذي يريد

يوجد العديد من أنواع Complications , يمكنك رؤية التفاصيل في هذا الرابط

سنقوم بالتركيز على نوع COMPLICATION.TEXT في هذا المثال

 

 

 <ComplicationSlot
            name="left_complication"
            displayName="Left Complication"
            height="85"
            slotId="2"
            supportedTypes="SHORT_TEXT"
            width="85"
            x="100"
            y="230">
            <DefaultProviderPolicy
                defaultSystemProvider="WATCH_BATTERY"
                defaultSystemProviderType="SHORT_TEXT"
                primaryProvider="EMPTY"
                primaryProviderType="SHORT_TEXT" />
            <BoundingOval
                height="112"
                outlinePadding="2"
                width="112"
                x="0"
                y="0" />

            <Complication type="SHORT_TEXT">
                <PartText
                    height="50"
                    width="150"
                    x="0"
                    y="0">

                    <Text align="CENTER">
                        <Font
                            color="#ffffff"
                            family="rubik"
                            size="28"
                            slant="NORMAL"
                            weight="NORMAL">
                            <Upper>
                                <Template>%s
                                    <Parameter expression="[COMPLICATION.TEXT]" />
                                </Template>
                            </Upper>
                        </Font>
                    </Text>
                </PartText>
            </Complication>
        </ComplicationSlot>

 

لنشرح المثال السابق

أولاً قمنا بتعريف  ComplicationSlot ووضعنا المعلومات المطلوبة , أهمها slotId و supportedTypes

ثم وضعنا DefaultProviderPolicy والذي سيقول للنظام أن هذه Complication بشكل إفتراضي ستقوم بعرض "نسبة البطارية" في حال المستخدم لم يقم بتغييرها

وبحسب نوع الComplication فإن كل Complication ستقدم Text و Title وقد تختلف من تطبيق لآخر

في حالتنا قمنا بوضع WATCH_BATTERY بشكل إفتراضي 

كما يمكنك وضع Complication خاص بتطبيق معين اذا كان يقدم Complication

مثل:

com.devlomi.prayerwear/com.devlomi.prayerwatchface.complications.NextPrayerTimeLeftComplicationService

 

BoundingOval هي الدائرة التي ستظهر للمستخدم عند الدخول الى نافذة التخصيص

 

داخل Complication وضعنا PartText  داخله Parameter 

وقمنا بأخذ [COMPLICATION.TEXT] الذي يقدمه الComplication

 

الكود كاملا

 

<WatchFace
    height="450"
    width="450">
    <Metadata
        key="CLOCK_TYPE"
        value="DIGITAL" />

    <UserConfigurations>
        <BooleanConfiguration
            defaultValue="FALSE"
            displayName="show_battery_percentage"
            id="show_battery" />

        <ListConfiguration
            defaultValue="0"
            displayName="wallpaper"
            id="wallpaper">

            <ListOption id="0" />
            <ListOption id="1" />
            <ListOption id="2" />
            <ListOption id="3" />

        </ListConfiguration>

        <ColorConfiguration
            defaultValue="0"
            displayName="font_color"
            id="font_color">
            <ColorOption
                colors="#FFFFFF"
                displayName="white"
                id="0" />
            <ColorOption
                colors="#FF0000"
                displayName="red"
                id="1" />
            <ColorOption
                colors="#00FF00"
                displayName="green"
                id="2" />
            <ColorOption
                colors="#0000FF"
                displayName="blue"
                id="3" />
        </ColorConfiguration>
    </UserConfigurations>


    <Scene>

        <PartText
            height="100"
            width="450"
            x="100"
            y="100">

            <Text>
                <Font
                    color="[CONFIGURATION.font_color]"
                    family="rubik"
                    size="30">
                    <Template>%s
                        <Parameter expression="[DAY_OF_WEEK_S]" />
                    </Template>
                </Font>
            </Text>
        </PartText>

        <BooleanConfiguration id="show_battery">
            <BooleanOption id="TRUE">

                <PartText
                    height="100"
                    width="450"
                    x="100"
                    y="200">

                    <Text>
                        <Font
                            color="[CONFIGURATION.font_color]"
                            family="rubik"
                            size="30">
                            <Template>%s
                                <Parameter expression="[BATTERY_PERCENT]" />
                            </Template>
                        </Font>
                    </Text>

                </PartText>
            </BooleanOption>
        </BooleanConfiguration>

        <ComplicationSlot
            name="left_complication"
            displayName="Left Complication"
            height="85"
            slotId="2"
            supportedTypes="SHORT_TEXT"
            width="85"
            x="100"
            y="230">
            <DefaultProviderPolicy
                defaultSystemProvider="WATCH_BATTERY"
                defaultSystemProviderType="SHORT_TEXT"
                primaryProvider="EMPTY"
                primaryProviderType="SHORT_TEXT" />
            <BoundingOval
                height="112"
                outlinePadding="2"
                width="112"
                x="0"
                y="0" />

            <Complication type="SHORT_TEXT">
                <PartText
                    height="50"
                    width="150"
                    x="0"
                    y="0">

                    <Text align="CENTER">
                        <Font
                            color="#ffffff"
                            family="rubik"
                            size="28"
                            slant="NORMAL"
                            weight="NORMAL">
                            <Upper>
                                <Template>%s
                                    <Parameter expression="[COMPLICATION.TEXT]" />
                                </Template>
                            </Upper>
                        </Font>
                    </Text>
                </PartText>
            </Complication>
        </ComplicationSlot>


    </Scene>
</WatchFace>

 

نقوم بتشغيل التطبيق

 بشكل إفتراضي قام بعرض نسبة البطارية

كما استطعنا تغيير النص من نسبة البطارية الى عدد الخطوات من خلال إعدادات الWatch Face

 

كلمات دليلية: android watchface wearos wff
0
إعجاب
5
مشاهدات
0
مشاركة
1
متابع

التعليقات (0)

لايوجد لديك حساب في عالم البرمجة؟

تحب تنضم لعالم البرمجة؟ وتنشئ عالمك الخاص، تنشر المقالات، الدورات، تشارك المبرمجين وتساعد الآخرين، اشترك الآن بخطوات يسيرة !