Malzeme tasarımı yönergelerine benzeyen bir SearchView oluşturma


134

Şu anda uygulamamı Materyal tasarımına nasıl dönüştüreceğimizi öğrenme sürecindeyim ve şu an biraz takılıp kaldım. Araç Çubuğunu ekledim ve gezinti çekmecemi tüm içeriğin üzerine yerleştirdim.

Şimdi malzeme kılavuzlarındakine benzeyen genişletilebilir bir arama oluşturmaya çalışıyorum : resim açıklamasını buraya girin

Şu anda aldığım şey bu ve yukarıdaki gibi nasıl yapacağımı anlayamıyorum:
Aramam

Bu benim menü 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>

Bu işe yarar, ben SearchView genişleyen bir menü öğesi olsun ve benim liste iyi filtre. Yine de 1. resim gibi bir şey görünmüyor.

Kullanmaya çalıştım MenuItemCompat.setOnActionExpandListener(), R.id.action_searchböylece ev simgesini geri okla değiştirebildim, ancak bu işe yaramıyor. Dinleyicide hiçbir şey işten atılmaz. Bu işe yarasa bile, hala 1. görüntüye çok yakın olmazdı.

Yeni uygulama tamamlama araç çubuğunda, malzeme yönergelerine benzeyen bir SearchView'ü nasıl oluştururum?


6
app: showAsAction = "always | collapseActionView"
Pavlos

Cevabımı burada incelemek isteyebilirsiniz: stackoverflow.com/a/41013994/5326551
shnizlon

Yanıtlar:


152

android.support.v7Kütüphane kullanıyorsanız, bunu yapmak oldukça kolaydır .

Aşama 1

Bir menü öğesi bildirme

<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" />

Adım 2

Arama Görünümü'nü genişletin AppCompatActivityve onCreateOptionsMenukurulumda.

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

    ... 

}

Sonuç

resim açıklamasını buraya girin

resim açıklamasını buraya girin


2
Onu iptal ettim, ama hangi emülatörü kullanıyorsun? Denedim ama navigate-backdüğmeyi değil, bir arama simgesi alıyorum ve ekranın sol kenarından uzaklığı, Xsimge ile ekranın sağ kenarı arasındaki mesafeyle aynı değil. eylem taşması). Soruyu burada yayınladınız , içine bakabilir misiniz?
Solace

13
önemli bir arama değil. eylem çubuğunda sadece her zamanki eski arama
Gopal Singh Sirvi

2
Ben satırı ekleyin arama butonuna tıklayın gerek kalmadan her zaman görünür kılmak için, kendi alt soruyu yanıtladı searchView.setIconifiedByDefault(false);için onCreateOptionsMenuişlevi.
adelriosantiago

3
başka bir yararlı tidbit - Eğer arama görünümünün başlangıçta genişletilmesini istiyorsanız app:showAsAction="always"ve olduğundan emin olun DEĞİLapp:showAsAction="ifRoom|collapseActionView"
Vinay W

1
Ayrıca, searchBar genişletilse bile bu yöntemi kullanarak OverflowIcon hala görülebilir (yani 3 nokta). Ancak bazı uygulamalar, aramayı tamamen genişleterek ve arka planı beyaza dönüştürerek işler. Beğen GMail
Zen

83

Bunun üzerinden bir hafta geçtikten sonra. Bence anladım.
Şimdi sadece Araç Çubuğu içinde bir EditText kullanıyorum. Bu bana reddit üzerindeki oj88 tarafından önerildi.

Şimdi bu var:
Yeni Arama Görünümü

İlk benim aktivite onCreate () içinde sağ tarafta bir görüntü görünümü ile EditText ekledi Araç Çubuğu böyle:

    // 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);

Bu işe yaradı, ama sonra ev düğmesine dokunduğumda onOptionsItemSelected () çağrılmadığı bir sorunla karşılaştım. Bu yüzden ana sayfa düğmesine basarak aramayı iptal edemedim. Tıklama dinleyicisini ana sayfa düğmesine kaydetmenin birkaç farklı yolunu denedim ancak işe yaramadı.

Sonunda ben vardı ActionBarDrawerToggle şeylere müdahale olduğunu öğrendim, bu yüzden kaldırdım. Bu dinleyici daha sonra çalışmaya başladı:

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

Şimdi ana düğmeyle aramayı iptal edebilirim, ancak henüz iptal etmek için geri düğmesine basamıyorum. Bu yüzden onBackPressed () ekledi:

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

EditText ve menü öğesinin görünürlüğünü değiştirmek için bu yöntemi oluşturdum:

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

Araç çubuğundaki ana sayfa düğmesini çekmece simgesi ile geri düğmesi arasında değiştirmek için bir yola ihtiyacım vardı. Sonunda bu SO cevabında aşağıdaki yöntemi buldum . Bana biraz mantıklı gelmesi için biraz değiştirmiş olmama rağmen:

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

Bu işe yarıyor, yol boyunca bulduğum birkaç hatayı çözmeyi başardım. % 100 olduğunu sanmıyorum ama benim için yeterince iyi çalışıyor.

EDIT: Arama görünümünü Java yerine XML olarak eklemek istiyorsanız, bunu yapın:

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>

Faaliyetinizin onCreate () yöntemi:

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

Harika çalışıyor, harika görünüyor, teşekkürler! Ancak, kod düzenleri oluşturmak yerine, xml içinde EditText ve ImageView ile LinearLayout oluşturdum ve sadece onCreate içinde şişirilmiş.
aluxian

Evet, XML'de yapmaya çalıştım ama Android Studio'nun düzen XML'de otomatik tamamlama vermediği için yanlış bir şey yaptığımı düşündüm.
Mike

Bu cevabı lütfen bunun için gerekli XML düzen tasarımıyla güncelleyebilir misiniz? diğerlerine çok yardımcı olabilir.
Shreyash Mahajan

1
@ Lütfen yanıtınızı güncelleyip eksiksiz github kaynak kodunuzu yazabilir misiniz?
Hamed Ghadirian

1
lütfen projenin tamamını
github'da yayınlayın


19

Sorunuzdaki ilk ekran görüntüsü herkese açık bir widget değil. Destek SearchView ( android.support.v7.widget.SearchView), Android 5.0 Lollipop'un SearchView ( ) işlevini taklit eder android.widget.SearchView. İkinci ekran görüntünüz Google Play gibi diğer materyal tasarımlı uygulamalar tarafından kullanılır.

İlk ekran görüntünüzdeki SearchView, Drive, YouTube ve diğer kapalı kaynaklı Google Apps'ta kullanılır. Neyse ki, Android 5.0 Dialer'da da kullanılıyor . Görünümü geri yüklemeyi deneyebilirsiniz, ancak bazı 5.0 API'ları kullanır.

Bakmak isteyeceğiniz sınıflar:

Görünümün nasıl kullanılacağını anlamak için SearchEditTextLayout , AnimUtils ve DialtactsActivity . ContactsCommon'dan kaynaklara da ihtiyacınız olacak .

İyi şanslar.


Buna baktığınız için teşekkürler, zaten orada yapabilecek bir şey olmasını umuyordum. Şimdilik şeffaf bir arka plana sahip bir EditText kullandım ve ihtiyacım olan şey için iyi görünüyor.
Mike

111
Bu cevap beni çok rahatsız ediyor. Google neden kendi malzeme tasarım yönergelerine uygun özel bir widget kullanıyor ve sonra bizim için olmayan bir crappy widget yayınlıyor? Ve her geliştirici şimdi bununla kendi başına mücadele mi ediyor? Bunun için ne gibi bir sebep var?
Greg Ennis

18

İşte bunu yapmaya teşebbüsüm:

1. Adım: adlı bir stil oluşturun 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>

2. Adım: adlı bir düzen oluşturun 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" />  

3. Adım: Bu arama görünümü için bir menü öğesi oluşturun

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

4. Adım: Menüyü şişirin

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

Sonuç:

resim açıklamasını buraya girin

Yapamadığım tek şey, tüm genişliği doldurmak oldu Toolbar. Birisi bunu yapmama yardım edebilseydi, o zaman bu altın olurdu.


1
I wasn't able to do was to make it fill the entire width, hangi destek kitaplığı sürümünü kullanıyorsunuz? app:contentInsetStartWithNavigation="0dp"Araç Çubuğunuz için ayar yapmayı deneyin .
Mangesh

@LittleChild, Magnesh tarafından verilen çözümü deneyin. Hala çözülmediyse, araç çubuğuna aşağıdaki satırları eklemeyi deneyin. app: contentInsetStartWithNavigation = "0DP" app: contentInsetLeft = "0DP" app: contentInsetStart = "0DP" app: paddingStart = "0DP" android: layout_marginLeft = "0DP" android: layout_marginStart = "0DP"
Shreyash Mahajan

SearchViewStyle'daki her satır için açıklama yaptığınız için teşekkür ederiz!
Shinta S

Küçük Çocuk Tüm genişlik için şu şekilde yapabilirsiniz: (" stackoverflow.com/questions/27946569/… )
Ali_dev

10

İstenilen SearchView görünümünü elde etmek için stilleri kullanabilirsiniz.

İlk olarak, styleSearchView'iniz için böyle bir şeye benzemesi gerekir:

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

Bu makalede "SearchView" bölümünün altında bulabileceğiniz özelliklerin listesi .

İkincisi, ActionBar olarak kullanılan bir stylesizin için bir oluşturmanız gerekir Toolbar:

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

Son olarak, Araç Çubuğu tema özelliğinizi bu şekilde güncellemeniz gerekir:

<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" />

Sonuç:

resim açıklamasını buraya girin

NOT: ToolbarTema özelliğinizi doğrudan değiştirmeniz gerekir . Ana tema searchViewStyleözelliğinizi güncelleyecek olursanız, bu durum sizi etkilemez Toolbar.


Hey navigate-back(geri ok) ve cancel(x) simgelerini kendiniz mi eklediniz yoksa otomatik olarak eklendi mi?
Solace

1
@Solace otomatik olarak eklenir
Artem

Yalnızca SearchView'de arama sorgusu yazmaya başladığınızda mı görünüyorsunuz yoksa hiçbir şey yazmamış olsanız ve arama ipucu görünür olsalar da oradalar mı? Sorgu yazmaya başlayana kadar benim görünmüyor çünkü soruyorum. Bu yüzden bu bilgiler benim için çok yararlı olacak
Solace

1
@Solace navigate-backher zaman gösterilir, clearyalnızca bir arama sorgusu yazdıktan sonra gösterilir.
Artem

6

İstenen efekti elde etmenin başka bir yolu, bu Malzeme Arama Görünümü kitaplığını kullanmaktır . Arama geçmişini otomatik olarak işler ve görünüme de arama önerileri sunmak mümkündür.

Örnek: (Portekizce olarak gösterilir, ancak İngilizce ve İtalyanca olarak da çalışır).

Örneklem

Kurmak

Bu lib'i kullanabilmeniz için, uygulama modülünüzde paketin MsvAuthorityiçinde bir sınıf br.com.maukeruygulamanız gerekir ve bu adın genel statik String değişkenine sahip olması gerekir CONTENT_AUTHORITY. İstediğiniz değeri verin ve manifest dosyanıza aynı adı eklemeyi unutmayın . Lib, İçerik Sağlayıcı yetkisini ayarlamak için bu dosyayı kullanır.

Misal:

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>

kullanım

Kullanmak için bağımlılığı ekleyin:

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

Ardından, Activitydüzen dosyanıza aşağıdakileri ekleyin:

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

Bundan sonra, sadece almak gerekir MaterialSearchViewkullanarak referansı getViewById(), ve o kadar açık veya kullanarak kapatın MaterialSearchView#openSearch()ve MaterialSearchView#closeSearch().

Not: Görünümü yalnızca 'den açıp kapatmak mümkün değil Toolbar. openSearch()Yöntemi, ButtonYüzer Eylem Düğmesi gibi herhangi birinden kullanabilirsiniz .

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

Aşağıdakileri yaparak görünümü geri düğmesini kullanarak da kapatabilirsiniz:

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

Lib'in kullanımı hakkında daha fazla bilgi için github sayfasını kontrol edin .


2
Mükemmel kütüphane ve açmak / kapatmak için bir MenuItem gerekmemesi için açma / kapama yöntemini soyutlamak için harika bir fikir, bunu bir arama simgesiyle bir FloatingActionButton ile uygulamamda kullanmayı planlıyorum, bu yüzden harika çalışacak.
AdamMc331

Neden 'Ara' gibi dizeler için parametreler yok? Kütüphane insanları dizenin ingilizce veya portekizce sürümleriyle sınırlıyor gibi görünüyor: /
Aspiring Dev

Ancak ipucu String'i README'de belirtildiği gibi stilleri kullanarak değiştirmek mümkündür. Ses girişi ipucuna gelince, daha sonra yayınlanacak: github.com/Mauker1/MaterialSearchView/issues/23
Mauker

@rpgmaker En son güncellemeyi kontrol edin, bu dizeleri değiştirmek artık mümkün.
Mauker

@Mauker nasıl android ayarlamak için herhangi bir fikir: imeOptions = "actionSearch" bileşen EditText için? (Klavyede bir "arama" düğmesi görüntülemek istiyorum)
Greg

2

Aşağıdakiler, Gmail'deki ile aynı bir SearchView oluşturur ve bunu verilen Araç Çubuğuna ekler. Sadece kendi "ViewUtil.convertDpToPixel" yöntemini uygulamanız gerekir.

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;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.