Membuat SearchView yang terlihat seperti pedoman desain material


135

Saat ini saya sedang dalam proses mempelajari cara mengonversi aplikasi saya ke desain Material dan saat ini saya agak mandek. Saya telah menambahkan Toolbar dan saya telah membuat panel navigasi saya menutupi semua konten.

Saya sekarang mencoba membuat pencarian yang dapat diperluas yang terlihat seperti yang ada di pedoman material : masukkan deskripsi gambar di sini

Inilah yang saya dapatkan sekarang dan saya tidak tahu bagaimana membuatnya seperti di atas:
Pencarian saya

Ini adalah menu saya xml:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_search"
        android:icon="@android:drawable/ic_menu_search"
        android:title="Search"
        app:showAsAction="always"
        app:actionViewClass="android.support.v7.widget.SearchView" />
</menu>

Itu berhasil, saya mendapatkan item menu yang meluas ke SearchView dan saya bisa memfilter daftar saya dengan baik. Ini tidak terlihat seperti gambar pertama.

Saya mencoba menggunakan MenuItemCompat.setOnActionExpandListener()pada R.id.action_searchjadi saya bisa mengubah ikon rumah untuk kembali panah, tapi itu tampaknya tidak bekerja. Tidak ada yang dipecat di pendengar. Bahkan jika itu berhasil, itu tetap tidak akan terlalu dekat dengan gambar pertama.

Bagaimana cara membuat SearchView di toolbar appcompat baru yang terlihat seperti pedoman material?


6
app: showAsAction = "selalu | collapseActionView"
Pavlos

Anda mungkin ingin melihat jawaban saya di sini: stackoverflow.com/a/41013994/5326551
shnizlon

Jawaban:


152

Sebenarnya cukup mudah untuk melakukan ini, jika Anda menggunakan android.support.v7perpustakaan.

Langkah 1

Deklarasikan item menu

<item android:id="@+id/action_search"
    android:title="Search"
    android:icon="@drawable/abc_ic_search_api_mtrl_alpha"
    app:showAsAction="ifRoom|collapseActionView"
    app:actionViewClass="android.support.v7.widget.SearchView" />

Langkah 2

Perluas AppCompatActivitydan dalam onCreateOptionsMenupenyiapan SearchView.

import android.support.v7.widget.SearchView;

...

public class YourActivity extends AppCompatActivity {

    ...

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_home, menu);
        // Retrieve the SearchView and plug it into SearchManager
        final SearchView searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.action_search));
        SearchManager searchManager = (SearchManager) getSystemService(SEARCH_SERVICE);
        searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
        return true;
    }

    ... 

}

Hasil

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini


2
Saya telah meningkatkannya, tetapi emulator mana yang Anda gunakan? Saya sudah mencobanya tetapi saya tidak mendapatkan navigate-backtombolnya, melainkan ikon pencarian, dan jaraknya dari tepi kiri layar tidak sama dengan jarak antara Xikon dan tepi kanan layar (saya tidak punya tindakan overflow). Posting pertanyaan di sini , dapatkah Anda memeriksanya?
Penghiburan

13
ini bukan pencarian material. ini hanya pencarian lama di bar tindakan biasa
Gopal Singh Sirvi

2
Saya menjawab sub-pertanyaan saya sendiri, agar selalu terlihat tanpa perlu mengklik tombol pencarian, tambahkan baris searchView.setIconifiedByDefault(false);ke onCreateOptionsMenufungsi.
adelriosantiago

3
berita gembira lain yang berguna - jika Anda ingin tampilan pencarian diperluas pada awalnya, pastikan Anda memiliki app:showAsAction="always"dan TIDAKapp:showAsAction="ifRoom|collapseActionView"
Vinay W

1
Selain itu, menggunakan metode ini, bahkan ketika searchBar diperluas, OverflowIcon masih terlihat (yaitu, 3-titik). Tetapi beberapa aplikasi, menangani pencarian, dengan memperluasnya sepenuhnya dan mengubah latar belakang menjadi putih. Seperti GMail
Zen

83

Setelah seminggu memikirkan hal ini. Saya pikir saya sudah menemukan jawabannya.
Saya sekarang hanya menggunakan EditText di dalam Toolbar. Ini disarankan kepada saya oleh oj88 di reddit.

Saya sekarang memiliki ini:
SearchView baru

Pertama di dalam onCreate () aktivitas saya, saya menambahkan EditText dengan tampilan gambar di sisi kanan ke Toolbar seperti ini:

    // Setup search container view
    searchContainer = new LinearLayout(this);
    Toolbar.LayoutParams containerParams = new Toolbar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
    containerParams.gravity = Gravity.CENTER_VERTICAL;
    searchContainer.setLayoutParams(containerParams);

    // Setup search view
    toolbarSearchView = new EditText(this);
    // Set width / height / gravity
    int[] textSizeAttr = new int[]{android.R.attr.actionBarSize};
    int indexOfAttrTextSize = 0;
    TypedArray a = obtainStyledAttributes(new TypedValue().data, textSizeAttr);
    int actionBarHeight = a.getDimensionPixelSize(indexOfAttrTextSize, -1);
    a.recycle();
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, actionBarHeight);
    params.gravity = Gravity.CENTER_VERTICAL;
    params.weight = 1;
    toolbarSearchView.setLayoutParams(params);

    // Setup display
    toolbarSearchView.setBackgroundColor(Color.TRANSPARENT);
    toolbarSearchView.setPadding(2, 0, 0, 0);
    toolbarSearchView.setTextColor(Color.WHITE);
    toolbarSearchView.setGravity(Gravity.CENTER_VERTICAL);
    toolbarSearchView.setSingleLine(true);
    toolbarSearchView.setImeActionLabel("Search", EditorInfo.IME_ACTION_UNSPECIFIED);
    toolbarSearchView.setHint("Search");
    toolbarSearchView.setHintTextColor(Color.parseColor("#b3ffffff"));
    try {
        // Set cursor colour to white
        // https://stackoverflow.com/a/26544231/1692770
        // https://github.com/android/platform_frameworks_base/blob/kitkat-release/core/java/android/widget/TextView.java#L562-564
        Field f = TextView.class.getDeclaredField("mCursorDrawableRes");
        f.setAccessible(true);
        f.set(toolbarSearchView, R.drawable.edittext_whitecursor);
    } catch (Exception ignored) {
    }

    // Search text changed listener
    toolbarSearchView.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            Fragment mainFragment = getFragmentManager().findFragmentById(R.id.container);
            if (mainFragment != null && mainFragment instanceof MainListFragment) {
                ((MainListFragment) mainFragment).search(s.toString());
            }
        }

        @Override
        public void afterTextChanged(Editable s) {
            // https://stackoverflow.com/a/6438918/1692770
            if (s.toString().length() <= 0) {
                toolbarSearchView.setHintTextColor(Color.parseColor("#b3ffffff"));
            }
        }
    });
    ((LinearLayout) searchContainer).addView(toolbarSearchView);

    // Setup the clear button
    searchClearButton = new ImageView(this);
    Resources r = getResources();
    int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 16, r.getDisplayMetrics());
    LinearLayout.LayoutParams clearParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    clearParams.gravity = Gravity.CENTER;
    searchClearButton.setLayoutParams(clearParams);
    searchClearButton.setImageResource(R.drawable.ic_close_white_24dp); // TODO: Get this image from here: https://github.com/google/material-design-icons
    searchClearButton.setPadding(px, 0, px, 0);
    searchClearButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            toolbarSearchView.setText("");
        }
    });
    ((LinearLayout) searchContainer).addView(searchClearButton);

    // Add search view to toolbar and hide it
    searchContainer.setVisibility(View.GONE);
    toolbar.addView(searchContainer);

Ini berfungsi, tetapi kemudian saya menemukan masalah di mana onOptionsItemSelected () tidak dipanggil ketika saya mengetuk tombol beranda. Jadi saya tidak dapat membatalkan pencarian dengan menekan tombol home. Saya mencoba beberapa cara berbeda untuk mendaftarkan pendengar klik di tombol beranda tetapi tidak berhasil.

Akhirnya saya menemukan bahwa ActionBarDrawerToggle yang saya miliki mengganggu sesuatu, jadi saya menghapusnya. Pendengar ini kemudian mulai bekerja:

    toolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // toolbarHomeButtonAnimating is a boolean that is initialized as false. It's used to stop the user pressing the home button while it is animating and breaking things.
            if (!toolbarHomeButtonAnimating) {
                // Here you'll want to check if you have a search query set, if you don't then hide the search box.
                // My main fragment handles this stuff, so I call its methods.
                FragmentManager fragmentManager = getFragmentManager();
                final Fragment fragment = fragmentManager.findFragmentById(R.id.container);
                if (fragment != null && fragment instanceof MainListFragment) {
                    if (((MainListFragment) fragment).hasSearchQuery() || searchContainer.getVisibility() == View.VISIBLE) {
                        displaySearchView(false);
                        return;
                    }
                }
            }

            if (mDrawerLayout.isDrawerOpen(findViewById(R.id.navigation_drawer)))
                mDrawerLayout.closeDrawer(findViewById(R.id.navigation_drawer));
            else
                mDrawerLayout.openDrawer(findViewById(R.id.navigation_drawer));
        }
    });

Jadi sekarang saya bisa membatalkan pencarian dengan tombol home, tapi saya belum bisa menekan tombol back untuk membatalkannya. Jadi saya menambahkan ini ke onBackPressed ():

    FragmentManager fragmentManager = getFragmentManager();
    final Fragment mainFragment = fragmentManager.findFragmentById(R.id.container);
    if (mainFragment != null && mainFragment instanceof MainListFragment) {
        if (((MainListFragment) mainFragment).hasSearchQuery() || searchContainer.getVisibility() == View.VISIBLE) {
            displaySearchView(false);
            return;
        }
    }

Saya membuat metode ini untuk mengubah visibilitas EditText dan item menu:

public void displaySearchView(boolean visible) {
    if (visible) {
        // Stops user from being able to open drawer while searching
        mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);

        // Hide search button, display EditText
        menu.findItem(R.id.action_search).setVisible(false);
        searchContainer.setVisibility(View.VISIBLE);

        // Animate the home icon to the back arrow
        toggleActionBarIcon(ActionDrawableState.ARROW, mDrawerToggle, true);

        // Shift focus to the search EditText
        toolbarSearchView.requestFocus();

        // Pop up the soft keyboard
        new Handler().postDelayed(new Runnable() {
            public void run() {
                toolbarSearchView.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, 0, 0, 0));
                toolbarSearchView.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 0, 0, 0));
            }
        }, 200);
    } else {
        // Allows user to open drawer again
        mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);

        // Hide the EditText and put the search button back on the Toolbar.
        // This sometimes fails when it isn't postDelayed(), don't know why.
        toolbarSearchView.postDelayed(new Runnable() {
            @Override
            public void run() {
                toolbarSearchView.setText("");
                searchContainer.setVisibility(View.GONE);
                menu.findItem(R.id.action_search).setVisible(true);
            }
        }, 200);

        // Turn the home button back into a drawer icon
        toggleActionBarIcon(ActionDrawableState.BURGER, mDrawerToggle, true);

        // Hide the keyboard because the search box has been hidden
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(toolbarSearchView.getWindowToken(), 0);
    }
}

Saya membutuhkan cara untuk mengaktifkan tombol beranda pada bilah alat antara ikon laci dan tombol kembali. Saya akhirnya menemukan metode di bawah ini dalam jawaban SO ini . Meskipun saya memodifikasinya sedikit agar lebih masuk akal bagi saya:

private enum ActionDrawableState {
    BURGER, ARROW
}

/**
 * Modified version of this, https://stackoverflow.com/a/26836272/1692770<br>
 * I flipped the start offset around for the animations because it seemed like it was the wrong way around to me.<br>
 * I also added a listener to the animation so I can find out when the home button has finished rotating.
 */
private void toggleActionBarIcon(final ActionDrawableState state, final ActionBarDrawerToggle toggle, boolean animate) {
    if (animate) {
        float start = state == ActionDrawableState.BURGER ? 1.0f : 0f;
        float end = Math.abs(start - 1);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            ValueAnimator offsetAnimator = ValueAnimator.ofFloat(start, end);
            offsetAnimator.setDuration(300);
            offsetAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
            offsetAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    float offset = (Float) animation.getAnimatedValue();
                    toggle.onDrawerSlide(null, offset);
                }
            });
            offsetAnimator.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animation) {

                }

                @Override
                public void onAnimationEnd(Animator animation) {
                    toolbarHomeButtonAnimating = false;
                }

                @Override
                public void onAnimationCancel(Animator animation) {

                }

                @Override
                public void onAnimationRepeat(Animator animation) {

                }
            });
            toolbarHomeButtonAnimating = true;
            offsetAnimator.start();
        }
    } else {
        if (state == ActionDrawableState.BURGER) {
            toggle.onDrawerClosed(null);
        } else {
            toggle.onDrawerOpened(null);
        }
    }
}

Ini berfungsi, saya telah berhasil menyelesaikan beberapa bug yang saya temukan di sepanjang jalan. Saya tidak berpikir itu 100% tetapi bekerja cukup baik untuk saya.

EDIT: Jika Anda ingin menambahkan tampilan pencarian dalam XML, bukan Java, lakukan ini:

toolbar.xml:

<android.support.v7.widget.Toolbar 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/toolbar"
    contentInsetLeft="72dp"
    contentInsetStart="72dp"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    android:elevation="4dp"
    android:minHeight="?attr/actionBarSize"
    app:contentInsetLeft="72dp"
    app:contentInsetStart="72dp"
    app:popupTheme="@style/ActionBarPopupThemeOverlay"
    app:theme="@style/ActionBarThemeOverlay">

    <LinearLayout
        android:id="@+id/search_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_vertical"
        android:orientation="horizontal">

        <EditText
            android:id="@+id/search_view"
            android:layout_width="0dp"
            android:layout_height="?attr/actionBarSize"
            android:layout_weight="1"
            android:background="@android:color/transparent"
            android:gravity="center_vertical"
            android:hint="Search"
            android:imeOptions="actionSearch"
            android:inputType="text"
            android:maxLines="1"
            android:paddingLeft="2dp"
            android:singleLine="true"
            android:textColor="#ffffff"
            android:textColorHint="#b3ffffff" />

        <ImageView
            android:id="@+id/search_clear"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:paddingLeft="16dp"
            android:paddingRight="16dp"
            android:src="@drawable/ic_close_white_24dp" />
    </LinearLayout>
</android.support.v7.widget.Toolbar>

onCreate () dari Aktivitas Anda:

    searchContainer = findViewById(R.id.search_container);
    toolbarSearchView = (EditText) findViewById(R.id.search_view);
    searchClearButton = (ImageView) findViewById(R.id.search_clear);

    // Setup search container view
    try {
        // Set cursor colour to white
        // https://stackoverflow.com/a/26544231/1692770
        // https://github.com/android/platform_frameworks_base/blob/kitkat-release/core/java/android/widget/TextView.java#L562-564
        Field f = TextView.class.getDeclaredField("mCursorDrawableRes");
        f.setAccessible(true);
        f.set(toolbarSearchView, R.drawable.edittext_whitecursor);
    } catch (Exception ignored) {
    }

    // Search text changed listener
    toolbarSearchView.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            Fragment mainFragment = getFragmentManager().findFragmentById(R.id.container);
            if (mainFragment != null && mainFragment instanceof MainListFragment) {
                ((MainListFragment) mainFragment).search(s.toString());
            }
        }

        @Override
        public void afterTextChanged(Editable s) {
        }
    });

    // Clear search text when clear button is tapped
    searchClearButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            toolbarSearchView.setText("");
        }
    });

    // Hide the search view
    searchContainer.setVisibility(View.GONE);

Bekerja dengan baik, tampak hebat, terima kasih! Namun, alih-alih membuat tata letak dalam kode, saya membuat LinearLayout dengan EditText dan ImageView dalam xml dan hanya menggembungkannya di onCreate.
aluxian

Ya, saya mencoba melakukannya dalam XML tetapi saya pikir saya melakukan sesuatu yang salah karena Android Studio tidak akan memberi saya pelengkapan otomatis di XML layout.
Mike

Bisakah Anda memperbarui jawaban ini dengan masing-masing desain tata letak XML yang diperlukan untuk ini? yang dapat membantu orang lain dengan sangat baik.
Shreyash Mahajan

1
@Mike Bisakah Anda memperbarui jawaban Anda dan memasukkan kode sumber github lengkap Anda?
Hamed Ghadirian

1
silakan posting proyek lengkap di github
Nilabja


19

Tangkapan layar pertama dalam pertanyaan Anda bukanlah widget publik. Dukungan SearchView ( android.support.v7.widget.SearchView) meniru SearchView ( ) Android 5.0 Lollipop android.widget.SearchView. Tangkapan layar kedua Anda digunakan oleh aplikasi dengan desain material lain seperti Google Play.

SearchView di tangkapan layar pertama Anda digunakan di Drive, YouTube, dan Google Apps sumber tertutup lainnya. Untungnya, ini juga digunakan di Android 5.0 Dialer . Anda dapat mencoba mem-backport tampilan, tetapi ini menggunakan beberapa API 5.0.

Kelas-kelas yang ingin Anda lihat adalah:

SearchEditTextLayout , AnimUtils , dan DialtactsActivity untuk memahami cara menggunakan View. Anda juga akan membutuhkan sumber daya dari ContactsCommon .

Semoga berhasil.


Terima kasih telah memeriksanya, saya berharap sudah ada sesuatu di luar sana yang dapat melakukannya. Untuk saat ini saya baru saja menggunakan EditText dengan latar belakang transparan dan sepertinya ok untuk apa yang saya butuhkan.
Mike

112
Jawaban ini sangat mengganggu saya. Mengapa google menggunakan widget pribadi yang kebetulan cocok dengan pedoman desain material mereka sendiri dan kemudian menerbitkan widget jelek untuk kita yang tidak sesuai? Dan setiap pengembang sekarang di luar sana berjuang dengan ini sendiri? Alasan apa yang mungkin untuk ini?
Greg Ennis

18

Inilah upaya saya melakukan ini:

Langkah 1: Buat gaya bernama SearchViewStyle

<style name="SearchViewStyle" parent="Widget.AppCompat.SearchView">
    <!-- Gets rid of the search icon -->
    <item name="searchIcon">@drawable/search</item>
    <!-- Gets rid of the "underline" in the text -->
    <item name="queryBackground">@null</item>
    <!-- Gets rid of the search icon when the SearchView is expanded -->
    <item name="searchHintIcon">@null</item>
    <!-- The hint text that appears when the user has not typed anything -->
    <item name="queryHint">@string/search_hint</item>
</style>

Langkah 2: Buat tata letak bernama simple_search_view_item.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.SearchView
    android:layout_gravity="end"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    style="@style/SearchViewStyle"
    xmlns:android="http://schemas.android.com/apk/res/android" />  

Langkah 3: Buat item menu untuk tampilan pencarian ini

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        app:actionLayout="@layout/simple_search_view_item"
        android:title="@string/search"
        android:icon="@drawable/search"
        app:showAsAction="always" />
</menu>  

Langkah 4: Tingkatkan menu

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.menu_searchable_activity, menu);
    return true;
}  

Hasil:

masukkan deskripsi gambar di sini

Satu-satunya hal yang tidak dapat saya lakukan adalah membuatnya memenuhi seluruh lebar file Toolbar. Jika seseorang dapat membantu saya melakukan itu maka itu akan menjadi emas.


1
I wasn't able to do was to make it fill the entire width, versi pustaka dukungan mana yang Anda gunakan? Coba setel app:contentInsetStartWithNavigation="0dp"untuk Toolbar Anda.
Mangesh

@LittleChild, coba solusi yang diberikan oleh Magnesh. Jika masih belum terselesaikan maka coba tambahkan baris di bawah ini di toolbar. app: contentInsetStartWithNavigation = "0dp" app: contentInsetLeft = "0dp" app: contentInsetStart = "0dp" app: paddingStart = "0dp" android: layout_marginLeft = "0dp" android: layout_marginStart = "0dp"
Shreyash17 atajan

Terima kasih telah memberikan penjelasan untuk setiap baris di SearchViewStyle!
Shinta S

Little Child Untuk lebar keseluruhan, Anda dapat melakukan sth seperti ini: (" stackoverflow.com/questions/27946569/… )
Ali_dev

10

Untuk mendapatkan tampilan SearchView yang diinginkan, Anda dapat menggunakan gaya.

Pertama, Anda perlu membuat styleSearchView Anda, yang akan terlihat seperti ini:

<style name="CustomSearchView" parent="Widget.AppCompat.SearchView">
    <item name="searchIcon">@null</item>
    <item name="queryBackground">@null</item>
</style>

Daftar lengkap atribut yang dapat Anda temukan di artikel ini , di bawah bagian "Tampilan Pencarian".

Kedua, Anda perlu membuat styleuntuk Anda Toolbar, yang digunakan sebagai ActionBar:

<style name="ToolbarSearchView" parent="Base.ThemeOverlay.AppCompat.Dark.ActionBar">
    <item name="searchViewStyle">@style/CustomSearchView</item>
</style>

Dan terakhir, Anda perlu memperbarui atribut tema Toolbar dengan cara ini:

<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    app:theme="@style/ToolbarSearchView" />

Hasil:

masukkan deskripsi gambar di sini

CATATAN: Anda perlu mengubah Toolbaratribut tema Anda secara langsung. Jika Anda hanya memperbarui searchViewStyleatribut tema utama, itu tidak akan memengaruhi Toolbar.


Hai, apakah Anda menambahkan ikon navigate-back(panah kembali) dan cancel(x) itu sendiri atau ditambahkan secara otomatis?
Hiburan

1
@Solace mereka ditambahkan secara otomatis
Artem

Apakah mereka muncul hanya ketika Anda mulai menulis permintaan pencarian di SearchView atau apakah mereka ada bahkan ketika Anda belum menulis apa pun dan petunjuk pencarian terlihat? Saya bertanya karena milik saya tidak muncul sampai saya mulai menulis kueri. Jadi informasi ini akan sangat berguna bagi saya
Solace

1
@Solace navigate-backselalu ditampilkan, clearhanya ditampilkan setelah Anda menulis beberapa kueri penelusuran.
Artem

6

Cara lain untuk mencapai efek yang diinginkan adalah dengan menggunakan pustaka Tampilan Pencarian Material . Ini menangani riwayat pencarian secara otomatis dan memungkinkan untuk memberikan saran pencarian ke tampilan juga.

Contoh: (Ditampilkan dalam bahasa Portugis, tetapi juga berfungsi dalam bahasa Inggris dan Italia).

Sampel

Mendirikan

Sebelum Anda dapat menggunakan lib ini, Anda harus mengimplementasikan kelas yang dinamai MsvAuthoritydi dalam br.com.maukerpaket pada modul aplikasi Anda, dan harus memiliki variabel String statis publik yang dipanggil CONTENT_AUTHORITY. Berikan nilai yang Anda inginkan dan jangan lupa untuk menambahkan nama yang sama pada file manifes Anda. Lib akan menggunakan file ini untuk menyetel otoritas Penyedia Konten.

Contoh:

MsvAuthority.java

package br.com.mauker;

public class MsvAuthority {
    public static final String CONTENT_AUTHORITY = "br.com.mauker.materialsearchview.searchhistorydatabase";
}

AndroidManifest.xml

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

    <application ... >
        <provider
        android:name="br.com.mauker.materialsearchview.db.HistoryProvider"
        android:authorities="br.com.mauker.materialsearchview.searchhistorydatabase"
        android:exported="false"
        android:protectionLevel="signature"
        android:syncable="true"/>
    </application>

</manifest>

Pemakaian

Untuk menggunakannya, tambahkan dependensi:

compile 'br.com.mauker.materialsearchview:materialsearchview:1.2.0'

Dan kemudian, pada Activityfile layout Anda , tambahkan yang berikut ini:

<br.com.mauker.materialsearchview.MaterialSearchView
    android:id="@+id/search_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

Setelah itu, Anda hanya perlu mendapatkan MaterialSearchViewreferensi dengan menggunakan getViewById(), dan buka atau tutup menggunakan MaterialSearchView#openSearch()dan MaterialSearchView#closeSearch().

PS: Mungkin untuk membuka dan menutup tampilan tidak hanya dari Toolbar. openSearch()Pada dasarnya Anda dapat menggunakan metode ini dari mana saja Button, seperti Tombol Tindakan Mengambang.

// Inside onCreate()
MaterialSearchView searchView = (MaterialSearchView) findViewById(R.id.search_view);
Button bt = (Button) findViewById(R.id.button);

bt.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            searchView.openSearch();
        }
    });

Anda juga dapat menutup tampilan menggunakan tombol kembali dengan melakukan hal berikut:

@Override
public void onBackPressed() {
    if (searchView.isOpen()) {
        // Close the search on the back button press.
        searchView.closeSearch();
    } else {
        super.onBackPressed();
    }
}

Untuk informasi lebih lanjut tentang cara menggunakan lib, periksa halaman github .


2
Perpustakaan yang sangat baik, dan ide bagus untuk mengabstraksi metode buka / tutup sehingga MenuItem tidak diperlukan untuk membuka / menutupnya, saya berencana menggunakan ini di aplikasi saya dengan FloatingActionButton dengan ikon pencarian, jadi ini akan berfungsi dengan baik.
AdamMc331

Mengapa tidak ada parameter untuk string seperti 'Search'? Tampaknya perpustakaan membatasi orang untuk menggunakan string versi bahasa Inggris atau bahasa Portugis: /
Aspiring Dev

Tapi itu mungkin untuk mengubah String petunjuk dengan menggunakan gaya seperti yang dinyatakan di README. Sedangkan untuk petunjuk input suara, akan dirilis nanti: github.com/Mauker1/MaterialSearchView/issues/23
Mauker

@rpgmaker Periksa pembaruan terkini, sekarang mungkin untuk mengubah string tersebut.
Mauker

@Mauker punya ide bagaimana menyetel android: imeOptions = "actionSearch" ke EditText komponen Anda? (Saya ingin menampilkan tombol "cari" di keyboard)
Greg

2

Berikut ini akan membuat SearchView identik dengan yang ada di Gmail dan menambahkannya ke Toolbar yang diberikan. Anda hanya perlu menerapkan metode "ViewUtil.convertDpToPixel" Anda sendiri.

private SearchView createMaterialSearchView(Toolbar toolbar, String hintText) {

    setSupportActionBar(toolbar);
    ActionBar actionBar = getSupportActionBar();
    actionBar.setDisplayHomeAsUpEnabled(true);
    actionBar.setDisplayShowCustomEnabled(true);
    actionBar.setDisplayShowTitleEnabled(false);

    SearchView searchView = new SearchView(this);
    searchView.setIconifiedByDefault(false);
    searchView.setMaxWidth(Integer.MAX_VALUE);
    searchView.setMinimumHeight(Integer.MAX_VALUE);
    searchView.setQueryHint(hintText);

    int rightMarginFrame = 0;
    View frame = searchView.findViewById(getResources().getIdentifier("android:id/search_edit_frame", null, null));
    if (frame != null) {
        LinearLayout.LayoutParams frameParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        rightMarginFrame = ((LinearLayout.LayoutParams) frame.getLayoutParams()).rightMargin;
        frameParams.setMargins(0, 0, 0, 0);
        frame.setLayoutParams(frameParams);
    }

    View plate = searchView.findViewById(getResources().getIdentifier("android:id/search_plate", null, null));
    if (plate != null) {
        plate.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        plate.setPadding(0, 0, rightMarginFrame, 0);
        plate.setBackgroundColor(Color.TRANSPARENT);
    }

    int autoCompleteId = getResources().getIdentifier("android:id/search_src_text", null, null);
    if (searchView.findViewById(autoCompleteId) != null) {
        EditText autoComplete = (EditText) searchView.findViewById(autoCompleteId);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, (int) ViewUtil.convertDpToPixel(36));
        params.weight = 1;
        params.gravity = Gravity.CENTER_VERTICAL;
        params.leftMargin = rightMarginFrame;
        autoComplete.setLayoutParams(params);
        autoComplete.setTextSize(16f);
    }

    int searchMagId = getResources().getIdentifier("android:id/search_mag_icon", null, null);
    if (searchView.findViewById(searchMagId) != null) {
        ImageView v = (ImageView) searchView.findViewById(searchMagId);
        v.setImageDrawable(null);
        v.setPadding(0, 0, 0, 0);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        params.setMargins(0, 0, 0, 0);
        v.setLayoutParams(params);
    }

    toolbar.setTitle(null);
    toolbar.setContentInsetsAbsolute(0, 0);
    toolbar.addView(searchView);

    return searchView;
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.