رابط کاربری فرستنده اندروید را سفارشی کنید

شما می‌توانید ویجت‌های 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>

سه خط آخر بالا به شما امکان می‌دهد سبک‌های مخصوص پوشش مقدماتی، کنترلر کوچک و کنترلر گسترش‌یافته را به عنوان بخشی از این قالب تعریف کنید. مثال‌هایی در بخش‌های بعدی آمده است.

دکمه‌ی ارسال را سفارشی کنید

برای افزودن یک 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>

اگر نسخه کتابخانه پشتیبانی جدیدتر از 26.0.0 باشد، باید setTint استفاده شود. برای نسخه‌های قدیمی‌تر کتابخانه پشتیبانی، لطفاً به جای آن buttonTint استفاده کنید.

سفارشی‌سازی پوسته‌ی مقدماتی

کلاس IntroductoryOverlay از ویژگی‌های استایل مختلفی پشتیبانی می‌کند که برنامه شما می‌تواند در یک تم سفارشی آن‌ها را لغو کند. این مثال نحوه لغو ظاهر متن دکمه و عنوان روی ویجت overlay را نشان می‌دهد:

<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 شامل متدهایی است که هنگام تغییر وضعیت جلسه تبدیل (cast session) یا جلسه رسانه (media session) توسط SDK فراخوانی می‌شوند. زیرکلاس UIController شما باید یک ImageView به عنوان یکی از پارامترها دریافت کند و وضعیت آن را در صورت نیاز به‌روزرسانی کند.

  3. زیرکلاس MiniControllerFragment ایجاد کنید، سپس onCreateView بازنویسی کنید و getButtonImageViewAt(int) را برای دریافت ImageView مربوط به آن دکمه سفارشی فراخوانی کنید. سپس bindViewToUIController(View, UIController) را برای مرتبط کردن نما با UIController سفارشی خود فراخوانی کنید.

  4. برای نحوه مدیریت اکشن از دکمه سفارشی خود، به MediaIntentReceiver در بخش افزودن اکشن‌های سفارشی مراجعه کنید.

    در اینجا مثالی از مرتبط کردن یک دکمه در اسلات ۲ به یک 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)
        ...
    }
}
جاوا
// 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);
        ...
    }
}

سفارشی‌سازی کنترلر توسعه‌یافته

سفارشی سازی تم

اگر Activity یک کنترلر توسعه‌یافته از نوار ابزار با تم تیره استفاده می‌کند، می‌توانید تمی را روی نوار ابزار تنظیم کنید که از متن روشن و رنگ آیکون روشن استفاده کند:

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

دکمه‌ها را انتخاب کنید

بخش فعالیت (Activity) کنترلر توسعه‌یافته، پنج جایگاه برای نمایش دکمه‌های کنترلی دارد. جایگاه وسط همیشه دکمه‌ی پخش/مکث را نشان می‌دهد و قابل تنظیم نیست. چهار جایگاه دیگر، از چپ به راست، توسط برنامه‌ی فرستنده قابل تنظیم هستند.

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

به طور پیش‌فرض، Activity یک دکمه‌ی زیرنویس، یک دکمه‌ی پرش به آیتم قبلی، یک دکمه‌ی پرش به آیتم بعدی و یک دکمه‌ی قطع صدا را در این چهار جایگاه، از چپ به راست، نشان می‌دهد. توسعه‌دهندگان می‌توانند از ویژگی castControlButtons برای لغو اینکه کدام دکمه‌ها در کدام جایگاه‌ها نمایش داده شوند، استفاده کنند. لیست دکمه‌های کنترلی پشتیبانی‌شده به عنوان منابع ID تعریف می‌شوند که مشابه انواع دکمه برای دکمه‌های مینی کنترلر هستند.

در اینجا مثالی آورده شده است که یک دکمه‌ی عقب‌گرد را در جایگاه دوم، یک دکمه‌ی پرش به جلو را در جایگاه سوم قرار می‌دهد و جایگاه‌های اول و آخر را خالی می‌گذارد:

// 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 ارائه نشده‌اند، مانند دکمه "thumb's up" پشتیبانی می‌کند. مراحل آن به شرح زیر است:

  1. با استفاده از @id/cast_button_type_custom ‎ در ویژگی castControlButtons ‎ از ExpandedControllerActivity ‎، یک اسلات برای قرار دادن یک دکمه سفارشی مشخص کنید. سپس می‌توانید getButtonImageViewAt(int) ‎ برای دریافت ImageView مربوط به آن دکمه سفارشی استفاده کنید.

  2. یک زیرکلاس از UIController پیاده‌سازی کنید. UIController شامل متدهایی است که هنگام تغییر وضعیت جلسه تبدیل (cast session) یا جلسه رسانه (media session) توسط SDK فراخوانی می‌شوند. زیرکلاس UIController شما باید یک ImageView به عنوان یکی از پارامترها دریافت کند و وضعیت آن را در صورت نیاز به‌روزرسانی کند.

  3. کلاس زیرکلاس ExpandedControllerActivity را ایجاد کنید، سپس onCreate override کنید و getButtonImageViewAt(int) را برای دریافت شیء view مربوط به دکمه فراخوانی کنید. سپس bindViewToUIController(View, UIController) را برای مرتبط کردن view با UIController سفارشی خود فراخوانی کنید.

  4. برای نحوه مدیریت اکشن از دکمه سفارشی خود، به MediaIntentReceiver در بخش افزودن اکشن‌های سفارشی مراجعه کنید.

در اینجا مثالی از مرتبط کردن یک دکمه در اسلات ۲ به یک 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)
        ...
    }
}
جاوا
// 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);
        ...
    }
}