البحث في تطبيقات التلفزيون

غالبًا ما يكون لدى المستخدمين محتوى محدد في الاعتبار عند استخدام أحد تطبيقات الوسائط على التلفزيون. إذا كان تطبيقك يحتوي على كتالوجًا كبيرًا من المحتوى، فإن التصفح عن عنوان معين قد لا يكون الطريقة الأكثر فعالية المستخدمين للعثور على ما يبحثون عنه. يمكن لواجهة البحث أن تساعد المستخدمين في الوصول إلى المحتوى الذي يريدونه بشكل أسرع من التصفّح

توفر مكتبة androidx.leanback مجموعة من الفئات لتفعيل واجهة بحث قياسية داخل تطبيقك بما يتوافق مع وظائف البحث الأخرى على التلفزيون وتوفّر ميزات مثل الإدخال الصوتي.

يناقش هذا الدليل كيفية توفير واجهة بحث في تطبيقك باستخدام دعم Leanback دروس المكتبة.

إضافة إجراء بحث

عند استخدام الفئة BrowseFragment للوسائط واجهة التصفح، يمكنك تفعيل واجهة بحث كجزء عادي من واجهة من واجهة pyplot. واجهة البحث هي رمز يظهر في التنسيق عند ضبط View.OnClickListener على BrowseFragment. الخاص بك. يوضح الرمز النموذجي التالي هذا الأسلوب.

Kotlin

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

Java

@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. لتوفير واجهة بحث ونتائج:

Kotlin

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

Java

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. يشغِّل طلب البحث على سلسلة محادثات منفصلة. يؤدي هذا الأسلوب إلى بطء الأداء المحتمل من حظر سلسلة محادثات واجهة المستخدم الرئيسية.