कैटलॉग ब्राउज़र बनाना

Compose की मदद से बेहतर ऐप्लिकेशन बनाना
Android TV OS के लिए Jetpack Compose का इस्तेमाल करके, कम से कम कोड में सुंदर यूज़र इंटरफ़ेस बनाएं.

टीवी पर चलने वाले मीडिया ऐप्लिकेशन में, लोगों को कॉन्टेंट ब्राउज़ करने, उसे चुनने, और चलाने की सुविधा होनी चाहिए. कॉन्टेंट ब्राउज़ करने का अनुभव आसान और सहज होना चाहिए. साथ ही, यह देखने में अच्छा और दिलचस्प होना चाहिए.

इस गाइड में, androidx.leanback लाइब्रेरी की बंद की गई क्लास का इस्तेमाल करके, अपने ऐप्लिकेशन के मीडिया कैटलॉग से संगीत या वीडियो ब्राउज़ करने के लिए, यूज़र इंटरफ़ेस लागू करने का तरीका बताया गया है.

ध्यान दें: यहां दिखाए गए लागू करने के उदाहरण में, हटा दी गई BrowseFragment क्लास के बजाय BrowseSupportFragment का इस्तेमाल किया गया है. BrowseSupportFragment क्लास को बढ़ाता है. इससे यह पक्का करने में मदद मिलती है कि सभी डिवाइसों और Android वर्शन पर एक जैसा व्यवहार हो. Fragment

ऐप्लिकेशन की मुख्य स्क्रीन

पहली इमेज. Leanback के सैंपल ऐप्लिकेशन का ब्राउज़ फ़्रैगमेंट, वीडियो कैटलॉग का डेटा दिखाता है.

मीडिया ब्राउज़ करने का लेआउट बनाना

Leanback यूज़र इंटरफ़ेस (यूआई) टूलकिट में मौजूद 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>

ऐप्लिकेशन की मुख्य ऐक्टिविटी, इस व्यू को सेट करती है. इसे यहां दिए गए उदाहरण में दिखाया गया है:

Kotlin

class MainActivity : Activity() {

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

Java

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

BrowseSupportFragment तरीके, वीडियो डेटा और यूज़र इंटरफ़ेस (यूआई) एलिमेंट की मदद से व्यू को पॉप्युलेट करते हैं. साथ ही, लेआउट पैरामीटर सेट करते हैं. जैसे, आइकॉन और टाइटल. इसके अलावा, यह भी सेट करते हैं कि कैटगरी हेडर चालू हैं या नहीं.

यूज़र इंटरफ़ेस (यूआई) एलिमेंट सेट अप करने के बारे में ज़्यादा जानकारी के लिए, यूआई एलिमेंट सेट करें सेक्शन देखें. हेडर छिपाने के बारे में ज़्यादा जानने के लिए, हेडर छिपाना या बंद करना सेक्शन देखें.

ऐप्लिकेशन का सबक्लास, BrowseSupportFragment के तरीकों को लागू करता है. यह यूज़र इंटरफ़ेस (यूआई) एलिमेंट पर उपयोगकर्ता की कार्रवाइयों के लिए इवेंट लिसनर भी सेट अप करता है. साथ ही, बैकग्राउंड मैनेजर तैयार करता है. इसे इस उदाहरण में दिखाया गया है:

Kotlin

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()
    }
    ...

Java

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

यूज़र इंटरफ़ेस (यूआई) एलिमेंट सेट करना

पिछले सैंपल में, निजी तरीके से setupUIElements() मीडिया कैटलॉग ब्राउज़र को स्टाइल करने के लिए कई BrowseSupportFragment तरीकों को कॉल करता है:

  • setBadgeDrawable() इस कोड से, बताई गई ड्रॉएबल रिसॉर्स को ब्राउज़ फ़्रैगमेंट के सबसे ऊपर दाएं कोने में रखा जाता है. जैसा कि आंकड़ों 1 और 2 में दिखाया गया है. अगर setTitle() को भी कॉल किया जाता है, तो यह तरीका टाइटल स्ट्रिंग को ड्रॉएबल रिसॉर्स से बदल देता है. ड्रॉएबल रिसॉर्स की ऊंचाई 52 डीपी होनी चाहिए.
  • setTitle() से ब्राउज़ फ़्रैगमेंट के सबसे ऊपर दाएं कोने में टाइटल स्ट्रिंग सेट होती है. हालांकि, ऐसा तब तक होता है, जब तक setBadgeDrawable() को कॉल नहीं किया जाता.
  • setHeadersState() और setHeadersTransitionOnBackEnabled() हेडर को छिपाते या बंद करते हैं. ज़्यादा जानकारी के लिए, हेडर छिपाना या बंद करना सेक्शन देखें.
  • setBrandColor() इस विकल्प का इस्तेमाल करके, ब्राउज़ फ़्रैगमेंट में मौजूद यूज़र इंटरफ़ेस (यूआई) एलिमेंट के बैकग्राउंड का रंग सेट किया जाता है. खास तौर पर, हेडर सेक्शन के बैकग्राउंड का रंग सेट किया जाता है. इसके लिए, रंग की वैल्यू तय की जाती है.
  • setSearchAffordanceColor() इस विकल्प की मदद से, खोज आइकॉन का रंग सेट किया जाता है. इसके लिए, रंग की वैल्यू तय की जाती है. खोज आइकॉन, ब्राउज़ फ़्रैगमेंट के सबसे ऊपर बाएं कोने में दिखता है. इसे पहली और दूसरी इमेज में दिखाया गया है.

हेडर व्यू को पसंद के मुताबिक बनाना

पहली इमेज में दिखाया गया ब्राउज़ फ़्रैगमेंट, वीडियो कैटगरी के नाम दिखाता है. ये नाम, वीडियो डेटाबेस में मौजूद लाइन के हेडर होते हैं. इन्हें टेक्स्ट व्यू में दिखाया जाता है. ज़्यादा जटिल लेआउट में अतिरिक्त व्यू शामिल करने के लिए, हेडर को भी अपनी पसंद के मुताबिक बनाया जा सकता है. यहां दिए गए सेक्शन में, इमेज व्यू को शामिल करने का तरीका बताया गया है. इसमें कैटगरी के नाम के बगल में आइकॉन दिखता है. जैसा कि इमेज 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 के साथ बाइंड करने का तरीका बताया गया है.

Kotlin

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

Java

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() में अपने व्यू को फ़ोकस करने के लिए, यह तरीका अपनाएं:

    Kotlin

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

    Java

    @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() तरीके का इस्तेमाल करके लाइन के हेडर के लिए प्रज़ेंटर सेट करें. इसे यहां दिए गए उदाहरण में दिखाया गया है.

Kotlin

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

Java

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

पूरे उदाहरण के लिए, Leanback का सैंपल ऐप्लिकेशन देखें.

हेडर छिपाना या बंद करना

कभी-कभी आपको लाइन के हेडर नहीं दिखाने होते. जैसे, जब स्क्रोल की जा सकने वाली सूची के लिए, ज़रूरत के मुताबिक कैटगरी न हों. लाइन के हेडर छिपाने या बंद करने के लिए, फ़्रैगमेंट के BrowseSupportFragment.setHeadersState() तरीके के दौरान BrowseSupportFragment.setHeadersState() तरीके को कॉल करें.onActivityCreated() setHeadersState() वाला तरीका, ब्राउज़ फ़्रैगमेंट में हेडर की शुरुआती स्थिति सेट करता है. इसके लिए, इनमें से किसी एक कॉन्स्टेंट को पैरामीटर के तौर पर इस्तेमाल किया जाता है:

  • HEADERS_ENABLED: जब ब्राउज़ फ़्रैगमेंट गतिविधि बनाई जाती है, तब हेडर डिफ़ॉल्ट रूप से चालू होते हैं और दिखते हैं. इस पेज पर, हेडर पहली और दूसरी इमेज में दिखाए गए तरीके से दिखते हैं.
  • HEADERS_HIDDEN: ब्राउज़ फ़्रैगमेंट गतिविधि बनाए जाने पर, हेडर डिफ़ॉल्ट रूप से चालू हो जाते हैं और छिप जाते हैं. स्क्रीन का हेडर सेक्शन छोटा किया गया है. इसे कार्ड व्यू उपलब्ध कराएं में एक इमेज में दिखाया गया है. उपयोगकर्ता, छोटा किए गए हेडर सेक्शन को बड़ा करने के लिए उसे चुन सकता है.
  • HEADERS_DISABLED: जब ब्राउज़ फ़्रैगमेंट गतिविधि बनाई जाती है, तो हेडर डिफ़ॉल्ट रूप से बंद होते हैं और कभी नहीं दिखते.

अगर HEADERS_ENABLED या HEADERS_HIDDEN सेट है, तो setHeadersTransitionOnBackEnabled() को कॉल किया जा सकता है. इससे, लाइन में चुने गए कॉन्टेंट आइटम से वापस लाइन के हेडर पर जाने में मदद मिलती है. अगर आपने इस तरीके का इस्तेमाल नहीं किया है, तो यह सुविधा डिफ़ॉल्ट रूप से चालू रहती है. खुद ही बैक मूवमेंट को हैंडल करने के लिए, false को setHeadersTransitionOnBackEnabled() पर पास करें और बैक स्टैक को हैंडल करने की अपनी रणनीति लागू करें.

मीडिया की सूचियां दिखाना

BrowseSupportFragment क्लास की मदद से, ब्राउज़ किए जा सकने वाले मीडिया कॉन्टेंट की कैटगरी और मीडिया आइटम को तय किया जा सकता है और दिखाया जा सकता है. इसके लिए, अडैप्टर और प्रज़ेंटर का इस्तेमाल करके मीडिया कैटलॉग से कॉन्टेंट लिया जाता है. अडैप्टर की मदद से, स्थानीय या ऑनलाइन डेटा सोर्स से कनेक्ट किया जा सकता है. इनमें आपके मीडिया कैटलॉग की जानकारी होती है. स्क्रीन पर कोई आइटम दिखाने के लिए, अडैप्टर व्यू बनाने और उन व्यू में डेटा बाइंड करने के लिए, प्रेजेंटर का इस्तेमाल करते हैं.

यहां दिए गए उदाहरण कोड में, स्ट्रिंग डेटा दिखाने के लिए Presenter को लागू करने का तरीका बताया गया है:

Kotlin

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

Java

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 क्लास का इस्तेमाल किया जाता है:

Kotlin

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
}

Java

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 यूज़र इंटरफ़ेस (यूआई) टूलकिट, आपके टीवी ऐप्लिकेशन की गतिविधि का बैकग्राउंड बदलने के लिए BackgroundManager क्लास उपलब्ध कराती है. नीचे दिए गए उदाहरण में, टीवी ऐप्लिकेशन की गतिविधि में बैकग्राउंड अपडेट करने का आसान तरीका बताया गया है:

Kotlin

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

Java

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

मीडिया ब्राउज़ करने की सुविधा देने वाले कई ऐप्लिकेशन, उपयोगकर्ता के मीडिया लिस्टिंग में नेविगेट करने पर बैकग्राउंड को अपने-आप अपडेट करते हैं. इसके लिए, सिलेक्शन लिसनर सेट अप किया जा सकता है. इससे उपयोगकर्ता के मौजूदा चुनाव के आधार पर, बैकग्राउंड अपने-आप अपडेट हो जाएगा. इस उदाहरण में, OnItemViewSelectedListener क्लास को सेट अप करने का तरीका बताया गया है. इससे, चुनने से जुड़े इवेंट को कैप्चर किया जा सकता है और बैकग्राउंड को अपडेट किया जा सकता है:

Kotlin

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()
            }
        }

Java

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();
            }
        }
    };
}

ध्यान दें: पिछले उदाहरण में, सिर्फ़ दिखाने के लिए एक आसान उदाहरण दिया गया है. अपने ऐप्लिकेशन में यह फ़ंक्शन बनाते समय, बेहतर परफ़ॉर्मेंस के लिए बैकग्राउंड अपडेट ऐक्शन को अलग थ्रेड में चलाएं. इसके अलावा, अगर आपको उपयोगकर्ताओं के आइटम स्क्रोल करने पर बैकग्राउंड अपडेट करना है, तो बैकग्राउंड इमेज को अपडेट करने में लगने वाला समय जोड़ें. इससे, उपयोगकर्ता के किसी आइटम पर रुकने तक बैकग्राउंड इमेज अपडेट नहीं होगी. इस तकनीक से, बैकग्राउंड इमेज को बार-बार अपडेट करने से बचा जा सकता है.