Android প্রেরকের UI কাস্টমাইজ করা

আপনি 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>

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 রিসোর্স হিসেবে সংজ্ঞায়িত করা হয়:

বোতামের ধরন বিবরণ
@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 প্লেব্যাক ৩০ সেকেন্ড রিওয়াইন্ড করে
@id/cast_button_type_forward_30_seconds প্লেব্যাক ৩০ সেকেন্ড এগিয়ে যায়
@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. MiniControllerFragment-এর castControlButtons অ্যাট্রিবিউটে @id/cast_button_type_custom ব্যবহার করে কাস্টম বোতামের জন্য একটি স্লট নির্দিষ্ট করুন।

  2. UIController-এর সাবক্লাস প্রয়োগ করুন। UIController-এ এমন পদ্ধতি আছে যা কাস্ট সেশন বা মিডিয়া সেশনের স্ট্যাটাস পরিবর্তন হলে SDK-এর মাধ্যমে কল করা হয়। আপনার UIController-এর সাবক্লাস একটি প্যারামিটার হিসেবে ImageView নেবে এবং প্রয়োজন অনুযায়ী এর স্ট্যাটাস আপডেট করবে।

  3. সাবক্লাস MiniControllerFragment, তারপর ওভাররাইড করুন onCreateView এবং কল করুন getButtonImageViewAt(int) যাতে কাস্টম বোতামের জন্য ImageView পাওয়া যায়। তারপর আপনার কাস্টম UIController-এর সাথে ভিউ অ্যাসোসিয়েট করতে bindViewToUIController(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>
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. ExpandedControllerActivity-এর castControlButtons অ্যাট্রিবিউটে @id/cast_button_type_custom ব্যবহার করে কাস্টম বোতামের জন্য একটি স্লট নির্দিষ্ট করুন। তারপর আপনি getButtonImageViewAt(int) ব্যবহার করে সেই কাস্টম বোতামের জন্য ImageView পেতে পারেন।

  2. UIController-এর সাবক্লাস প্রয়োগ করুন। UIController-এ এমন পদ্ধতি আছে যা কাস্ট সেশন বা মিডিয়া সেশনের স্ট্যাটাস পরিবর্তন হলে SDK-এর মাধ্যমে কল করা হয়। আপনার UIController-এর সাবক্লাসকে প্যারামিটার হিসেবে ImageView নিতে হবে এবং প্রয়োজন অনুযায়ী এর স্ট্যাটাস আপডেট করতে হবে।

  3. Subclass ExpandedControllerActivity, তারপর ওভাররাইড করুন onCreate এবং কল করুন getButtonImageViewAt(int) বোতামের ভিউ অবজেক্ট পেতে। তারপর আপনার কাস্টম UIController-এর সাথে ভিউ অ্যাসোসিয়েট করতে bindViewToUIController(View, UIController) কল করুন।

  4. আপনার কাস্টম বোতাম থেকে অ্যাকশন কীভাবে ম্যানেজ করবেন তা জানতে MediaIntentReceiver কাস্টম অ্যাকশন যোগ করুন বিকল্পে দেখুন।

এখানে স্লট ২-এ একটি বোতামকে MyCustomUIController নামের একটি UIController-এর সাথে যুক্ত করার উদাহরণ দেওয়া হল:

// 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);
        ...
    }
}