Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.8k views
in Technique[技术] by (71.8m points)

xml - Styling Search View on Android (min21)

I'm trying to customize my search bar on Android Studio for my application. The result I'd like to achieve is the one here: My Search bar and the Quora's one

I'm trying to follow G's documentation (https://developer.android.com/guide/topics/search/search-dialog.html) without results.

Here's my code:

Styles.xml

  <style name="CustomSearchViewStyle" parent="Widget.AppCompat.SearchView">
        <item name ="voiceIcon">@drawable/ic_flag</item>
        <item name="searchIcon">@drawable/ic_search</item>
        <item name="queryBackground">@color/DarkYellow</item>
        <item name="android:background">@color/MainYellow</item>
        <item name="android:paddingBottom">20dp</item>
        <item name="android:paddingTop">5dp</item>
        <item name="android:paddingStart">-15dp</item>
        <item name="android:paddingEnd">15dp</item>
        <item name="android:inputType">textCapWords</item>
    </style>

Searchable.xml

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

    <searchable
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:label="@string/app_name"
        android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"

    />

MainActivity.xml

 <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.v7.widget.SearchView
            android:id="@+id/top_search_bar"
            style="@style/CustomSearchViewStyle"
            android:layout_width="match_parent"
            android:layout_height="@dimen/search_bar_height"
            android:layout_alignParentStart="true"
            app:iconifiedByDefault="false"
            app:queryHint="@string/search_hint"
            android:layout_alignParentEnd="true" />
    </RelativeLayout>

Can't get the reason why I can't put a custom icon behind the "Hint Text" nor the voice search icon at the end of the bar, inside the query's field.

I tried to activate this property: <item name="searchHintIcon">@drawable/ic_search</item> but nothing happens.

Do you have any suggestions for that?

Thank you so much.

Have a nice day.

UPDATE: Seems that deleting the string "setIconifiedByDefault" in the xml or the java file shows the Hint Icon but I'd like to have my searchBar always NOT iconified (always visible) so, that doesn't solve my issue.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

OK, Seems We figured it out a solution to our problem. (thanks to my teammate Claffolo)

I honestly couldn't figure it out how to solve my issue so we preferred to create our personal Search Bar, instead of using Google's one.

This is the result we achieved: Search Bar (I replaced our logo with that home icon because we prefer to hide our logo.), pretty similar to the one I wanted, uh?

This is my activity_main.xml:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.Toolbar
        android:id="@+id/my_toolbar"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:background="?attr/colorPrimary"
        android:layout_alignParentStart="true"
        android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingTop="2dp"
            android:paddingEnd="16dp">

            <ImageView
                android:id="@+id/search_bar_hint_icon"
                android:layout_width="32dp"
                android:layout_height="32dp"
                android:src="@drawable/ic_search"/>

            <EditText
                android:id="@+id/search_bar_edit_text"
                android:layout_width="0dp"
                android:hint="@string/search_hint"
                android:textColorHint="@color/LightYellow"
                android:backgroundTint="@color/DarkYellow"
                android:background="@color/DarkYellow"
                android:inputType="textCapWords"
                android:layout_weight="1"
                android:layout_height="32dp" />

            <ImageButton
                android:id="@+id/search_bar_voice_icon"
                android:layout_width="32dp"
                android:layout_height="32dp"
                android:background="@drawable/ic_mic" />

        </LinearLayout>

    </android.support.v7.widget.Toolbar>

    <ImageView
        android:id="@+id/imageview_logo"
        android:layout_width="match_parent"
        android:layout_height="35dp"
        android:layout_below="@id/my_toolbar"
        android:src="@drawable/ic_home"
        android:background="@color/MainYellow"
        />
</RelativeLayout>

So as you can see it's a struct made of three elements: a EditText, which handles the input, an ImageView that is represented by that lens icon before the Search Hint TextBox and a ImageButton, the mic_icon button that handles voice_speech events. All of them are places in a linearLayout, and in a Toolbar, I had to place layout_weight = 1 field in the EditText to achieve the result you can see in the picture.

Anyway, here's how we handled our code:

MainActivity.java:

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //SETUP TOOLBAR
        Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar);
        setSupportActionBar(myToolbar);
}
    voice_search_button = (ImageButton)findViewById(R.id.search_bar_voice_icon);
    editText = (EditText) findViewById(R.id.search_bar_edit_text);
    editText.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            fragmentManager.beginTransaction().replace(R.id.fragment_container, new SearchResultsFragment()).commit();
        }
    });

    editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if(hasFocus){
                fragmentManager.beginTransaction().replace(R.id.fragment_container, new SearchResultsFragment()).commit();
            }
        }
    });

To handle voice_speech events, add the following in MainActivity.java, under onCreate overrided method:

  //Voice Search Listener
        voice_search_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                promptSpeechInput();
            }
        });

And override these two methods:

/**
 * Showing google speech input dialog
 * */
private void promptSpeechInput() {
    Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
            RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());
    intent.putExtra(RecognizerIntent.EXTRA_PROMPT,
            getString(R.string.speech_prompt));
    try {
        startActivityForResult(intent, REQ_CODE_SPEECH_INPUT);
    } catch (ActivityNotFoundException a) {
        Toast.makeText(getApplicationContext(),
                getString(R.string.speech_not_supported),
                Toast.LENGTH_SHORT).show();
    }
}

/**
 * Receiving speech input
 * */
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    switch (requestCode) {
        case REQ_CODE_SPEECH_INPUT: {
            if (resultCode == RESULT_OK && null != data) {

                ArrayList<String> result = data
                        .getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
                editText.setText(result.get(0));
                //TODO AVVIARE ATTIVITA' CON TESTO RESULT.GET(0)
            }
            break;
        }

    }
}

In the end, we're still dealing with the instantSearch and filtering features thanks to this guy who answered here: How to filter a RecyclerView with a SearchView

Hope this helped someone, I will update my answer, eventually.

Have a nice day.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...