একটি ক্যাটালগ ব্রাউজার তৈরি করুন

রচনার সাথে আরও ভাল তৈরি করুন৷
Android TV OS এর জন্য Jetpack Compose ব্যবহার করে ন্যূনতম কোড সহ সুন্দর UI তৈরি করুন।

একটি টিভিতে চলে এমন একটি মিডিয়া অ্যাপ ব্যবহারকারীদের তার সামগ্রী অফার ব্রাউজ করতে, একটি নির্বাচন করতে এবং সামগ্রী খেলা শুরু করতে দিতে হবে৷ বিষয়বস্তু ব্রাউজিং অভিজ্ঞতা অবশ্যই সহজ এবং স্বজ্ঞাত এবং সেইসাথে দৃশ্যত আনন্দদায়ক এবং আকর্ষক হতে হবে।

এই নির্দেশিকাটি আপনার অ্যাপের মিডিয়া ক্যাটালগ থেকে সঙ্গীত বা ভিডিও ব্রাউজ করার জন্য একটি ব্যবহারকারী ইন্টারফেস বাস্তবায়ন করতে androidx.leanback লাইব্রেরি দ্বারা প্রদত্ত ক্লাসগুলি কীভাবে ব্যবহার করবেন তা আলোচনা করে৷

দ্রষ্টব্য: এখানে দেখানো বাস্তবায়নের উদাহরণটি অপ্রচলিত BrowseFragment ক্লাসের পরিবর্তে BrowseSupportFragment ব্যবহার করে। BrowseSupportFragment অ্যান্ড্রয়েডএক্স Fragment ক্লাস প্রসারিত করে, ডিভাইস এবং অ্যান্ড্রয়েড সংস্করণ জুড়ে সামঞ্জস্যপূর্ণ আচরণ নিশ্চিত করতে সহায়তা করে।

অ্যাপের প্রধান স্ক্রীন

চিত্র 1. Leanback নমুনা অ্যাপের ব্রাউজ টুকরা ভিডিও ক্যাটালগ ডেটা প্রদর্শন করে।

একটি মিডিয়া ব্রাউজ লেআউট তৈরি করুন

Leanback UI টুলকিটে BrowseSupportFragment ক্লাস আপনাকে ন্যূনতম কোড সহ মিডিয়া আইটেমগুলির সারি এবং বিভাগ ব্রাউজ করার জন্য একটি প্রাথমিক লেআউট তৈরি করতে দেয়। নিম্নলিখিত উদাহরণটি দেখায় কিভাবে একটি লেআউট তৈরি করতে হয় যাতে একটি BrowseSupportFragment অবজেক্ট রয়েছে:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/main_frame"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment
        android:name="com.example.android.tvleanback.ui.MainFragment"
        android:id="@+id/main_browse_fragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</FrameLayout>

অ্যাপ্লিকেশনটির প্রধান কার্যকলাপ এই দৃশ্যটি সেট করে, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:

কোটলিন

class MainActivity : Activity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main)
    }
...

জাভা

public class MainActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
...

BrowseSupportFragment পদ্ধতিগুলি ভিডিও ডেটা এবং UI উপাদানগুলির সাথে ভিউ পূরণ করে এবং আইকন এবং শিরোনামের মতো বিন্যাস পরামিতি এবং বিভাগ শিরোনাম সক্ষম করা আছে কিনা তা সেট করে৷

UI উপাদানগুলি সেট আপ করার বিষয়ে আরও তথ্যের জন্য, UI উপাদানগুলি সেট করুন বিভাগটি দেখুন৷ শিরোনামগুলি লুকানোর বিষয়ে আরও তথ্যের জন্য, শিরোনামগুলি লুকান বা অক্ষম করুন বিভাগটি দেখুন৷

অ্যাপ্লিকেশনটির সাবক্লাস যেটি BrowseSupportFragment পদ্ধতিগুলি প্রয়োগ করে তা UI উপাদানগুলিতে ব্যবহারকারীর ক্রিয়াগুলির জন্য ইভেন্ট শ্রোতাদের সেট আপ করে এবং পটভূমি পরিচালক প্রস্তুত করে, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:

কোটলিন

class MainFragment : BrowseSupportFragment(),
        LoaderManager.LoaderCallbacks<HashMap<String, List<Movie>>> {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        loadVideoData()
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        prepareBackgroundManager()
        setupUIElements()
        setupEventListeners()
    }
    ...
    private fun prepareBackgroundManager() {
        backgroundManager = BackgroundManager.getInstance(activity).apply {
            attach(activity?.window)
        }
        defaultBackground = resources.getDrawable(R.drawable.default_background)
        metrics = DisplayMetrics()
        activity?.windowManager?.defaultDisplay?.getMetrics(metrics)
    }

    private fun setupUIElements() {
        badgeDrawable = resources.getDrawable(R.drawable.videos_by_google_banner)
        // Badge, when set, takes precedent over title
        title = getString(R.string.browse_title)
        headersState = BrowseSupportFragment.HEADERS_ENABLED
        isHeadersTransitionOnBackEnabled = true
        // Set header background color
        brandColor = ContextCompat.getColor(requireContext(), R.color.fastlane_background)

        // Set search icon color
        searchAffordanceColor = ContextCompat.getColor(requireContext(), R.color.search_opaque)
    }

    private fun loadVideoData() {
        VideoProvider.setContext(activity)
        videosUrl = getString(R.string.catalog_url)
        loaderManager.initLoader(0, null, this)
    }

    private fun setupEventListeners() {
        setOnSearchClickedListener {
            Intent(activity, SearchActivity::class.java).also { intent ->
                startActivity(intent)
            }
        }

        onItemViewClickedListener = ItemViewClickedListener()
        onItemViewSelectedListener = ItemViewSelectedListener()
    }
    ...

জাভা

public class MainFragment extends BrowseSupportFragment implements
        LoaderManager.LoaderCallbacks<HashMap<String, List<Movie>>> {
}
...
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        loadVideoData();
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        prepareBackgroundManager();
        setupUIElements();
        setupEventListeners();
    }
...
    private void prepareBackgroundManager() {
        backgroundManager = BackgroundManager.getInstance(getActivity());
        backgroundManager.attach(getActivity().getWindow());
        defaultBackground = getResources()
            .getDrawable(R.drawable.default_background);
        metrics = new DisplayMetrics();
        getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
    }

    private void setupUIElements() {
        setBadgeDrawable(getActivity().getResources()
            .getDrawable(R.drawable.videos_by_google_banner));
        // Badge, when set, takes precedent over title
        setTitle(getString(R.string.browse_title));
        setHeadersState(HEADERS_ENABLED);
        setHeadersTransitionOnBackEnabled(true);
        // Set header background color
        setBrandColor(ContextCompat.getColor(requireContext(), R.color.fastlane_background));
        // Set search icon color
        setSearchAffordanceColor(ContextCompat.getColor(requireContext(), R.color.search_opaque));
    }

    private void loadVideoData() {
        VideoProvider.setContext(getActivity());
        videosUrl = getString(R.string.catalog_url);
        getLoaderManager().initLoader(0, null, this);
    }

    private void setupEventListeners() {
        setOnSearchClickedListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                Intent intent = new Intent(getActivity(), SearchActivity.class);
                startActivity(intent);
            }
        });

        setOnItemViewClickedListener(new ItemViewClickedListener());
        setOnItemViewSelectedListener(new ItemViewSelectedListener());
    }
...

UI উপাদান সেট করুন

পূর্ববর্তী নমুনায়, ব্যক্তিগত পদ্ধতি setupUIElements() মিডিয়া ক্যাটালগ ব্রাউজারকে স্টাইল করার জন্য বিভিন্ন BrowseSupportFragment পদ্ধতি কল করে:

  • setBadgeDrawable() ব্রাউজ ফ্র্যাগমেন্টের উপরের-ডান কোণায় নির্দিষ্ট অঙ্কনযোগ্য সংস্থান রাখে, যেমনটি চিত্র 1 এবং 2-এ দেখানো হয়েছে। এই পদ্ধতিটি শিরোনাম স্ট্রিংকে অঙ্কনযোগ্য সংস্থান দিয়ে প্রতিস্থাপন করে, যদি setTitle() ও বলা হয়। অঙ্কনযোগ্য সম্পদ অবশ্যই 52 ডিপি লম্বা হতে হবে।
  • setTitle() ব্রাউজ ফ্র্যাগমেন্টের উপরের-ডান কোণায় শিরোনাম স্ট্রিং সেট করে, যদি না setBadgeDrawable() বলা হয়।
  • setHeadersState() এবং setHeadersTransitionOnBackEnabled() হেডার লুকান বা নিষ্ক্রিয় করুন। আরও তথ্যের জন্য হেডার লুকান বা অক্ষম করুন বিভাগটি দেখুন।
  • setBrandColor() ব্রাউজ ফ্র্যাগমেন্টে UI উপাদানগুলির জন্য পটভূমির রঙ সেট করে, বিশেষ করে হেডার বিভাগের পটভূমির রঙ, নির্দিষ্ট রঙের মান সহ।
  • setSearchAffordanceColor() নির্দিষ্ট রঙের মান সহ অনুসন্ধান আইকনের রঙ সেট করে। অনুসন্ধান আইকনটি ব্রাউজ ফ্র্যাগমেন্টের উপরের-বাম কোণে প্রদর্শিত হয়, যেমনটি চিত্র 1 এবং 2 এ দেখানো হয়েছে।

হেডার ভিউ কাস্টমাইজ করুন

চিত্র 1-এ দেখানো ব্রাউজ ফ্র্যাগমেন্ট ভিডিও বিভাগের নামগুলি প্রদর্শন করে, যা ভিডিও ডাটাবেসের সারি শিরোনাম, পাঠ্য দর্শনে। আপনি আরও জটিল লেআউটে অতিরিক্ত ভিউ অন্তর্ভুক্ত করতে হেডারটি কাস্টমাইজ করতে পারেন। নিম্নলিখিত বিভাগগুলি দেখায় যে কীভাবে একটি চিত্র ভিউ অন্তর্ভুক্ত করতে হয় যা চিত্র 2-এ দেখানো হিসাবে বিভাগের নামের পাশে একটি আইকন প্রদর্শন করে।

অ্যাপের প্রধান স্ক্রীন

চিত্র 2. একটি আইকন এবং একটি টেক্সট লেবেল উভয়ের সাথে ব্রাউজ ফ্র্যাগমেন্টের সারি শিরোনাম।

সারি হেডারের বিন্যাস নিম্নরূপ সংজ্ঞায়িত করা হয়েছে:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/header_icon"
        android:layout_width="32dp"
        android:layout_height="32dp" />
    <TextView
        android:id="@+id/header_label"
        android:layout_marginTop="6dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

একটি Presenter ব্যবহার করুন এবং ভিউ হোল্ডার তৈরি, আবদ্ধ এবং আনবাইন্ড করতে বিমূর্ত পদ্ধতিগুলি প্রয়োগ করুন। নিম্নলিখিত উদাহরণটি দেখায় কিভাবে ভিউহোল্ডারকে দুটি ভিউ, একটি ImageView এবং একটি TextView দিয়ে আবদ্ধ করতে হয়।

কোটলিন

class IconHeaderItemPresenter : Presenter() {

    override fun onCreateViewHolder(viewGroup: ViewGroup): Presenter.ViewHolder {
        val view = LayoutInflater.from(viewGroup.context).run {
            inflate(R.layout.icon_header_item, null)
        }

        return Presenter.ViewHolder(view)
    }


    override fun onBindViewHolder(viewHolder: Presenter.ViewHolder, o: Any) {
        val headerItem = (o as ListRow).headerItem
        val rootView = viewHolder.view

        rootView.findViewById<ImageView>(R.id.header_icon).apply {
            rootView.resources.getDrawable(R.drawable.ic_action_video, null).also { icon ->
                setImageDrawable(icon)
            }
        }

        rootView.findViewById<TextView>(R.id.header_label).apply {
            text = headerItem.name
        }
    }

    override fun onUnbindViewHolder(viewHolder: Presenter.ViewHolder) {
        // no-op
    }
}

জাভা

public class IconHeaderItemPresenter extends Presenter {
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup) {
        LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext());

        View view = inflater.inflate(R.layout.icon_header_item, null);

        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder viewHolder, Object o) {
        HeaderItem headerItem = ((ListRow) o).getHeaderItem();
        View rootView = viewHolder.view;

        ImageView iconView = (ImageView) rootView.findViewById(R.id.header_icon);
        Drawable icon = rootView.getResources().getDrawable(R.drawable.ic_action_video, null);
        iconView.setImageDrawable(icon);

        TextView label = (TextView) rootView.findViewById(R.id.header_label);
        label.setText(headerItem.getName());
    }

    @Override
    public void onUnbindViewHolder(ViewHolder viewHolder) {
    // no-op
    }
}

আপনার শিরোনামগুলি অবশ্যই ফোকাসযোগ্য হতে হবে যাতে ডি-প্যাডটি তাদের মাধ্যমে স্ক্রোল করতে ব্যবহার করা যেতে পারে। এটি পরিচালনা করার দুটি উপায় রয়েছে:

  • onBindViewHolder() এ ফোকাসযোগ্য হতে আপনার ভিউ সেট করুন:

    কোটলিন

    override fun onBindViewHolder(viewHolder: Presenter.ViewHolder, o: Any) {
        val headerItem = (o as ListRow).headerItem
        val rootView = viewHolder.view
    
        rootView.focusable = View.FOCUSABLE
        // ...
    }
    

    জাভা

    @Override
    public void onBindViewHolder(ViewHolder viewHolder, Object o) {
        HeaderItem headerItem = ((ListRow) o).getHeaderItem();
        View rootView = viewHolder.view;
        rootView.setFocusable(View.FOCUSABLE) // Allows the D-Pad to navigate to this header item
        // ...
    }
    
  • ফোকাসযোগ্য হতে আপনার লেআউট সেট করুন:
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
       ...
       android:focusable="true">

অবশেষে, BrowseSupportFragment বাস্তবায়নে যা ক্যাটালগ ব্রাউজার প্রদর্শন করে, setHeaderPresenterSelector() পদ্ধতিটি ব্যবহার করুন সারি হেডারের জন্য উপস্থাপক সেট করতে, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে।

কোটলিন

setHeaderPresenterSelector(object : PresenterSelector() {
    override fun getPresenter(o: Any): Presenter {
        return IconHeaderItemPresenter()
    }
})

জাভা

setHeaderPresenterSelector(new PresenterSelector() {
    @Override
    public Presenter getPresenter(Object o) {
        return new IconHeaderItemPresenter();
    }
});

একটি সম্পূর্ণ উদাহরণের জন্য, Leanback নমুনা অ্যাপটি দেখুন।

হেডার লুকান বা অক্ষম করুন

কখনও কখনও আপনি সারি শিরোনামগুলি উপস্থিত হতে চান না, যেমন যখন স্ক্রোলযোগ্য তালিকার প্রয়োজনের জন্য পর্যাপ্ত বিভাগ না থাকে। সারি শিরোনামগুলি লুকাতে বা অক্ষম করতে খণ্ডের onActivityCreated() পদ্ধতির সময় BrowseSupportFragment.setHeadersState() পদ্ধতিতে কল করুন। setHeadersState() পদ্ধতি ব্রাউজ ফ্র্যাগমেন্টে হেডারগুলির প্রাথমিক অবস্থা সেট করে, একটি প্যারামিটার হিসাবে নিম্নলিখিত ধ্রুবকগুলির মধ্যে একটি দেওয়া হয়েছে:

  • HEADERS_ENABLED : যখন ব্রাউজ ফ্র্যাগমেন্ট অ্যাক্টিভিটি তৈরি করা হয়, তখন হেডার সক্রিয় করা হয় এবং ডিফল্টরূপে দেখানো হয়। এই পৃষ্ঠায় চিত্র 1 এবং 2-এ দেখানো হিসাবে হেডারগুলি উপস্থিত হয়৷
  • HEADERS_HIDDEN : যখন ব্রাউজ ফ্র্যাগমেন্ট অ্যাক্টিভিটি তৈরি করা হয়, তখন হেডার সক্রিয় থাকে এবং ডিফল্টরূপে লুকানো থাকে। স্ক্রীনের শিরোনাম বিভাগটি ভেঙে গেছে, যেমনটি একটি কার্ড ভিউ প্রদানের একটি চিত্রে দেখানো হয়েছে। ব্যবহারকারী এটিকে প্রসারিত করতে সঙ্কুচিত হেডার বিভাগটি নির্বাচন করতে পারেন।
  • HEADERS_DISABLED : যখন ব্রাউজ ফ্র্যাগমেন্ট অ্যাক্টিভিটি তৈরি করা হয়, তখন হেডারগুলি ডিফল্টরূপে অক্ষম থাকে এবং কখনই প্রদর্শিত হয় না।

যদি হয় HEADERS_ENABLED বা HEADERS_HIDDEN সেট করা থাকে, আপনি সারির একটি নির্বাচিত বিষয়বস্তু আইটেম থেকে সারি হেডারে ফিরে যেতে সমর্থন করতে setHeadersTransitionOnBackEnabled() কল করতে পারেন৷ আপনি যদি পদ্ধতিটি কল না করেন তবে এটি ডিফল্টরূপে সক্রিয় থাকে৷ ব্যাক মুভমেন্ট নিজে পরিচালনা করতে, setHeadersTransitionOnBackEnabled()false পাস করুন এবং আপনার নিজের ব্যাক স্ট্যাক হ্যান্ডলিং বাস্তবায়ন করুন।

মিডিয়া তালিকা প্রদর্শন করুন

BrowseSupportFragment ক্লাস আপনাকে অ্যাডাপ্টার এবং উপস্থাপক ব্যবহার করে মিডিয়া ক্যাটালগ থেকে ব্রাউজযোগ্য মিডিয়া বিষয়বস্তু বিভাগ এবং মিডিয়া আইটেমগুলি সংজ্ঞায়িত এবং প্রদর্শন করতে দেয়। অ্যাডাপ্টারগুলি আপনাকে স্থানীয় বা অনলাইন ডেটা উত্সগুলির সাথে সংযোগ করতে দেয় যেখানে আপনার মিডিয়া ক্যাটালগ তথ্য রয়েছে৷ অ্যাডাপ্টারগুলি ভিউ তৈরি করতে এবং স্ক্রিনে কোনও আইটেম প্রদর্শনের জন্য সেই ভিউগুলির সাথে ডেটা আবদ্ধ করতে উপস্থাপকদের ব্যবহার করে।

নিম্নলিখিত উদাহরণ কোডটি স্ট্রিং ডেটা প্রদর্শনের জন্য একটি Presenter বাস্তবায়ন দেখায়:

কোটলিন

private const val TAG = "StringPresenter"

class StringPresenter : Presenter() {

    override fun onCreateViewHolder(parent: ViewGroup): Presenter.ViewHolder {
        val textView = TextView(parent.context).apply {
            isFocusable = true
            isFocusableInTouchMode = true
            background = parent.resources.getDrawable(R.drawable.text_bg)
        }
        return Presenter.ViewHolder(textView)
    }

    override fun onBindViewHolder(viewHolder: Presenter.ViewHolder, item: Any) {
        (viewHolder.view as TextView).text = item.toString()
    }

    override fun onUnbindViewHolder(viewHolder: Presenter.ViewHolder) {
        // no op
    }
}

জাভা

public class StringPresenter extends Presenter {
    private static final String TAG = "StringPresenter";

    public ViewHolder onCreateViewHolder(ViewGroup parent) {
        TextView textView = new TextView(parent.getContext());
        textView.setFocusable(true);
        textView.setFocusableInTouchMode(true);
        textView.setBackground(
                parent.getResources().getDrawable(R.drawable.text_bg));
        return new ViewHolder(textView);
    }

    public void onBindViewHolder(ViewHolder viewHolder, Object item) {
        ((TextView) viewHolder.view).setText(item.toString());
    }

    public void onUnbindViewHolder(ViewHolder viewHolder) {
        // no op
    }
}

একবার আপনি আপনার মিডিয়া আইটেমগুলির জন্য একটি উপস্থাপক শ্রেণী তৈরি করার পরে, আপনি একটি অ্যাডাপ্টার তৈরি করতে পারেন এবং ব্যবহারকারীর দ্বারা ব্রাউজ করার জন্য সেই আইটেমগুলিকে স্ক্রিনে প্রদর্শন করতে BrowseSupportFragment এর সাথে সংযুক্ত করতে পারেন৷ নিম্নলিখিত উদাহরণ কোডটি দেখায় কিভাবে পূর্ববর্তী কোড উদাহরণে দেখানো StringPresenter ক্লাস ব্যবহার করে বিভাগ এবং আইটেমগুলি প্রদর্শন করার জন্য একটি অ্যাডাপ্টার তৈরি করতে হয়:

কোটলিন

private const val NUM_ROWS = 4
...
private lateinit var rowsAdapter: ArrayObjectAdapter

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    buildRowsAdapter()
}

private fun buildRowsAdapter() {
    rowsAdapter = ArrayObjectAdapter(ListRowPresenter())
    for (i in 0 until NUM_ROWS) {
        val listRowAdapter = ArrayObjectAdapter(StringPresenter()).apply {
            add("Media Item 1")
            add("Media Item 2")
            add("Media Item 3")
        }
        HeaderItem(i.toLong(), "Category $i").also { header ->
            rowsAdapter.add(ListRow(header, listRowAdapter))
        }
    }
    browseSupportFragment.adapter = rowsAdapter
}

জাভা

private ArrayObjectAdapter rowsAdapter;
private static final int NUM_ROWS = 4;

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    buildRowsAdapter();
}

private void buildRowsAdapter() {
    rowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());

    for (int i = 0; i < NUM_ROWS; ++i) {
        ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(
                new StringPresenter());
        listRowAdapter.add("Media Item 1");
        listRowAdapter.add("Media Item 2");
        listRowAdapter.add("Media Item 3");
        HeaderItem header = new HeaderItem(i, "Category " + i);
        rowsAdapter.add(new ListRow(header, listRowAdapter));
    }

    browseSupportFragment.setAdapter(rowsAdapter);
}

এই উদাহরণটি অ্যাডাপ্টারের একটি স্থির বাস্তবায়ন দেখায়। একটি সাধারণ মিডিয়া ব্রাউজিং অ্যাপ্লিকেশন একটি অনলাইন ডাটাবেস বা ওয়েব পরিষেবা থেকে ডেটা ব্যবহার করে। একটি ব্রাউজিং অ্যাপ্লিকেশনের উদাহরণের জন্য যা ওয়েব থেকে পুনরুদ্ধার করা ডেটা ব্যবহার করে, Leanback নমুনা অ্যাপটি দেখুন।

ব্যাকগ্রাউন্ড আপডেট করুন

টিভিতে একটি মিডিয়া-ব্রাউজিং অ্যাপে চাক্ষুষ আগ্রহ যোগ করতে, ব্যবহারকারীরা বিষয়বস্তুর মাধ্যমে ব্রাউজ করার সাথে সাথে আপনি পটভূমি চিত্রটি আপডেট করতে পারেন। এই কৌশলটি আপনার অ্যাপের সাথে মিথস্ক্রিয়াকে আরও সিনেমাটিক এবং উপভোগ্য করে তুলতে পারে।

Leanback UI টুলকিট আপনার টিভি অ্যাপ কার্যকলাপের পটভূমি পরিবর্তন করার জন্য একটি BackgroundManager ক্লাস প্রদান করে। নিম্নলিখিত উদাহরণটি দেখায় যে কীভাবে আপনার টিভি অ্যাপ কার্যকলাপের মধ্যে পটভূমি আপডেট করার জন্য একটি সহজ পদ্ধতি তৈরি করতে হয়:

কোটলিন

protected fun updateBackground(drawable: Drawable) {
    BackgroundManager.getInstance(this).drawable = drawable
}

জাভা

protected void updateBackground(Drawable drawable) {
    BackgroundManager.getInstance(this).setDrawable(drawable);
}

অনেক মিডিয়া-ব্রাউজিং অ্যাপ স্বয়ংক্রিয়ভাবে পটভূমি আপডেট করে যখন ব্যবহারকারী মিডিয়া তালিকার মাধ্যমে নেভিগেট করে। এটি করার জন্য, আপনি ব্যবহারকারীর বর্তমান নির্বাচনের উপর ভিত্তি করে স্বয়ংক্রিয়ভাবে পটভূমি আপডেট করতে একটি নির্বাচন শ্রোতা সেট আপ করতে পারেন। নিম্নলিখিত উদাহরণটি দেখায় কিভাবে একটি OnItemViewSelectedListener ক্লাস সেট আপ করতে হয় নির্বাচন ইভেন্টগুলি ধরতে এবং পটভূমি আপডেট করতে:

কোটলিন

protected fun clearBackground() {
    BackgroundManager.getInstance(this).drawable = defaultBackground
}

protected fun getDefaultItemViewSelectedListener(): OnItemViewSelectedListener =
        OnItemViewSelectedListener { _, item, _, _ ->
            if (item is Movie) {
                item.getBackdropDrawable().also { background ->
                    updateBackground(background)
                }
            } else {
                clearBackground()
            }
        }

জাভা

protected void clearBackground() {
    BackgroundManager.getInstance(this).setDrawable(defaultBackground);
}

protected OnItemViewSelectedListener getDefaultItemViewSelectedListener() {
    return new OnItemViewSelectedListener() {
        @Override
        public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item,
                RowPresenter.ViewHolder rowViewHolder, Row row) {
            if (item instanceof Movie ) {
                Drawable background = ((Movie)item).getBackdropDrawable();
                updateBackground(background);
            } else {
                clearBackground();
            }
        }
    };
}

দ্রষ্টব্য: পূর্ববর্তী বাস্তবায়ন চিত্রের উদ্দেশ্যে একটি সহজ উদাহরণ। আপনার নিজের অ্যাপে এই ফাংশনটি তৈরি করার সময়, ভাল পারফরম্যান্সের জন্য একটি পৃথক থ্রেডে ব্যাকগ্রাউন্ড আপডেট অ্যাকশন চালান। এছাড়াও, আপনি যদি ব্যবহারকারীদের আইটেমগুলির মাধ্যমে স্ক্রোল করার প্রতিক্রিয়া হিসাবে ব্যাকগ্রাউন্ড আপডেট করার পরিকল্পনা করেন, তবে ব্যবহারকারী একটি আইটেমে স্থির না হওয়া পর্যন্ত একটি ব্যাকগ্রাউন্ড ইমেজ আপডেট বিলম্বিত করার জন্য একটি সময় যোগ করুন। এই কৌশলটি অত্যধিক ব্যাকগ্রাউন্ড ইমেজ আপডেট এড়ায়।