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

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

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

בדוגמה הזו נוצר סגנון עיצוב מותאם אישית 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>

מצהירים על העיצוב המותאם אישית של נתב המדיה ומצהירים על עיצוב בהתאמה אישית 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. אפשר לציין יחידת קיבולת (Slot) שכוללת לחצן בהתאמה אישית באמצעות @id/cast_button_type_custom במאפיין castControlButtons של MiniControllerFragment.

  2. מטמיעים סיווג משנה של UIController. השדה UIController מכיל שיטות ש-SDK מבצע קריאה כשהמצב של סשן ההעברה או של סשן המדיה משתנה. מחלקת המשנה של 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>
קוטלין
// 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. אפשר לציין יחידת קיבולת (Slot) שכוללת לחצן בהתאמה אישית באמצעות @id/cast_button_type_custom במאפיין castControlButtons של ExpandedControllerActivity. לאחר מכן תוכלו להשתמש ב-getButtonImageViewAt(int) כדי לקבל את התג ImageView של הלחצן בהתאמה אישית.

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

  3. מחלקת המשנה ExtendedControllerActivity, לאחר מכן תוכלו לשנות את 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>
קוטלין
// 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);
        ...
    }
}