התאמה אישית של ממשק המשתמש של השולח ב-Android

אתם יכולים להתאים אישית את ווידג'טים של Cast על ידי הגדרת הצבעים, עיצוב הלחצנים, הטקסט והמראה של התמונה הממוזערת, ובחירת סוגי הלחצנים שיוצגו.

התאמה אישית של העיצוב של האפליקציה

בדוגמה הזו נוצר סגנון עיצוב בהתאמה אישית Theme.CastVideosTheme, שבו אפשר להגדיר צבעים בהתאמה אישית, סגנון של שכבת-על למבוא, סגנון של בקר קטן וסגנון של בקר מורחב.

<style name="Theme.CastVideosTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Set AppCompat's color theming attrs -->
    <item name="colorPrimary">@color/primary</item>
    <item name="colorPrimaryDark">@color/primary_dark</item>
    <item name="colorAccent">@color/accent</item>
    <item name="android:textColorPrimary">@color/primary_text</item>
    <item name="android:textColorSecondary">@color/secondary_text</item>
    <item name="castIntroOverlayStyle">@style/CustomCastIntroOverlay</item>
    <item name="castMiniControllerStyle">@style/CustomCastMiniController</item>
    <item name="castExpandedControllerStyle">@style/CustomCastExpandedController</item>
</style>

שלוש השורות האחרונות שלמעלה מאפשרות לכם להגדיר סגנונות ספציפיים לשכבת-על של פתיח, לבקר מינימלי ולבקר מורחב כחלק מהנושא הזה. דוגמאות מופיעות בסעיפים הבאים.

התאמה אישית של לחצן Cast

כדי להוסיף mediaRouteTheme מותאם אישית לעיצוב של האפליקציה:

<style name="Theme.CastVideosTheme" parent="Theme.AppCompat.Light.NoActionBar">
  <!-- ... -->
  <item name="mediaRouteTheme">@style/CustomMediaRouterTheme</item>
</style>

מגדירים את העיצוב המותאם אישית של Media Router ומגדירים mediaRouteButtonStyle מותאם אישית:

<style name="CustomMediaRouterTheme" parent="Theme.MediaRouter">
  <item name="mediaRouteButtonStyle">@style/CustomMediaRouteButtonStyle</item>
</style>

<style name="CustomMediaRouteButtonStyle" parent="Widget.MediaRouter.Light.MediaRouteButton">
  <item name="mediaRouteButtonTint">#EEFF41</item>
</style>

צריך להשתמש ב-setTint אם גרסת ספריית התמיכה חדשה יותר מ-26.0.0. בגרסאות ישנות יותר של ספריית התמיכה, צריך להשתמש ב-buttonTint במקום זאת.

התאמה אישית של העיצוב של שכבת-העל של ההקדמה

המחלקות IntroductoryOverlay תומכות במאפייני סגנון שונים שהאפליקציה יכולה לבטל בערכת נושא בהתאמה אישית. בדוגמה הזו מוצג איך לשנות את מראה הטקסט של הכפתור ושל הכותרת בווידג'ט של שכבת-העל:

<style name="CustomCastIntroOverlay" parent="CastIntroOverlay">
    <item name="castButtonTextAppearance">@style/TextAppearance.CustomCastIntroOverlay.Button</item>
    <item name="castTitleTextAppearance">@style/TextAppearance.CustomCastIntroOverlay.Title</item>
</style>
<style name="TextAppearance.CustomCastIntroOverlay.Button" parent="android:style/TextAppearance">
    <item name="android:textColor">#FFFFFF</item>
</style>
<style name="TextAppearance.CustomCastIntroOverlay.Title"parent="android:style/TextAppearance.Large">
    <item name="android:textColor">#FFFFFF</item>
</style>

התאמה אישית של השלט הקטן

התאמה אישית של העיצוב

המחלקות MiniControllerFragment תומכות במאפייני סגנון שונים שהאפליקציה יכולה לבטל בערכת נושא בהתאמה אישית. בדוגמה הזו מוסבר איך להפעיל את התצוגה של התמונה הממוזערת, לשנות את מראה הטקסט של כותרת המשנה ושל הכתוביות, להגדיר את הצבעים ולהתאים אישית את הלחצנים:

<style name="CustomCastMiniController" parent="CastMiniController">
    <item name="castShowImageThumbnail">true</item>
    <item name="castTitleTextAppearance">@style/TextAppearance.AppCompat.Subhead</item>
    <item name="castSubtitleTextAppearance">@style/TextAppearance.AppCompat.Caption</item>
    <item name="castBackground">#FFFFFF</item>
    <item name="castProgressBarColor">#FFFFFF</item>
    <item name="castPlayButtonDrawable">@drawable/cast_ic_mini_controller_play</item>
    <item name="castPauseButtonDrawable">@drawable/cast_ic_mini_controller_pause</item>
    <item name="castStopButtonDrawable">@drawable/cast_ic_mini_controller_stop</item>
    <item name="castLargePlayButtonDrawable">@drawable/cast_ic_mini_controller_play_large</item>
    <item name="castLargePauseButtonDrawable">@drawable/cast_ic_mini_controller_pause_large</item>
    <item name="castLargeStopButtonDrawable">@drawable/cast_ic_mini_controller_stop_large</item>
    <item name="castSkipPreviousButtonDrawable">@drawable/cast_ic_mini_controller_skip_prev</item>
    <item name="castSkipNextButtonDrawable">@drawable/cast_ic_mini_controller_skip_next</item>
    <item name="castRewind30ButtonDrawable">@drawable/cast_ic_mini_controller_rewind30</item>
    <item name="castForward30ButtonDrawable">@drawable/cast_ic_mini_controller_forward30</item>
    <item name="castMuteToggleButtonDrawable">@drawable/cast_ic_mini_controller_mute</item>
    <item name="castClosedCaptionsButtonDrawable">@drawable/cast_ic_mini_controller_closed_caption</item
</style>

בחירת כפתורים

ל-MiniControllerFragment יש שלושה חריצים שבהם יכולה להופיע עטיפת האלבום ושני לחצנים, או שלושה לחצני בקרה אם עטיפת האלבום לא מופיעה.

SLOT  SLOT  SLOT
  1     2     3

כברירת מחדל, הפריט מציג לחצן הפעלה או השהיה. מפתחים יכולים להשתמש במאפיין castControlButtons כדי לשנות את הכפתורים שיוצגו. הכפתורים הנתמכים מוגדרים כמשאבי מזהה:

סוג לחצן תיאור
@id/cast_button_type_empty לא להציב לחצן במשבצת הזו
@id/cast_button_type_custom כפתור בהתאמה אישית
@id/cast_button_type_play_pause_toggle מעבר בין הפעלה להשהיה
@id/cast_button_type_skip_previous דילוג לפריט הקודם בתור
@id/cast_button_type_skip_next דילוג לפריט הבא בתור
@id/cast_button_type_rewind_30_seconds הרצה אחורה של 30 שניות
@id/cast_button_type_forward_30_seconds דילוג קדימה של 30 שניות בהפעלה
@id/cast_button_type_mute_toggle השתקה וביטול ההשתקה של המקבל
@id/cast_button_type_closed_caption תיפתח תיבת דו-שיח לבחירת טראקים של טקסט ואודיו

דוגמה לשימוש בלחצן להחלפת הפעלה/השהיה, בלחצן דילוג קדימה ובגרפיקה של האלבום, בסדר הזה משמאל לימין:

<array name="cast_mini_controller_control_buttons">
    <item>@id/cast_button_type_empty</item>
    <item>@id/cast_button_type_play_pause_toggle</item>
    <item>@id/cast_button_type_forward_30_seconds</item>
</array>
...
<fragment
    android:id="@+id/cast_mini_controller"
    ...
    app:castControlButtons="@array/cast_mini_controller_control_buttons"
    class="com.google.android.gms.cast.framework.media.widget.MiniControllerFragment">

אזהרה: המערך הזה חייב לכלול בדיוק שלושה פריטים, אחרת תופעל חריגה בזמן הריצה. אם לא רוצים להציג לחצן במשבצת, משתמשים בערך @id/cast_button_type_empty.

הוספת לחצנים בהתאמה אישית

ב-MiniControllerFragment אפשר להוסיף כפתורי בקרה בהתאמה אישית שלא מסופקים על ידי ה-SDK, כמו כפתור לייק. השלבים:

  1. מציינים משבצת להכלת כפתור מותאם אישית באמצעות @id/cast_button_type_custom במאפיין castControlButtons של MiniControllerFragment.

  2. מטמיעים מחלקת משנה של UIController. ‫UIController מכיל שיטות שמופעלות על ידי ה-SDK כשהמצב של סשן ה-Cast או סשן המדיה משתנה. מחלקת המשנה של UIController צריכה לקבל את ImageView כאחד הפרמטרים ולעדכן את המצב שלה לפי הצורך.

  3. מחלקת משנה MiniControllerFragment, ואז מחליפים את onCreateView וקוראים ל getButtonImageViewAt(int) כדי לקבל את ImageView עבור הלחצן המותאם אישית הזה. לאחר מכן מתקשרים אל bindViewToUIController(View, UIController) כדי לקשר את התצוגה אל UIController בהתאמה אישית.

  4. במאמר MediaIntentReceiver בקטע הוספת פעולות בהתאמה אישית מוסבר איך לטפל בפעולה מהכפתור המותאם אישית.

    דוגמה לשיוך לחצן במשבצת 2 ל-UIController בשם MyCustomUIController:

// arrays.xml
<array name="cast_expanded_controller_control_buttons">
    <item>@id/cast_button_type_empty</item>
    <item>@id/cast_button_type_rewind_30_seconds</item>
    <item>@id/cast_button_type_custom</item>
    <item>@id/cast_button_type_empty</item>
</array>
Kotlin
// MyCustomUIController.kt
class MyCustomUIController(private val mView: View) : UIController() {
    override fun onMediaStatusUpdated() {
        // Update the state of mView based on the latest the media status.
        ...
        mView.visibility = View.INVISIBLE
        ...
    }
}

// MyMiniControllerFragment.kt
class MyMiniControllerFragment : MiniControllerFragment() {
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        super.onCreateView(inflater, container, savedInstanceState)
        val customButtonView = getButtonImageViewAt(2)
        val myCustomUiController = MyCustomUIController(customButtonView)
        uiMediaController.bindViewToUIController(customButtonView, myCustomUiController)
        ...
    }
}
Java
// MyCustomUIController.java
class MyCustomUIController extends UIController {
    private final View mView;

    public MyCustomUIController(View view) {
            mView = view;
    }

    @Override
    public onMediaStatusUpdated() {
        // Update the state of mView based on the latest the media status.
        ...
        mView.setVisibility(View.INVISIBLE);
        ...
    }
}

// MyMiniControllerFragment.java
class MyMiniControllerFragment extends MiniControllerFragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        ImageView customButtonView = getButtonImageViewAt(2);
        MyCustomUIController myCustomUiController = new MyCustomUIController(customButtonView);
        getUIMediaController().bindViewToUIController(customButtonView, myCustomUiController);
        ...
    }
}

התאמה אישית של בקר מורחב

התאמה אישית של העיצוב

אם הפעילות של בקר מורחב משתמשת בסרגל כלים עם עיצוב כהה, אפשר להגדיר עיצוב בסרגל הכלים כדי להשתמש בטקסט בהיר ובצבע סמל בהיר:

<style name="Theme.CastVideosTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="castExpandedControllerToolbarStyle">
        @style/ThemeOverlay.AppCompat.Dark.ActionBar
    </item>
</style>

אתם יכולים לציין תמונות משלכם שישמשו לציור הלחצנים בשלט המורחב:

<style name="CustomCastExpandedController" parent="CastExpandedController">
    <item name="castButtonColor">@null</item>
    <item name="castPlayButtonDrawable">@drawable/cast_ic_expanded_controller_play</item>
    <item name="castPauseButtonDrawable">@drawable/cast_ic_expanded_controller_pause</item>
    <item name="castStopButtonDrawable">@drawable/cast_ic_expanded_controller_stop</item>
    <item name="castSkipPreviousButtonDrawable">@drawable/cast_ic_expanded_controller_skip_previous</item>
    <item name="castSkipNextButtonDrawable">@drawable/cast_ic_expanded_controller_skip_next</item>
    <item name="castRewind30ButtonDrawable">@drawable/cast_ic_expanded_controller_rewind30</item>
    <item name="castForward30ButtonDrawable">@drawable/cast_ic_expanded_controller_forward30</item>
</style>

בחירת כפתורים

בבקר המורחב יש חמישה מקומות להצגת לחצני בקרה. במשבצת האמצעית תמיד מופיע כפתור הפעלה או השהיה, ואי אפשר להגדיר אותה. ארבעת המשבצות האחרות ניתנות להגדרה על ידי אפליקציית השולח, משמאל לימין.

SLOT  SLOT  PLAY/PAUSE  SLOT  SLOT
  1     2     BUTTON      3     4

כברירת מחדל, בפעילות מוצגים לחצן כתוביות, לחצן דילוג לפריט הקודם, לחצן דילוג לפריט הבא ולחצן הפעלה/השבתה של השתקה בארבעת המקומות האלה, משמאל לימין. מפתחים יכולים להשתמש במאפיין castControlButtons כדי לשנות את הלחצנים שיוצגו במשבצות מסוימות. רשימת לחצני הבקרה הנתמכים מוגדרת כמשאבי מזהה זהים לסוגי הלחצנים של לחצני הבקרה הקטנים.

דוגמה להצבת לחצן להרצה אחורה במשבצת השנייה, לחצן להרצה קדימה במשבצת השלישית, והשארת המשבצת הראשונה והאחרונה ריקות:

// arrays.xml
<array name="cast_expanded_controller_control_buttons">
    <item>@id/cast_button_type_empty</item>
    <item>@id/cast_button_type_rewind_30_seconds</item>
    <item>@id/cast_button_type_forward_30_seconds</item>
    <item>@id/cast_button_type_empty</item>
</array>
...
// styles.xml
<style name="Theme.MyTheme">
    <item name="castExpandedControllerStyle">
        @style/CustomCastExpandedController
    </item>
</style>
...
<style name="CustomCastExpandedController" parent="CastExpandedController">
    <item name="castControlButtons">
        @array/cast_expanded_controller_control_buttons
    </item>
</style>

המערך חייב להכיל ארבעה פריטים בדיוק, אחרת תופעל חריגה בזמן ריצה. אם לא רוצים להציג לחצן במשבצת, משתמשים בערך @id/cast_button_type_empty. הדומיין CastContext יכול לנהל את מחזור החיים ואת ההצגה של הפעילות הזו.

הוספת לחצנים בהתאמה אישית

ב-ExpandedControllerActivity יש תמיכה בהוספה של לחצני בקרה בהתאמה אישית שלא מסופקים על ידי ה-SDK, כמו לחצן 'לייק'. השלבים:

  1. מציינים משבצת להכלת כפתור מותאם אישית באמצעות @id/cast_button_type_custom במאפיין castControlButtons של ExpandedControllerActivity. אחר כך תוכלו להשתמש ב-getButtonImageViewAt(int) כדי לקבל את ImageView של הלחצן המותאם אישית.

  2. מטמיעים מחלקת משנה של UIController. ‫UIController מכיל שיטות שמופעלות על ידי ה-SDK כשהמצב של סשן Cast או סשן מדיה משתנה. מחלקת המשנה של UIController צריכה לקבל את ImageView כאחד מהפרמטרים ולעדכן את המצב שלה לפי הצורך.

  3. יוצרים מחלקת משנה של ExpandedControllerActivity, ואז מבטלים את ברירת המחדל של onCreate וקוראים ל-getButtonImageViewAt(int) כדי לקבל את אובייקט התצוגה של הלחצן. לאחר מכן מתקשרים אל bindViewToUIController(View, UIController) כדי לקשר את התצוגה לUIController בהתאמה אישית.

  4. במאמר הוספת פעולות בהתאמה אישית מוסבר איך לטפל בפעולה מהכפתור המותאם אישית.MediaIntentReceiver

דוגמה לשיוך לחצן במשבצת 2 לUIController בשם MyCustomUIController:

// arrays.xml
<array name="cast_expanded_controller_control_buttons">
    <item>@id/cast_button_type_empty</item>
    <item>@id/cast_button_type_rewind_30_seconds</item>
    <item>@id/cast_button_type_custom</item>
    <item>@id/cast_button_type_empty</item>
</array>
Kotlin
// MyCustomUIController.kt
class MyCustomUIController(private val mView: View) : UIController() {
    override fun onMediaStatusUpdated() {
        // Update the state of mView based on the latest the media status.
        ...
        mView.visibility = View.INVISIBLE
        ...
    }
}

// MyExpandedControllerActivity.kt
internal class MyExpandedControllerActivity : ExpandedControllerActivity() {
    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val customButtonView = getButtonImageViewAt(2)
        val myCustomUiController = MyCustomUIController(customButtonView)
        uiMediaController.bindViewToUIController(customButtonView, myCustomUiController)
        ...
    }
}
Java
// MyCustomUIController.java
class MyCustomUIController extends UIController {
    private final View mView;

    public MyCustomUIController(View view) {
        mView = view;
    }

    @Override
    public onMediaStatusUpdated() {
        // Update the state of mView based on the latest the media status.
        ...
        mView.setVisibility(View.INVISIBLE);
        ...
    }
}

// MyExpandedControllerActivity.java
class MyExpandedControllerActivity extends ExpandedControllerActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ImageView customButtonView = getButtonImageViewAt(2);
        MyCustomUIController myCustomUiController = new MyCustomUIController(customButtonView);
        getUIMediaController().bindViewToUIController(customButtonView, myCustomUiController);
        ...
    }
}