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