جستجو در برنامه های تلویزیون

کاربران معمولاً هنگام استفاده از یک برنامه رسانه در تلویزیون، محتوای خاصی را در ذهن دارند. اگر برنامه شما حاوی کاتالوگ بزرگی از محتوا است، مرور برای یک عنوان خاص ممکن است کارآمدترین راه برای کاربران برای یافتن آنچه به دنبال آن هستند نباشد. یک رابط جستجو می تواند به کاربران شما کمک کند تا سریعتر از مرور به محتوای مورد نظر خود برسند.

کتابخانه androidx.leanback مجموعه ای از کلاس ها را برای فعال کردن یک رابط جستجوی استاندارد در برنامه شما فراهم می کند که با سایر عملکردهای جستجو در تلویزیون سازگار است و ویژگی هایی مانند ورودی صوتی را ارائه می دهد.

این راهنما نحوه ارائه رابط جستجو در برنامه خود را با استفاده از کلاس های کتابخانه پشتیبانی Leanback مورد بحث قرار می دهد.

یک اقدام جستجو اضافه کنید

هنگامی که از کلاس BrowseFragment برای یک رابط مرور رسانه استفاده می کنید، می توانید یک رابط جستجو را به عنوان بخشی استاندارد از رابط کاربری فعال کنید. رابط جستجو نمادی است که هنگام تنظیم View.OnClickListener در شی BrowseFragment در طرح ظاهر می شود. کد نمونه زیر این تکنیک را نشان می دهد.

کاتلین

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.browse_activity)
    browseFragment = fragmentManager.findFragmentById(R.id.browse_fragment) as BrowseFragment
    browseFragment.setOnSearchClickedListener { view ->
        val intent = Intent(this@BrowseActivity, SearchActivity::class.java)
        startActivity(intent)
    }

    browseFragment.setAdapter(buildAdapter())
}

جاوا

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.browse_activity);

    browseFragment = (BrowseFragment)
            getFragmentManager().findFragmentById(R.id.browse_fragment);

    ...

    browseFragment.setOnSearchClickedListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(BrowseActivity.this, SearchActivity.class);
            startActivity(intent);
        }
    });

    browseFragment.setAdapter(buildAdapter());
}

توجه: می توانید رنگ نماد جستجو را با استفاده از روش setSearchAffordanceColor(int) تنظیم کنید.

ورودی جستجو و نتایج را اضافه کنید

هنگامی که کاربر نماد جستجو را انتخاب می کند، سیستم یک فعالیت جستجو را با استفاده از هدف تعریف شده فراخوانی می کند. برای فعالیت جستجوی خود، از طرح‌بندی خطی حاوی SearchFragment استفاده کنید. این قطعه همچنین باید رابط SearchFragment.SearchResultProvider را برای نمایش نتایج جستجو پیاده سازی کند.

نمونه کد زیر نحوه گسترش کلاس SearchFragment برای ارائه یک رابط جستجو و نتایج را نشان می دهد:

کاتلین

class MySearchFragment : SearchFragment(), SearchFragment.SearchResultProvider {
    private val rowsAdapter = ArrayObjectAdapter(ListRowPresenter())
    private val handler = Handler()
    private val delayedLoad = SearchRunnable()

    val resultsAdapter: ObjectAdapter
    get() {
        return rowsAdapter
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setSearchResultProvider(this)
        setOnItemClickedListener(getDefaultItemClickedListener())
    }

    fun onQueryTextChange(newQuery: String): Boolean {
        rowsAdapter.clear()
        if (!TextUtils.isEmpty(newQuery)) {
            delayedLoad.setSearchQuery(newQuery)
            handler.removeCallbacks(delayedLoad)
            handler.postDelayed(delayedLoad, SEARCH_DELAY_MS)
        }
        return true
    }

    fun onQueryTextSubmit(query: String): Boolean {
        rowsAdapter.clear()
        if (!TextUtils.isEmpty(query)) {
            delayedLoad.setSearchQuery(query)
            handler.removeCallbacks(delayedLoad)
            handler.postDelayed(delayedLoad, SEARCH_DELAY_MS)
        }
        return true
    }

    companion object {
        private val SEARCH_DELAY_MS = 300
    }
}

جاوا

public class MySearchFragment extends SearchFragment
        implements SearchFragment.SearchResultProvider {

    private static final int SEARCH_DELAY_MS = 300;
    private ArrayObjectAdapter rowsAdapter;
    private Handler handler = new Handler();
    private SearchRunnable delayedLoad;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        rowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
        setSearchResultProvider(this);
        setOnItemClickedListener(getDefaultItemClickedListener());
        delayedLoad = new SearchRunnable();
    }

    @Override
    public ObjectAdapter getResultsAdapter() {
        return rowsAdapter;
    }

    @Override
    public boolean onQueryTextChange(String newQuery) {
        rowsAdapter.clear();
        if (!TextUtils.isEmpty(newQuery)) {
            delayedLoad.setSearchQuery(newQuery);
            handler.removeCallbacks(delayedLoad);
            handler.postDelayed(delayedLoad, SEARCH_DELAY_MS);
        }
        return true;
    }

    @Override
    public boolean onQueryTextSubmit(String query) {
        rowsAdapter.clear();
        if (!TextUtils.isEmpty(query)) {
            delayedLoad.setSearchQuery(query);
            handler.removeCallbacks(delayedLoad);
            handler.postDelayed(delayedLoad, SEARCH_DELAY_MS);
        }
        return true;
    }
}

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