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

আপনি কাস্ট উইজেট কাস্টমাইজ করতে পারেন রঙ সেট করে, বোতাম, টেক্সট ও থাম্বনেল দেখানোর স্টাইল পরিবর্তন করে এবং কোন ধরনের বোতাম দেখাতে চান তা বেছে নিয়ে।

অ্যাপ থিম কাস্টমাইজ করা

এই উদাহরণে একটি কাস্টম থিম স্টাইল 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>

আপনার কাস্টম মিডিয়া রাউটার থিম ঘোষণা করুন এবং কাস্টম 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. কাস্টম বোতামের জন্য ImageView পেতে, সাবক্লাস MiniControllerFragment, তারপর ওভাররাইড onCreateView এবং কল getButtonImageViewAt(int) করুন। তারপর আপনার কাস্টম 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 ব্যবহার করে কাস্টম বোতাম রাখার জন্য একটি স্লট নির্দিষ্ট করুন। তারপরে, সেই কাস্টম বোতামের জন্য ImageView পাওয়ার জন্য আপনি getButtonImageViewAt(int) ব্যবহার করতে পারবেন।

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

  3. Subclass ExpandedControllerActivity, তারপর ওভাররাইড করুন onCreate এবং কল করুন getButtonImageViewAt(int) বোতামের ভিউ অবজেক্ট পেতে। তারপর আপনার কাস্টম 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
        ...
    }
}

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