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

امتحان کردن روش Compose
Jetpack Compose جعبه‌ابزار واسط کاربر توصیه‌شده برای Android است. با نحوه افزودن عملکرد جستجو در Compose آشنا شوید.

توصیه می‌کنیم از ابزاره SearchView به‌عنوان موردی در نوار برنامه استفاده کنید تا عملکرد جستجو را در برنامه‌تان ارائه دهید. همانند همه موارد در نوار برنامه، می‌توانید SearchView را تعریف کنید تا همیشه یا فقط وقتی فضا وجود دارد نشان داده شود. همچنین می‌توانید آن را به‌عنوان یک کنش جمع‌شدنی تعریف کنید که در ابتدا SearchView را به‌عنوان یک نماد نمایش می‌دهد و سپس وقتی کاربر روی نماد ضربه می‌زند، کل نوار برنامه را به‌عنوان یک فیلد جستجو اشغال می‌کند.

افزودن SearchView به نوار برنامه

برای افزودن ابزاره SearchView به نوار برنامه، فایلی با نام res/menu/options_menu.xml در پروژه‌تان ایجاد کنید و کد زیر را به فایل اضافه کنید. این کد نحوه ایجاد مورد جستجو را تعریف می‌کند، مثلاً نمادی که باید استفاده شود و عنوان مورد. مشخصه collapseActionView به SearchView شما اجازه می‌دهد تا گسترش یابد و کل نوار برنامه را بگیرد و وقتی از آن استفاده نمی‌شود، دوباره به یک مورد نوار برنامه معمولی جمع شود. به‌دلیل فضای محدود نوار برنامه در دستگاه‌های گوشی، توصیه می‌کنیم از مشخصه collapsibleActionView برای ارائه تجربه کاربری بهتر استفاده کنید.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/search"
        android:title="@string/search_title"
        android:icon="@drawable/ic_search"
        android:showAsAction="collapseActionView|ifRoom"
        android:actionViewClass="androidx.appcompat.widget.SearchView" />
</menu>

اگر نماد جستجوی دردسترس‌تری می‌خواهید، فایل ic_search.xml را در پوشه /res/drawable ایجاد کنید و کد زیر را در آن قرار دهید:

<vector
    android:height="24dp"
    android:tint="#000000"
    android:viewportHeight="24"
    android:viewportWidth="24"
    android:width="24dp"
    xmlns:android="http://schemas.android.com/apk/res/android">
        <path android:fillColor="@android:color/white" android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/>
</vector>

برای نمایش SearchView در نوار برنامه، منو XML را ازهم باز کنید منبع res/menu/options_menu.xml در onCreateOptionsMenu() روش فعالیت شما:

کاتلین

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.options_menu, menu)

    return true
}

اجرای برنامه چیزی شبیه به این تولید می‌کند:

تصویری که صفحه‌ای خالی را با نماد جستجو در نوار بالای برنامه نشان می‌دهد
شکل ۱. نماد جستجو در نوار بالای برنامه.

SearchView در نوار برنامه برنامه‌تان نشان داده می‌شود، اما کار نمی‌کند. اگر روی نماد جستجو ضربه بزنید، چیزی شبیه به این دریافت می‌کنید:

تصویری که نمای جستجو را درحال کنش نشان می‌دهد
شکل ۲. ‫SearchView درحال جنب‌وجوش.

برای اینکه SearchView کاربردی شود، باید تعریف کنید که SearchView چگونه رفتار می‌کند.

ایجاد پیکربندی جستجو

پیکربندی جستجو نحوه رفتار SearchView را مشخص می‌کند و در فایل res/xml/searchable.xml تعریف می‌شود. پیکربندی جستجو باید حداقل حاوی یک مشخصه android:label باشد که مقدار آن با مشخصه android:label عنصر <application> یا <activity> در مانیفست Android شما یکسان باشد. بااین‌حال، توصیه می‌کنیم مشخصه android:hint را نیز اضافه کنید تا کاربر بداند چه چیزی را باید در چارگوش جستجو وارد کند.

<?xml version="1.0" encoding="utf-8"?>

<searchable xmlns:android="http://schemas.android.com/apk/res/android"
        android:label="@string/app_name"
        android:hint="@string/search_hint" />

در فایل مانیفست برنامه‌تان، عنصر <meta-data> را که به فایل res/xml/searchable.xml اشاره می‌کند اعلام کنید. عنصر را در <activity> که می‌خواهید SearchView را در آن نمایش دهید اعلام کنید.

<activity
android:name=".SearchResultsActivity"
android:exported="false"
android:label="@string/title_activity_search_results"
android:launchMode="singleTop"
android:theme="@style/Theme.AppCompat.Light">
    <intent-filter>
        <action android:name="android.intent.action.SEARCH" />
    </intent-filter>
    <meta-data
        android:name="android.app.searchable"
        android:resource="@xml/searchable" />
</activity>

در روش onCreateOptionsMenu() که ایجاد می‌کنید، پیکربندی جستجو را با فراخوانی setSearchableInfo(SearchableInfo) به SearchView مرتبط کنید:

کاتلین

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.options_menu, menu)

    val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager
    val searchView = menu.findItem(R.id.search).actionView as SearchView
    val component = ComponentName(this, SearchResultsActivity::class.java)
    val searchableInfo = searchManager.getSearchableInfo(component)
    searchView.setSearchableInfo(searchableInfo)
    return true
}

فراخوانی getSearchableInfo() یک شیء SearchableInfo به‌دست می‌آورد که از فایل XML پیکربندی جستجو ایجاد شده است. وقتی پیکربندی جستجو به‌درستی با SearchView شما مرتبط باشد و کاربر پُرسمانی ارسال کند، SearchView فعالیتی را با هدف ACTION_SEARCH شروع می‌کند. سپس به فعالیتی نیاز دارید که بتواند این هدف را فیلتر کند و پرسمان جستجو را مدیریت کند.

ایجاد فعالیت جستجوشدنی

فعالیت قابل‌جستجو برای هدف ACTION_SEARCH فیلتر می‌کند و پرسمان را در مجموعه داده جستجو می‌کند. برای ایجاد فعالیت قابل‌جستجو، فعالیت موردنظرتان را برای فیلتر کردن ACTION_SEARCH intent اعلام کنید:

<activity android:name=".SearchResultsActivity" ... >
    ...
    <intent-filter>
        <action android:name="android.intent.action.SEARCH" />
    </intent-filter>
    ...
</activity>

در فعالیت قابل‌جستجو، هدف ACTION_SEARCH را با بررسی آن در روش onCreate() مدیریت کنید.

کاتلین

class SearchResultsActivity : AppCompatActivity() {

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

    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        handleIntent(intent)
    }

    private fun handleIntent(intent: Intent) {
        if (Intent.ACTION_SEARCH == intent.action) {
            val query = intent.getStringExtra(SearchManager.QUERY)
            Log.d("SEARCH", "Search query was: $query")
        }
    }
}

اکنون SearchView می‌تواند پُرسمان کاربر را بپذیرد و فعالیت قابل‌جستجوی شما را با هدف ACTION_SEARCH شروع کند.

پس‌از دریافت پُرسمان جستجو، می‌توانید آن را به ViewModel ارسال کنید، جایی که می‌توانید از آن در لایه‌های دیگر معماری‌تان برای بازیابی نتایج جستجو جهت نمایش استفاده کنید.