सामग्री डिजाइन दिशानिर्देशों की तरह दिखने वाला 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>

यह काम करता है, मुझे एक मेनू आइटम मिलता है जो सर्च व्यू तक फैलता है और मैं अपनी सूची को ठीक कर सकता हूं। यह हालांकि 1 तस्वीर की तरह कुछ भी नहीं दिखता है।

मैं का उपयोग करने की कोशिश की MenuItemCompat.setOnActionExpandListener()पर R.id.action_searchतो मैं वापस तीर के लिए होम आइकन को बदल सकता है, लेकिन यह काम करने के लिए प्रतीत नहीं होता। श्रोता में कुछ भी निकाल नहीं दिया जाता है। यहां तक ​​कि अगर यह काम किया है यह अभी भी 1 छवि के बहुत करीब नहीं होगा।

मैं नए Appcompat टूलबार में SearchView कैसे बना सकता हूं जो सामग्री दिशानिर्देशों की तरह दिखता है?


6
app: showAsAction = "हमेशा | पतनActionView"
Pavlos

आप यहाँ मेरे जवाब पर एक नज़र डालना चाहते हैं: stackoverflow.com/a/41013994/5326551
shnizlon 10

जवाबों:


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
यह एक भौतिक खोज नहीं है। यह एक्शन बार में केवल सामान्य पुरानी खोज है
गोपाल सिंह सिरवी

2
मैंने अपने स्वयं के उप-प्रश्न का उत्तर दिया, यह खोज बटन पर क्लिक करने की आवश्यकता के बिना हमेशा दिखाई searchView.setIconifiedByDefault(false);देने के लिए onCreateOptionsMenuफ़ंक्शन में लाइन जोड़ें ।
एडेल्रियोसेंटियागो

3
एक और उपयोगी tidbit - यदि आप चाहते हैं कि खोज दृश्य का विस्तार किया जाए तो शुरू में सुनिश्चित करें कि आपके पास है app:showAsAction="always"और नहींapp:showAsAction="ifRoom|collapseActionView"
विनय डब्ल्यू

1
इस विधि का उपयोग करते हुए भी, जब खोजकर्ता का विस्तार किया जाता है, तब भी ओवरफ़्लोइकॉन अभी भी दिखाई देता है (यानी, 3-डॉट्स)। लेकिन कुछ ऐप, इसे पूरी तरह से बढ़ाकर और बैकग्राउंड को व्हाइट में बदलकर सर्च को हैंडल करते हैं। जैसे GMail
ज़ेन

83

इस पर एक सप्ताह के पज़लिंग के बाद। मुझे लगता है कि मैंने इसका पता लगा लिया है।
मैं अब टूलबार के अंदर सिर्फ एक EditText का उपयोग कर रहा हूं। यह मुझे reddit पर oj88 द्वारा सुझाया गया था।

अब मेरे पास यह है:
नया खोज दृश्य

सबसे पहले मेरी गतिविधि के अंदर () मैंने इस तरह से टूलबार के दाहिने हाथ की तरफ एक छवि दृश्य के साथ 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));
        }
    });

इसलिए मैं अब होम बटन के साथ खोज को रद्द कर सकता हूं, लेकिन मैं इसे रद्द करने के लिए बैक बटन दबा नहीं सकता। इसलिए मैंने इसे 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;
        }
    }

मैंने EditText और मेनू आइटम की दृश्यता को टॉगल करने के लिए यह विधि बनाई:

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% है लेकिन यह मेरे लिए काफी अच्छा है।

संपादित करें: यदि आप जावा के बजाय XML में खोज दृश्य जोड़ना चाहते हैं, तो यह करें:

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>

आपकी गतिविधि का विवरण:

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

महान काम करता है, बहुत अच्छा लगता है, धन्यवाद! हालांकि, कोड में लेआउट बनाने के बजाय, मैंने LinTLayout को EditText और ImageView को xml में बनाया और बस इसे onCreate में फुलाया।
एल्युसियन

हाँ, मैंने इसे एक्सएमएल में करने की कोशिश की लेकिन मुझे लगा कि मैं कुछ गलत कर रहा हूं क्योंकि एंड्रॉइड स्टूडियो मुझे लेआउट एक्सएमएल में स्वत: पूर्ण नहीं देगा।
माइक

क्या आप इसके लिए आवश्यक XML लेआउट डिज़ाइन के साथ इस उत्तर को अपडेट कर सकते हैं? जो दूसरे की बहुत मदद कर सकता है।
श्रेयांश महाजन

1
@ माइक क्या आप अपने उत्तर को अपडेट कर सकते हैं और अपना पूरा जीथूब सोर्स कोड डाल सकते हैं?
ग़दीरियन

1
कृपया पूरी परियोजना को github में पोस्ट करें
नीलाब्जा

22

मैं इसके पुराने धागे को जानता हूं, लेकिन अभी भी मैंने जो लाइब्रेरी बनाई है, उसे पोस्ट कर रहा हूं। आशा है कि यह किसी की मदद कर सकता है।

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

मैटरियल खोज दृश्य


1
यह मुश्किल नहीं है, लेकिन मुझे आपका काम पसंद है। यह मेरा अपना खोज बनाने के लिए अपना समय बचाता है। धन्यवाद भाई!
स्लिम_युसर 69११६

19

आपके प्रश्न का पहला स्क्रीनशॉट सार्वजनिक विजेट नहीं है। समर्थन SearchView ( android.support.v7.widget.SearchView) Android 5.0 लॉलीपॉप के SearchView ( android.widget.SearchView) की नकल करता है । आपका दूसरा स्क्रीनशॉट Google Play जैसे अन्य सामग्री डिज़ाइन किए गए एप्लिकेशन द्वारा उपयोग किया जाता है।

आपके पहले स्क्रीनशॉट में SearchView का उपयोग Drive, YouTube और अन्य बंद स्रोत Google Apps में किया जाता है। सौभाग्य से, यह एंड्रॉइड 5.0 डायलर में भी उपयोग किया जाता है । आप दृश्य को वापस लाने का प्रयास कर सकते हैं, लेकिन यह कुछ 5.0 एपीआई का उपयोग करता है।

जिन वर्गों को आप देखना चाहेंगे, वे हैं:

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"अपने टूलबार के लिए सेटिंग का प्रयास करें ।
मंगेश

@ लिटिलचाइल्ड, मैग्नेश द्वारा दिए गए समाधान का प्रयास करें। यदि फिर भी यह हल नहीं हो रहा है तो टूलबार में नीचे की पंक्तियों को जोड़ने का प्रयास करें। एप्लिकेशन: contentInsetStartWithNavigation = "0dp" ऐप्स: contentInsetLeft = "0dp" ऐप्स: contentInsetStart = "0dp" ऐप्स: paddingStart = "0dp" एंड्रॉयड: layout_marginLeft = "0dp" एंड्रॉयड: layout_marginStart = "0dp"
Shreyash महाजन

SearchViewStyle में प्रत्येक पंक्ति के लिए स्पष्टीकरण देने के लिए धन्यवाद!
शिन्टा एस

छोटा बच्चा पूरी चौड़ाई के लिए, आप इस तरह से sth कर सकते हैं: (" 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, जो एक्शनबार के रूप में उपयोग किया जाता है:

<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
@ शोले वे अपने आप जुड़ जाते हैं
आर्टेम

क्या वे केवल तब दिखाई देते हैं जब आप SearchView में te search query लिखना शुरू करते हैं या वे तब भी होते हैं जब आपने कुछ भी नहीं लिखा होता है और खोज संकेत दिखाई देता है? मैं पूछ रहा हूं क्योंकि जब तक मैं क्वेरी लिखना शुरू नहीं करता, तब तक मेरा दिखाई नहीं देता। तो यह जानकारी मेरे लिए बहुत उपयोगी होगी
Solace

1
@ शोले navigate-backको हमेशा दिखाया जाता है, clearआपको कुछ खोज क्वेरी लिखने के बाद ही दिखाया जाता है।
आर्टेम

6

एक और तरीका जिससे आप वांछित प्रभाव प्राप्त कर सकते हैं वह है इस सामग्री खोज दृश्य पुस्तकालय का उपयोग करना । यह स्वचालित रूप से खोज इतिहास को संभालता है और साथ ही दृश्य को खोज सुझाव प्रदान करना संभव है।

नमूना: (यह पुर्तगाली में दिखाया गया है, लेकिन यह अंग्रेजी और इतालवी में भी काम करता है)।

नमूना

सेट अप

इससे पहले कि आप इस परिवाद का उपयोग कर सकें, आपको अपने ऐप मॉड्यूल पर पैकेज के MsvAuthorityअंदर नामित एक वर्ग को लागू br.com.maukerकरना होगा, और इसमें एक सार्वजनिक स्थैतिक स्थिर चर होना चाहिए 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()

पुनश्च: यह न केवल से खोलने और बंद करने के लिए संभव है 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();
    }
}

लीब का उपयोग कैसे करें के बारे में अधिक जानकारी के लिए, जीथब पृष्ठ देखें


2
उत्कृष्ट पुस्तकालय, और ओपन / क्लोज़ विधि को अमूर्त करने के लिए बहुत अच्छा विचार है कि एक MenuItem को इसे खोलने / बंद करने की आवश्यकता नहीं है, मैं अपने ऐप में इसे फ्लोटिंगएशनबटन के साथ एक खोज आइकन के साथ उपयोग करने की योजना बना रहा हूं, इसलिए यह बहुत अच्छा काम करेगा।
एडमएमसी331

'खोज' जैसे तार के लिए पैरामीटर क्यों नहीं हैं? ऐसा लगता है कि पुस्तकालय लोगों को या तो स्ट्रिंग के अंग्रेजी या पुर्तगाली संस्करणों में सीमित करता है: /
एस्पायरिंग देव

लेकिन शैलियों का उपयोग करके संकेत स्ट्रिंग को बदलना संभव है क्योंकि यह README पर कहा गया है। वॉइस इनपुट हिंट के लिए, इसे बाद में जारी किया जाएगा: github.com/Mauker1/MaterialSearchView/issues/23
Mauker

@rpgmaker नवीनतम अपडेट की जाँच करें, अब उन स्ट्रिंग्स को बदलना संभव है।
मौकर

@Mauker किसी भी विचार कैसे Android सेट करने के लिए: imeOptions = अपने घटक के EditText के लिए "actionSearch"? (मैं कीबोर्ड में "खोज" बटन प्रदर्शित करना चाहता हूं)
ग्रेग

2

निम्नलिखित जीमेल में एक के समान एक SearchView बनाएगा और इसे दिए गए टूलबार में जोड़ देगा। आपको बस अपना "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 Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.