Створення SearchView, схожого на інструкції з дизайну матеріалів


134

На даний момент я вивчаю, як перетворити додаток на Матеріальний дизайн, і зараз я трохи застряг. Додано Панель інструментів, і я зробив свій навігаційний ящик накладеним на весь вміст.

Зараз я намагаюся створити розширюваний пошук, який буде схожий на той, який міститься в матеріальних рекомендаціях : введіть тут опис зображення

Це те, що я зараз отримав, і я не можу зрозуміти, як зробити його таким, як описано вище:
Мій пошук

Це моє меню 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>

Це працює, я отримую пункт меню, який розширюється на SearchView, і я можу добре відфільтрувати свій список. Хоча це не схоже на першу картину.

Я намагався використовувати MenuItemCompat.setOnActionExpandListener()на R.id.action_searchтак що я міг би змінити значок додому до задньої стрілки, але це не схоже на роботу. Нічого не звільняється у слухача. Навіть якби це спрацьовувало, воно все одно не буде дуже близьким до першого зображення.

Як створити SearchView на новій панелі інструментів appcompat, яка виглядає як матеріальні вказівки?


6
додаток: showAsAction = "завжди | колапсActionView"
Павлос

Ви можете захотіти поглянути на мою відповідь тут: stackoverflow.com/a/41013994/5326551
shnizlon

Відповіді:


152

Це зробити насправді досить просто, якщо ви користуєтеся android.support.v7бібліотекою.

Крок 1

Оголосіть пункт меню

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

Крок - 2

Розширіть AppCompatActivityі в onCreateOptionsMenuналаштуванні 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;
    }

    ... 

}

Результат

введіть тут опис зображення

введіть тут опис зображення


2
Я відмовив, але який емулятор ви використовуєте? Я спробував це, але я не отримую navigate-backкнопку, а скоріше значок пошуку, і його відстань від лівого краю екрана не те саме, що між Xпіктограмою та правою кромкою екрана (у мене немає переповнення дії). Опублікувавте тут питання , чи можете ви в нього заглянути?
Потіха

13
це не матеріальний пошук. це лише звичайний старий пошук у панелі дій
Gopal Singh Sirvi

2
Я відповів на власне підпитання, щоб зробити його завжди видимим без необхідності натискання на кнопку пошуку, додавши рядок searchView.setIconifiedByDefault(false);до onCreateOptionsMenuфункції.
adelriosantiago

3
ще один корисний пришвидшений вигляд - якщо ви хочете, щоб перегляд пошуку було розширено, спочатку переконайтеся, що app:showAsAction="always"НЕ, і НЕapp:showAsAction="ifRoom|collapseActionView"
Vinay W

1
Крім того, використовуючи цей метод, навіть коли розширюється searchBar, OverflowIcon все ще видно (тобто 3-крапки). Але деякі програми обробляють пошук, розширивши його повністю і змінивши фон на білий. Як і GMail
Zen

83

Через тиждень спантеличує це. Я думаю, я це зрозумів.
Зараз я використовую лише EditText всередині Панелі інструментів. Це мені запропонував oj88 на reddit.

Тепер у мене є таке:
Новий SearchView

спочатку всередині onCreate () своєї діяльності я додав EditText із зображенням зображення праворуч на Панель інструментів так:

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

Це спрацювало, але потім я зіткнувся з проблемою, коли не було викликано OnOptionsItemSelected (), коли я натиснув кнопку додому. Тому я не зміг скасувати пошук, натиснувши кнопку "додому". Я спробував кілька різних способів зареєструвати слухач кліків на домашній кнопці, але вони не спрацювали.

Врешті-решт я дізнався, що у мене ActionBarDrawerToggle втручався в речі, тому я його видалив. Потім цей слухач почав працювати:

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

Тому я можу скасувати пошук за допомогою домашньої кнопки, але поки не можу натиснути кнопку "назад", щоб скасувати її. Тому я додав це до onBackPress ():

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

Я створив цей метод, щоб змінити видимість редагування тексту та елемента меню:

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

Мені знадобився спосіб перемикання кнопки додому на панелі інструментів між значком ящика та кнопкою "назад". Зрештою, я знайшов метод у цій відповіді ТА . Хоча я її трохи змінив, щоб мати більше сенсу для мене:

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

Це працює, мені вдалося розробити кілька помилок, які я знайшов по дорозі. Я не думаю, що це на 100%, але це працює досить добре для мене.

EDIT: Якщо ви хочете додати перегляд пошуку в XML замість Java, зробіть це:

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 () вашої активності:

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

Чудово працює, чудово виглядає, дякую! Однак замість створення макетів у коді я створив LinearLayout за допомогою EditText та ImageView у xml та просто надув його у onCreate.
алуксиан

Так, я спробував це зробити в XML, але я подумав, що роблю щось не так, оскільки Android Studio не дасть мені автозавершити в макеті XML.
Майк

Чи можете ви, будь ласка, оновити цю відповідь відповідним дизайном XML-макета, необхідним для цього? що може дуже добре допомогти іншим.
Шреяш Махаджан

1
@Mike Чи можете ви, будь ласка, оновити свою відповідь та додати повний вихідний код github?
Хамед Ґадіріан

1
опублікуйте повний проект у github
Нілабджа

22

Я знаю, що це стара тема, але все ще розміщую бібліотеку, яку я тільки що створив. Сподіваюся, це може комусь допомогти.

https://github.com/Shahroz16/material-searchview

Перегляд матеріалів пошуку


1
Це не важко, але мені подобається ваша робота. Це економить мій час на створення власного перегляду пошуку. Спасибі, брате!
Slim_user71169

19

Перший скріншот у вашому запитанні не є загальнодоступним віджетом. Підтримка SearchView ( android.support.v7.widget.SearchView) імітує Android 5.0 Lollipop's SearchView ( android.widget.SearchView). Ваш другий знімок екрана використовується іншими програмами, розробленими матеріалами, такими як Google Play.

Пошук у першому скріншоті використовується в Диску, YouTube та інших Google Apps із закритим джерелом. На щастя, він також використовується в наборі Android 5.0 . Ви можете спробувати підтримати подання, але для цього використовується деякі 5,0 API.

Класи, які ви хочете подивитися:

SearchEditTextLayout , AnimUtils та DialtactsActivity, щоб зрозуміти, як використовувати Перегляд. Вам також знадобляться ресурси від ContactsCommon .

Удачі.


Дякую за те, що вивчив це, я сподівався, що там уже є щось, що може це зробити. Наразі я просто використав EditText з прозорим фоном, і здається нормальним для того, що мені потрібно.
Майк

111
Ця відповідь мене дуже хвилює. Чому google використовує приватний віджет, який відповідає їх власним рекомендаціям щодо дизайну матеріалів, а потім публікує для нас відступний віджет, який цього не робить? І кожен розробник зараз бореться з цим самостійно? Які можливі міркування для цього?
Грег Енніс

18

Ось моя спроба зробити це:

Крок 1: Створіть стиль з назвою 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: Створіть макет з назвою 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: Створіть пункт меню для цього перегляду пошуку

<?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: Надуйте меню

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

Результат:

введіть тут опис зображення

Єдине, чого я не зміг зробити, це змусити його заповнити всю ширину Toolbar. Якби хтось міг допомогти мені це зробити, то це було б золото.


1
I wasn't able to do was to make it fill the entire width, яку версію бібліотеки підтримки ви використовуєте? Спробуйте встановити app:contentInsetStartWithNavigation="0dp"панель інструментів.
Менгеш

@LittleChild, спробуйте рішення, подане Магнешем. Якщо все-таки це не вирішено, спробуйте додати нижче рядки на панелі інструментів. Додаток: contentInsetStartWithNavigation = "0dp" додаток: contentInsetLeft = "0dp" додаток: contentInsetStart = "0dp" додаток: paddingStart = "0dp" андроїд: layout_marginLeft = "0dp" андроїд: layout_marginStart = "0dp"
Shreyash Mahajan

Дякуємо, що розмістили пояснення для кожного рядка в SearchViewStyle!
Shinta S

Маленька дитина Для всій ширині, ви можете зробити що- н , як це: ( » stackoverflow.com/questions/27946569 / ... )
Ali_dev

10

Щоб досягти бажаного вигляду SearchView, ви можете використовувати стилі.

Спочатку потрібно створити styleдля свого SearchView, який повинен виглядати приблизно так:

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

Цілий список атрибутів ви можете знайти в цій статті, в розділі "SearchView".

По-друге, вам потрібно створити styleдля свого Toolbar, який використовується як ActionBar:

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

І нарешті вам потрібно оновити атрибут теми Панелі інструментів таким чином:

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

Результат:

введіть тут опис зображення

ПРИМІТКА. Вам потрібно змінити Toolbarатрибут теми безпосередньо. Якщо ви просто оновите свій основний searchViewStyleатрибут теми, це не вплине на ваше Toolbar.


Привіт, ви самі додавали ці navigate-back(стрілку назад) та cancel(x) пісню або вони були автоматично додані?
Потіха

1
@Solace вони додаються автоматично
Артем

Вони з’являються лише тоді, коли ви починаєте писати пошуковий запит у SearchView або вони там є, навіть якщо ви нічого не написали, і підказка пошуку видно? Я прошу, бо мої не з’являються, поки я не почну писати запит. Тож ця інформація буде для мене дуже корисною
втішання

1
@Solace navigate-backзавжди відображається, clearвідображається лише після того, як ви написали певний пошуковий запит.
Артем

6

Ще одним способом досягнення бажаного ефекту є використання цієї бібліотеки перегляду матеріалів пошуку . Він обробляє історію пошуку автоматично, і також можна надати пропозиції для пошуку.

Зразок: (Показано португальською мовою, але він також працює англійською та італійською мовами).

Зразок

Налаштування

Перш ніж використовувати цю вкладку, ви повинні реалізувати клас, названий MsvAuthorityвсередині br.com.maukerпакету, на своєму модулі програми, і він повинен мати публічну статичну змінну String CONTENT_AUTHORITY. Надайте йому потрібне значення і не забудьте додати те саме ім’я у файл маніфесту. Lib використовуватиме цей файл для встановлення повноважень постачальника вмісту.

Приклад:

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>

Використання

Щоб використовувати його, додайте залежність:

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

А потім Activityдодайте у файл вашого макета наступне:

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

Після цього вам просто потрібно буде отримати MaterialSearchViewдовідку за допомогою getViewById()та відкрити її чи закрити за допомогою MaterialSearchView#openSearch()та MaterialSearchView#closeSearch().

PS: Можна відкривати та закривати вигляд не лише з боку Toolbar. Ви можете використовувати openSearch()метод практично з будь-якого Button, наприклад, кнопки з плаваючою дією.

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

Ви також можете закрити подання за допомогою кнопки "Назад", виконавши наступне:

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

Щоб отримати додаткові відомості про використання lib, перегляньте сторінку github .


2
Відмінна бібліотека та чудова ідея абстрагувати метод відкриття / закриття, щоб не відкривати / закривати меню MenuItem, я планую використовувати це у своєму додатку з FloatingActionButton зі значком пошуку, тому він буде чудово працювати.
AdamMc331

Чому немає параметрів для рядків типу "Пошук"? Здається, бібліотека обмежує людей англійською чи португальською версіями рядка: /
Aspiring Dev

Але можна змінити натяк на String, використовуючи стилі, як зазначено в README. Щодо підказки щодо голосового введення, вона вийде пізніше: github.com/Mauker1/MaterialSearchView/isissue/23
Mauker

@rpgmaker Перевірте останнє оновлення, тепер можна змінити ці рядки.
Маукер

@Mauker маєте ідею, як встановити android: imeOptions = "actionSearch" на EditText вашого компонента? (Я хочу відобразити на клавіатурі кнопку "Пошук")
Грег

2

Нижче буде створено SearchView, ідентичний тому, що в Gmail, і додасть його до заданої Панелі інструментів. Вам просто доведеться реалізувати власний метод "ViewUtil.convertDpToPixel".

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;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.