Mise en œuvre de SearchView conformément aux lignes directrices sur la conception du matériel

j'ai cherché des moyens de mettre en œuvre un searchview dans la barre d'outils des activités (barre d'action) conformément aux lignes directrices sur la conception des matériaux.

en cliquant sur l'icône de recherche, toute la barre d'outils s'anime pour avoir seulement le texte de recherche avec le fond blanc avec des suggestions apparaissant dans la vue principale au lieu d'un drop down.

Voici une capture d'écran des lignes directrices: enter image description here

voici un gif de la mise en œuvre de la boîte de réception Gmail: enter image description here

j'ai été à la recherche d'exemples de code et de tutoriels, mais jusqu'à présent, je n'ai pas réussi. Comment dois-je faire?

30
demandé sur GunnerFan 2015-05-21 12:07:49

7 réponses

j'ai essayé plusieurs bibliothèques SearchView, mais aucune d'elles n'a fonctionné aussi bien que celle de la bibliothèque de soutien, donc j'ai décidé de la redessiner, après beaucoup de travail, je suis satisfait du résultat:

enter image description here

, Voici comment vous pouvez le faire:

1) Ajouter l'article SearchView à votre menu

<item
    android:id="@+id/m_search"
    android:icon="@drawable/ic_action_search"
    android:title="@string/search_title"
    app:actionLayout="@layout/search_view_layout"
    app:showAsAction="ifRoom|collapseActionView" />

notez que je déclare actionLayout au lieu de actionViewClass , j'ai pensé que c'était la seule façon de définir le thème SearchView séparément du thème Toolbar.

search_view_layout.xml:

<android.support.v7.widget.SearchView
    android:id="@+id/search_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/SearchViewTheme" />

2) Ajoutez le thème personnalisé SearchView à vos styles, déclarez le thème SearchView dans votre thème de la barre d'outils ainsi:

<style name="SearchViewTheme" parent="Widget.AppCompat.SearchView.ActionBar">
    <item name="layout">@layout/toolbar_search_view</item>
    <item name="commitIcon">@drawable/ic_search_commit</item>
    <item name="colorControlNormal">@color/material_light_active_icon</item>
    <item name="colorControlHighlight">@color/material_ripple_light</item>
    <item name="autoCompleteTextViewStyle">@style/AutoCompleteTextViewStyle</item>
    <item name="suggestionRowLayout">@layout/search_view_suggestion_row</item>
    <item name="android:maxWidth">9999dp</item>
</style>

<style name="AutoCompleteTextViewStyle" parent="Widget.AppCompat.Light.AutoCompleteTextView">
    <item name="android:popupBackground">@drawable/search_suggestions_bg</item>
    <item name="android:popupElevation">0dp</item>
</style>

<style name="ToolbarTheme" parent="ThemeOverlay.AppCompat.Dark.ActionBar">
    <item name="searchViewStyle">@style/SearchViewTheme</item>
</style>

toolbar_search_view.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/search_bar"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:paddingEnd="8dp">

<!-- This is actually used for the badge icon *or* the badge label (or neither) -->
<TextView
    android:id="@+id/search_badge"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_marginBottom="2dp"
    android:drawablePadding="0dp"
    android:gravity="center_vertical"
    android:textAppearance="?android:attr/textAppearanceMedium"
    android:textColor="?android:attr/textColorPrimary"
    android:visibility="gone" />

<ImageView
    android:id="@+id/search_button"
    style="?attr/actionButtonStyle"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="center_vertical"
    android:contentDescription="@string/abc_searchview_description_search"
    android:focusable="true" />

<LinearLayout
    android:id="@+id/search_edit_frame"
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="1"
    android:layoutDirection="locale"
    android:orientation="horizontal">

    <ImageView
        android:id="@+id/search_mag_icon"
        style="@style/RtlOverlay.Widget.AppCompat.SearchView.MagIcon"
        android:layout_width="@dimen/abc_dropdownitem_icon_width"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:scaleType="centerInside"
        android:visibility="gone" />

    <!-- Inner layout contains the app icon, button(s) and EditText -->
    <LinearLayout
        android:id="@+id/search_plate"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_gravity="center_vertical"
        android:layout_weight="1"
        android:orientation="horizontal">

        <view
            android:id="@+id/search_src_text"
            class="android.support.v7.widget.SearchView$SearchAutoComplete"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_gravity="center_vertical"
            android:layout_marginEnd="@dimen/item_list_horizontal_margin"
            android:layout_marginStart="@dimen/item_list_horizontal_margin"
            android:layout_weight="1"
            android:background="@null"
            android:dropDownAnchor="@id/anchor_dropdown"
            android:dropDownHeight="wrap_content"
            android:dropDownHorizontalOffset="0dp"
            android:dropDownVerticalOffset="0dp"
            android:ellipsize="end"
            android:imeOptions="actionSearch"
            android:inputType="text|textAutoComplete|textNoSuggestions"
            android:maxLines="1"
            android:paddingEnd="8dp"
            android:textColor="@android:color/black"
            android:textColorHint="@color/material_light_hint_text"
            android:textSize="20sp" />

        <ImageView
            android:id="@+id/search_close_btn"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="center_vertical"
            android:background="?attr/selectableItemBackgroundBorderless"
            android:contentDescription="@string/abc_searchview_description_clear"
            android:focusable="true"
            android:paddingEnd="8dp"
            android:paddingStart="8dp" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/submit_area"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/search_go_btn"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="center_vertical"
            android:background="?attr/selectableItemBackgroundBorderless"
            android:contentDescription="@string/abc_searchview_description_submit"
            android:focusable="true"
            android:paddingEnd="8dp"
            android:paddingStart="8dp"
            android:visibility="gone" />

        <ImageView
            android:id="@+id/search_voice_btn"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="center_vertical"
            android:background="?attr/selectableItemBackgroundBorderless"
            android:contentDescription="@string/abc_searchview_description_voice"
            android:focusable="true"
            android:paddingEnd="8dp"
            android:paddingStart="8dp"
            android:visibility="gone" />
    </LinearLayout>
</LinearLayout>

notez que j'ai ajouté anchor dropdown view sous la vue barre d'outils, de sorte que les suggestions obtiendront la pleine largeur de l'écran.

<android.support.design.widget.AppBarLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/appBar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    app:collapseIcon="@drawable/ic_search_collapse"
    app:popupTheme="@style/AppTheme.PopupOverlay"
    app:theme="@style/ToolbarTheme" />

<View
    android:id="@+id/anchor_dropdown"
    android:layout_width="match_parent"
    android:layout_height="0dp" />

</android.support.design.widget.AppBarLayout>

search_view_suggestion_row.xml:

(changement suggestion_divider visibilité si vous voulez diviseur entre les suggestions):

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="58dp"
    android:theme="@style/Theme.AppCompat.DayNight">

<!-- Icons come first in the layout, since their placement doesn't depend on
     the placement of the text views. -->
<ImageView
    android:id="@android:id/icon1"
    style="@style/RtlOverlay.Widget.AppCompat.Search.DropDown.Icon1"
    android:layout_width="56dp"
    android:layout_height="56dp"
    android:layout_alignParentBottom="true"
    android:layout_alignParentTop="true"
    android:scaleType="centerInside"
    android:visibility="invisible" />

<ImageView
    android:id="@+id/edit_query"
    style="@style/RtlOverlay.Widget.AppCompat.Search.DropDown.Query"
    android:layout_width="56dp"
    android:layout_height="56dp"
    android:layout_alignParentBottom="true"
    android:layout_alignParentTop="true"
    android:background="?attr/selectableItemBackground"
    android:scaleType="centerInside"
    android:visibility="gone" />

<ImageView
    android:id="@id/android:icon2"
    style="@style/RtlOverlay.Widget.AppCompat.Search.DropDown.Icon2"
    android:layout_width="56dp"
    android:layout_height="56dp"
    android:layout_alignParentBottom="true"
    android:layout_alignParentTop="true"
    android:layout_alignWithParentIfMissing="true"
    android:scaleType="centerInside"
    android:visibility="gone" />

<!-- The subtitle comes before the title, since the height of the title depends on whether the
     subtitle is visible or gone. -->
<TextView
    android:id="@android:id/text2"
    style="?android:attr/dropDownItemStyle"
    android:layout_width="match_parent"
    android:layout_height="29dp"
    android:layout_alignParentBottom="true"
    android:layout_alignWithParentIfMissing="true"
    android:gravity="top"
    android:maxLines="1"
    android:paddingBottom="4dp"
    android:textColor="?android:textColorSecondary"
    android:textSize="12sp"
    android:visibility="gone" />

<!-- The title is placed above the subtitle, if there is one. If there is no
     subtitle, it fills the parent. -->
<TextView
    android:id="@android:id/text1"
    style="?android:attr/dropDownItemStyle"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_above="@android:id/text2"
    android:layout_centerVertical="true"
    android:ellipsize="end"
    android:maxLines="1"
    android:scrollHorizontally="false"
    android:textColor="?android:textColorPrimary"
    android:textSize="16sp" />

<View
    android:id="@+id/suggestion_divider"
    android:layout_width="match_parent"
    android:layout_height="0.5dp"
    android:layout_alignParentBottom="true"
    android:layout_alignStart="@android:id/text1"
    android:layout_marginStart="8dp"
    android:background="@color/divider_color"
    android:visibility="gone" />

le fond de suggestions et l'icône de propagation sont faits sur mesure, le reste des icônes I utilisé peut être trouvé à: https://material.io/icons/

ic_search_commit.xml:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:autoMirrored="true"
    android:viewportHeight="24.0"
    android:viewportWidth="24.0">
    <path
        android:fillColor="@color/active_icon_color"
        android:pathData="m18.364,16.95l-8.605,-8.605l7.905,-0l-0.007,-2.001l-11.314,0l0,11.314l1.994,-0l0.007,-7.898l8.605,8.605l1.414,-1.414z" />

search_suggestions_bg.xml:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
    <shape android:shape="rectangle">
        <padding android:top="0.5dp" />
        <stroke
            android:width="0.5dp"
            android:color="@color/divider_color" />
    </shape>
</item>
<item>
    <shape android:shape="rectangle">
        <solid android:color="@color/cards_and_dialogs_color" />
    </shape>
</item>

ajoutez les valeurs suivantes à vos couleurs.xml (ajouter des valeurs de la nuit que si vous utilisez du jour-nuit thème):

valeurs/couleurs.xml

<color name="material_light_primary_text">#DE000000</color>
<color name="material_light_hint_text">#61000000</color>
<color name="material_light_active_icon">#8A000000</color>
<color name="material_ripple_light">#1F000000</color>
<color name="divider_color">#1F000000</color>
<color name="active_icon_color">#8A000000</color>
<color name="cards_and_dialogs_color">@android:color/white</color>
<color name="quantum_grey_600">#757575</color>

les valeurs de la nuit et les couleurs.xml:

<color name="divider_color">#1FFFFFFF</color>
<color name="active_icon_color">@android:color/white</color>
<color name="cards_and_dialogs_color">#424242</color>

3) la Dernière partie, que la magie se produise dans le code:

configurer et initialiser SearchView dans l'activité désirée

private MenuItem mSearchItem;
private Toolbar mToolbar;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    mToolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(mToolbar);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);

    mSearchItem = menu.findItem(R.id.m_search);

    MenuItemCompat.setOnActionExpandListener(mSearchItem, new MenuItemCompat.OnActionExpandListener() {
        @Override
        public boolean onMenuItemActionCollapse(MenuItem item) {
            // Called when SearchView is collapsing
            if (mSearchItem.isActionViewExpanded()) {
                animateSearchToolbar(1, false, false);
            }
            return true;
        }

        @Override
        public boolean onMenuItemActionExpand(MenuItem item) {
            // Called when SearchView is expanding
            animateSearchToolbar(1, true, true);
            return true;
        }
    });

    return true;
}

public void animateSearchToolbar(int numberOfMenuIcon, boolean containsOverflow, boolean show) {

    mToolbar.setBackgroundColor(ContextCompat.getColor(this, android.R.color.white));
    mDrawerLayout.setStatusBarBackgroundColor(ContextCompat.getColor(this, R.color.quantum_grey_600));

    if (show) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            int width = mToolbar.getWidth() -
                    (containsOverflow ? getResources().getDimensionPixelSize(R.dimen.abc_action_button_min_width_overflow_material) : 0) -
                    ((getResources().getDimensionPixelSize(R.dimen.abc_action_button_min_width_material) * numberOfMenuIcon) / 2);
            Animator createCircularReveal = ViewAnimationUtils.createCircularReveal(mToolbar,
                    isRtl(getResources()) ? mToolbar.getWidth() - width : width, mToolbar.getHeight() / 2, 0.0f, (float) width);
            createCircularReveal.setDuration(250);
            createCircularReveal.start();
        } else {
            TranslateAnimation translateAnimation = new TranslateAnimation(0.0f, 0.0f, (float) (-mToolbar.getHeight()), 0.0f);
            translateAnimation.setDuration(220);
            mToolbar.clearAnimation();
            mToolbar.startAnimation(translateAnimation);
        }
    } else {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            int width = mToolbar.getWidth() -
                    (containsOverflow ? getResources().getDimensionPixelSize(R.dimen.abc_action_button_min_width_overflow_material) : 0) -
                    ((getResources().getDimensionPixelSize(R.dimen.abc_action_button_min_width_material) * numberOfMenuIcon) / 2);
            Animator createCircularReveal = ViewAnimationUtils.createCircularReveal(mToolbar,
                    isRtl(getResources()) ? mToolbar.getWidth() - width : width, mToolbar.getHeight() / 2, (float) width, 0.0f);
            createCircularReveal.setDuration(250);
            createCircularReveal.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
                    mToolbar.setBackgroundColor(getThemeColor(MainActivity.this, R.attr.colorPrimary));
                    mDrawerLayout.setStatusBarBackgroundColor(getThemeColor(MainActivity.this, R.attr.colorPrimaryDark));
                }
            });
            createCircularReveal.start();
        } else {
            AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.0f);
            Animation translateAnimation = new TranslateAnimation(0.0f, 0.0f, 0.0f, (float) (-mToolbar.getHeight()));
            AnimationSet animationSet = new AnimationSet(true);
            animationSet.addAnimation(alphaAnimation);
            animationSet.addAnimation(translateAnimation);
            animationSet.setDuration(220);
            animationSet.setAnimationListener(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {

                }

                @Override
                public void onAnimationEnd(Animation animation) {
                    mToolbar.setBackgroundColor(getThemeColor(MainActivity.this, R.attr.colorPrimary));
                }

                @Override
                public void onAnimationRepeat(Animation animation) {

                }
            });
            mToolbar.startAnimation(animationSet);
        }
        mDrawerLayout.setStatusBarBackgroundColor(getThemeColor(MainActivity.this, R.attr.colorPrimaryDark));
    }
}

private boolean isRtl(Resources resources) {
    return resources.getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
}

private static int getThemeColor(Context context, int id) {
    Resources.Theme theme = context.getTheme();
    TypedArray a = theme.obtainStyledAttributes(new int[]{id});
    int result = a.getColor(0, 0);
    a.recycle();
    return result;
}

peu de choses à noter au sujet du code:

1) l'animation ajustera son point de départ en fonction de votre ensemble d'éléments de menu et si la barre d'outils a l'icône de débordement, elle détectera si la mise en page est LTR ou RTL automatiquement.

2) j'utilise l'activité de tiroir de navigation, donc j'ai mis la couleur de StatusBar à mDrawerLayout, si vous utilisez l'activité régulière, vous pouvez définir la couleur de StatusBar de cette façon:

getWindow().setStatusBarColor(ContextCompat.getColor(this, R.color.quantum_grey_600));

3) l'animation circulaire reveal ne fonctionnera que sur KitKat et au-dessus.

73
répondu shnizlon 2018-06-27 08:14:09

Il est en fait assez facile à faire, si vous utilisez android.soutien.v7 bibliothèque.

Étape 1

déclare un élément de 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" />

Étape-2

étendre AppCompatActivity et dans les onceateoptionsmenu configurer la 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;
    }

    ... 
}
9
répondu Jigar Brahmbhatt 2016-07-03 23:32:24

l'idée est très simple - vous devez écrire votre propre AutoCompleteTextView en utilisant EditText, TextWatcher et RecyclerView avec un adaptateur filtrable.

  • EditText vous donne un champ de texte avec la capacité d'entrer des caractères
  • TextWatcher vous permet de surveiller les changements de texte
  • RecyclerView peut être placé n'importe où, de sorte que vous pouvez montrer les résultats de la recherche juste comme sur votre capture d'écran
  • L'adaptateur filtrable aide à présenter des données filtrées avec le texte entré

:

  • faites une mise en page avec EditText sur le dessus, avec RecyclerView remplir l'espace restant. Ajouter l'icône, l'ombre,etc.
  • ajouter un TextWatcher et mettre à jour l'adaptateur sur chaque changement de texte

si vous souhaitez voir ma solution en action, consultez mon projet sur github: https://github.com/ZieIony/Carbon

la démo complète peut être sonore dans l'application sample dans la section 'Demos'.

Screenshot

7
répondu Zielony 2015-05-21 10:24:19

prenant un indice de la réponse de @Zielony j'ai fait ce qui suit:

1) au lieu de cela, si j'utilise une barre D'Actionou une barre D'outils, j'ai construit ma propre mise en page (essentiellement un RelativeLayout avec menu burger, recherche et autres boutons de menu et un texte D'édition pour la recherche)

2) a utilisé un thème sans barre D'action, placé ma disposition personnalisée au sommet de l'activité de sorte qu'il semble comme une barre d'action.

3) dans le bouton de recherche OnClickListener I do 2 choses:

  • Masquer les boutons du menu et afficher le texte de recherche.
  • Ajouter un fragment pour afficher des suggestions de recherche et de recherche
  • Afficher le clavier d'entrée

3) Ajout D'OnClickListeners pour les autres boutons de menu.

4) a ajouté un correcteur de texte sur L'EditText 'search' pour afficher les conseils de recherche et les résultats du serveur.

C'est comment il apparaît maintenant: enter image description here

5
répondu GunnerFan 2015-06-22 14:00:28

je crois que j'ai compris. J'utilise maintenant juste un texte D'édition à l'intérieur de la barre d'outils.

j'ai maintenant ceci:

enter image description here

tout D'abord à l'intérieur de onCreate() de mon activité j'ai ajouté L'EditText avec une vue d'image sur le côté droit à la barre D'outils comme ceci:

// 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
    // http://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) {
        // http://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);

cela a fonctionné, mais ensuite je suis tombé sur un problème où une option a été sélectionnée() on ne m'a pas appelé quand j'ai tapé sur le bouton. Donc je n'ai pas pu annuler la recherche en appuyant sur le bouton Accueil. J'ai essayé quelques différentes façons d'enregistrer le click listener sur le bouton home mais elles n'ont pas fonctionné.

finalement j'ai découvert que L'action Bardrawertoggle que j'avais interférait avec les choses, donc je l'ai enlevé. Cet auditeur a alors commencé à travailler:

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

donc je peux maintenant annuler la recherche avec le bouton Accueil, mais je ne pouvez pas appuyer sur le bouton retour pour annuler. J'ai donc ajouté ceci à 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;
    }
}

j'ai créé cette méthode pour changer la visibilité de L'item EditText et 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);
    }
}

j'avais besoin d'un moyen pour basculer le bouton home sur la barre d'outils entre l'icône du tiroir et le bouton back. J'ai finalement trouvé la méthode ci-dessous dans cette réponse. Bien que je l'ai légèrement modifié pour faire plus de sens pour moi:

private enum ActionDrawableState
{
  BURGER, ARROW 
}

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

This ça marche, j'ai réussi à trouver quelques bugs que j'ai trouvés en cours de route. Je ne pense pas que ce soit 100% mais ça marche assez bien pour moi. Modifier: si vous voulez ajouter la vue de recherche en XML au lieu de Java faites ceci:

barre d'outils.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>

onCreate() de votre Activité:

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
    // http://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);
2
répondu Jigar Brahmbhatt 2015-12-31 13:25:55

, Voici comment j'ai essayé de mettre en œuvre, s'il vous plaît vérifier cela.

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

Meterial Search View

2
répondu ShahrozKhan91 2016-01-14 12:52:52

vous pouvez utiliser AutoCompleteTextView pour ce faire, Suivez le lien ci-dessous

comment construire Gmail comme la boîte de recherche dans la barre d'action?

0
répondu Vinay Jayaram 2017-05-23 12:18:20