Toolbar+SearchView+textSelection = bad position of text selection bar - android

Background
I'm trying to theme my app to have more material design look, and as such, I have a toolbar that's being set as the actionBar of the activity.
I have a SearchView in it that allows to search items of the listView below.
The problem
Thing is, you can select the text in the SearchView (to copy, cut, etc...), yet when this happens, the toolbar gets the text-selection toolbar on top of it, making it and the text itself hidden:
Before text selection:
After text selection:
What I've tried
I tried to disable text selection using this code:
final EditText searchTextView=(EditText)searchView.findViewById(R.id.search_src_text);
if(searchTextView!=null&&VERSION.SDK_INT>=VERSION_CODES.HONEYCOMB)
searchTextView.setTextIsSelectable(false);
But it didn't do anything. I've also tried to search for how to listen for the even of text selection (so that I could set the toolbar a marginTop or something), but I didn't find it.
The only thing that I have succeeded is using this code, which tells me when the text-selection toolbar appears (but not when it disappears) :
searchTextView.setOnCreateContextMenuListener(new OnCreateContextMenuListener()
{
#Override
public void onCreateContextMenu(final ContextMenu menu,final View v,final ContextMenuInfo menuInfo)
{
Log.d("AppLog","onCreateContextMenu");
}
});
This doesn't help. I can't even close the menu. I think it can't even help, as some devices might show something else instead of a toolbar (like on LG devices, where they have a small popup).
The code
The layout is basically a vertical LinearLayout, where the first item is the toolbar:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="#+id/activity_app_list__toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:colorControlNormal="?attr/colorControlNormal"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
tools:ignore="UnusedAttribute"/>
...
The theme that's used is set to hide the normal action bar:
<style name="AppTheme" parent="#style/Theme.AppCompat.Light.DarkActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
...
The action bar menu's XML is quite basic and has 3 action items, where the first one of them is the searchView:
<item
android:id="#+id/menuItem_search"
android:icon="?attr/app_search_menu_icon"
android:title="#string/search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="always|collapseActionView"/>
Handling the SearchView is done via a special class I've made that supports even old Android versions. This is the main function that handles the searchView :
#TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
public void init(final MenuItem searchMenuItem,final int hintResId,final OnQueryTextListener onQueryTextListener,final OnActionExpandListener onActionExpandListener)
{
this._searchMenuItem=searchMenuItem;
if(_searchView==null)
{
_searchView=(SearchView)MenuItemCompat.getActionView(searchMenuItem);
if(_searchView==null)
{
MenuItemCompat.setShowAsAction(searchMenuItem,MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW|MenuItem.SHOW_AS_ACTION_ALWAYS);
MenuItemCompat.setActionView(searchMenuItem,_searchView=new SearchView(_context));
}
_searchView.setQueryHint(_context.getString(hintResId));
if(VERSION.SDK_INT<VERSION_CODES.HONEYCOMB)
{
final EditText searchTextView=(EditText)_searchView.findViewById(R.id.search_src_text);
if(searchTextView!=null)
{
searchTextView.setScroller(new Scroller(_context));
searchTextView.setMaxLines(1);
searchTextView.setVerticalScrollBarEnabled(true);
searchTextView.setMovementMethod(new ScrollingMovementMethod());
final int searchTextColorResId=App.getResIdFromAttribute(_context,android.R.attr.textColorPrimary);
if(searchTextColorResId!=0)
searchTextView.setTextColor(_context.getResources().getColor(searchTextColorResId));
else
{
// TODO workaround for some v2.3 devices that can't get the correct color. remove this when stopping the support for v2.3
TextView searchBadge=(TextView)_searchView.findViewById(R.id.search_badge);
if(searchBadge!=null)
searchTextView.setTextColor(searchBadge.getTextColors());
}
}
}
_searchView.setOnQueryTextListener(onQueryTextListener);
MenuItemCompat.setOnActionExpandListener(searchMenuItem,onActionExpandListener);
}
}
The function is called at the end of "onCreateOptionsMenu" of any activity/fragment that is supposed to have a searchView, for example:
_searchHolder.init(menu.findItem(R.id.menuItem_search),R.string.search_for_apps,onQueryTextListener,onActionExpandListener);
The question
How can I solve this issue? Obviously this has happened because the Toolbar is just a view, so the text-selection bar is shown on top of it, but is there any way to fix this?
How do I avoid the extra toolbar become on top of the one I've used?
Is there a way to support all devices in this regard?
Looking at Google's apps, it seems that they usually don't use the official searchView, but one of their own. Only on Youtube it seems like the official one, but there it seems as if they also use the official actionBar (plus it has weird colors when selecting the text).

I found in many apps(Google messenger, Contacts etc) text selection is disabled in search view. You can do that by setting your toolbar theme as.
<style name="toolbarTheme" parent="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<item name="android:autoCompleteTextViewStyle">#style/SearchViewStyle</item>
<item name="android:textColor">#android:color/white</item>
<item name="android:textColorPrimary">#android:color/white</item>
<item name="android:editTextColor">#android:color/white</item>
</style>
<style name="SearchViewStyle" parent="#android:style/Widget.Holo.Light.AutoCompleteTextView">
<item name="android:longClickable">false</item>
</style>
Or if you want it like youtube add this line in your theme
<item name="windowActionModeOverlay">false</item>

Thanks of the Max's answer, I've tried looking the AppCompat style files by clicking on references one after another, I've found Widget.AppCompat.AutoCompleteTextView. Override it in your Toolbar theme with:
<item name="android:autoCompleteTextViewStyle">#style/AppTheme.SearchViewStyle</item>
<style name="AppTheme.SearchViewStyle" parent="Widget.AppCompat.AutoCompleteTextView">
<item name="android:longClickable">false</item>
</style>
It disables the longClick in SearchView. This works on devices from API 14 (didn't try previous versions) to API 22.1.1 at least.

Related

Changing the Color of the the Menu Items does not work

I have created a menu and now I want to change the text color of the individual menu titles.
To do this, I first created a style that should contain the corresponding attribute and then called this style in my Activity_home_drawer.xml. However, this only changes the menu TextColor when the corresponding menu title is clicked but is not permanent as I would like it to be.
What do I have to do so that the text color in my menu changes permanently to white and not Black anymore? Is my way of doing it the right way or is there a more elegant way to change the TextColor?
Thanks for any help!
Part of my Activity_home_drawer.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:showIn="navigation_view"
android:theme="#style/TextAppearance44">
<group android:id="#+id/category_group">
<item
android:id="#+id/nav_menu"
android:icon="#drawable/ic_store_black_24dp"
android:title="#string/menu_menu"
android:theme="#style/TextAppearance44"
/>
</group>
My TextAppearance44 style
<style name="TextAppearance44">
<item name="android:textColor">#color/colorWhite</item>
<item name="android:actionMenuTextColor">#color/colorWhite</item>
<item name="android:textSize">16sp</item>
<item name="android:titleTextColor">#color/colorWhite</item>
</style>
You need to change your ToolBar style. Check these two tutorials:
Toolbar assigning to activity and styling:
https://android-developers.googleblog.com/2014/10/appcompat-v21-material-design-for-pre.html?m=1
Changing style and items colors in the Toolbar:
https://www.murrayc.com/permalink/2014/10/28/android-changing-the-toolbars-text-color-and-overflow-icon-color/
In your case, you are looking mainly for (code fragment from second tutorial):
<!-- android:actionMenuTextColor is the color of the text of
action (menu) items in the Toolbar, at least in the
Theme.AppCompat theme.
For some reason, they already get the textColorPrimary
when running on API 21, but not on older versions of
Android, so this is only necessary to support older
Android versions.-->
<item name="actionMenuTextColor">#color/abc_primary_text_material_light</item>
I solved it by myself; I added these to lines to my NavigationView in my ActivityHome (where the Menu comes up).
app:itemTextColor="#color/colorWhite"
app:itemIconTint="#color/colorWhite"
Simple mistake, didnot know that there was such a attribute.

AppCompat ToolBar popupTheme not used when multi selection active

In styles.xml I'm styling the popup theme of the overflow menu in the toolbar:
<style name="ToolbarOverflowMenuStyle" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:backgroundTint">#color/white</item>
</style>
That works as intended but if I do a multi selection in a recycler view (list) the popup theme background color turns from white to yellow (the color of the toolbar). I have no idea why that is since it has the right color if the multi-selection isn't active.
Any ideas what I am doing wrong?
Styling of the toolbar:
<style name="PostToolbarStyle" parent="android:Theme.Material">
<item name="android:backgroundTint">#color/yellow</item>
<item name="android:textColorHint">#color/lightGray2</item>
<item name="android:textColorPrimary">#color/defaultTextColor</item>
<item name="android:textColorSecondary">#color/defaultTextColor</item>
</style>
And this is how I set the toolbar in the layout xml file:
<android.support.v7.widget.Toolbar
android:id="#+id/app_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:minHeight="?attr/actionBarSize"
android:paddingTop="#dimen/tool_bar_top_padding"
app:popupTheme="#style/ToolbarOverflowMenuStyle"
app:theme="#style/ThemeOverlay.AppCompat.ActionBar"/>
How the popup theme looks like (correctly) when multi-selection is not active:
And here how is being displayed (wrongly) when multi-select is active:
Its Menu -ActionMode you see your default OptionsMenu popUp background is the white, and the default contextual Menu for your app is the Yellow in your case. When you enter into multi-selection a ActionMode is triggered to handle the itemClick and what have you, and since you know how CAB works.
if you want to maintain the same white background in your setMultiChoiceModeListener override onPrepareActionMode(ActionMode mode, Menu menu) and use getCustomView().setBackgroundColor(Color.White);
Edit: addressing comment
This is what i mean in your onPrePareActionMode()
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
//the mode parameter is your CAB, so call that on it
mode.getCustomView().setBackgroundColor(Color.White);
}
Hope its helpful
Can you Try editing you style with this property, selectableItemBackground
<style name="ToolbarOverflowMenuStyle" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:backgroundTint">#color/white</item>
<item name="selectableItemBackground">?android:selectableItemBackground</item></style>
Had a similar problem with SwitchCompat and the solution was in one of the properties itself. Also this blog helped a lot . http://blog.mohitkanwal.com/blog/2015/03/07/styling-material-toolbar-in-android/

Toolbar logo and title are centered even though they're not supposed to be

I'm having trouble implementing a Toolbar in my Android application. I have several problems, really.
First off, here's my MainActivity.java:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar_Main);
toolbar.setLogo(R.drawable.logo);
toolbar.setTitle(R.string.app_name);
toolbar.inflateMenu(R.menu.main_actions);
setActionBar(toolbar);
}
}
activity_main.xml:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity"
android:nestedScrollingEnabled="false">
<Toolbar
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:id="#+id/toolbar_Main"
android:background="?android:attr/colorPrimary" />
<!-- There's an EditText here, but I think that's not the problem -->
</LinearLayout>
styles.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="android:Theme.Material.Light">
<item name="android:windowNoTitle">true</item>
<item name="android:windowActionBar">false</item>
<item name="android:colorPrimary">#color/primaryColor</item>
<item name="android:colorPrimaryDark">#color/primaryColorDark</item>
</style>
</resources>
The problems I'm having are:
the menu is gone;
the logo and title text are centered in the Toolbar, even though I'm pretty sure I haven't set any property to center or whatever.
Now the first problem I can fix by removing the setActionBar part (not sure if that's good practice though), but second one, not so much. The logo and text remain centered no matter what I try. I've tried setting the Toolbar's gravity to top|left, as well as some other things, all to no avail.
When searching on Google (or StackOverflow), all I get are results asking to center the text, which is what I don't want.
I should also mention that I'm developing the app only for API level 21, so no AppCompat and all that fancy stuff, just a Toolbar that I wish to use as the app's main ActionBar.
I'm probably just missing some tiny thing, so thanks in advance.
To me:
You should not remove the setActionBar() call;
Your menu might be disappearing because maybe you have a hardware menu button on your device. Try tapping and see what happens. To fix however, try deleting the inflateMenu() line and inflate the menu during onCreateOptionsMenu(), as usual;
Title and logo issues, as well as menu disappearing, might be due to:
<item name="android:windowNoTitle">true</item>
<item name="android:windowActionBar">false</item>
Why these lines? Just remove them if you don't need.
If this doesn't fix, try calling setActionBar(toolbar) first, and then set title using getActionBar().setTitle() . However I'm pretty sure that removing the two window lines from your style will be enough, so do that first.

How to customize the "up" button when the searchView is being expanded?

Background
My app has the ability to search for items (which are other apps) using the SearchView on the ActionBar.
The app uses the support library of Google, and it works well on all versions of Android from API 9 .
The problem
On Lollipop, when I click the search action item in order to start searching, I notice that the up/back button on the top-left corner gets to be white, which is bad for this case since the actionbar background is also quite white:
Weird thing is that it doesn't always occur, and I don't think it occurs on Android versions that aren't Lollipop (tested on multiple emulators and devices).
Another weird thing is that the navigation drawer icon seems ok, as well as the X icon inside the searchView.
Here's the XML of the toolbar I have:
<android.support.v7.widget.Toolbar
android:id="#+id/activity_app_list__toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize" />
the "colorPrimary" is set to be : #ffEFEFEF .
Also, the theme's parent of the activity is "Theme.AppCompat.Light.NoActionBar" , as I've set the toolbar to be the actionBar.
The question
How can I fix this issue?
What is the cause for this issue? How come it works fine on other Android versions?
It seems like a known issue: https://code.google.com/p/android/issues/detail?id=78346 .
workaround is here: https://code.google.com/p/android/issues/detail?id=78346#c5 , meaning:
values-21/themes.xml:
<style name="MyTheme" parent="Theme.AppCompat">
<item name="homeAsUpIndicator">#drawable/abc_ic_ab_back_mtrl_am_alpha</item>
</style>
That's it. Hope it gets fixed later.
In order to customize it, I assume I can use it, and also choose the color using "colorControlNormal"
I'd guess the "app:collapseIcon" attribute is what you were looking for?
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="#dimen/toolbarHeight"
app:collapseIcon="#drawable/collapseBackIcon" />
How can I fix this issue?
I created a utility class for this (and other) problems. Get it here:
https://gist.github.com/consp1racy/96958a1dedf5a99d4ca5
Part 1: Call the following method in your Activity.onCreate(Bundle):
ToolbarUtils.fixToolbar(mToolbar);
Part 2: The code uses value android:colorControlNormal from the Toolbar "theme" you specified in the layout. If you use support library and defined only colorControlNormal you need to add the following line after it:
<item name="android:colorControlNormal" tools:ignore="NewApi">?attr/colorControlNormal</item>
What is the cause of this issue?
After a lot of thought and experiments it seems that the arrow uses the original bitmap, which is white, without any coloring, which is wrong.
Note: The menu overflow icon also reads the android:colorControlNormal so now it will display correct color as well.
EDIT: Prerequisites:
Your Toolbar should have attributes similar to the following
<!-- custom toolbar theme -->
<item name="theme">#style/ThemeOverlay.MyApp.ActionBar</item>
<!-- light popup menu theme, change this if you need to -->
<item name="popupTheme">#style/ThemeOverlay.AppCompat.Light</item>
<!-- app bar background color -->
<item name="android:background">#color/material_deep_orange_500</item>
Then the toolbar theme should look something like this
<!-- example uses dark app bar template, feel free to change it to light if you need to -->
<style name="ThemeOverlay.MyApp.ActionBar" parent="ThemeOverlay.AppCompat.Dark.ActionBar">
<!-- this line defines title text color -->
<item name="android:textColorPrimary">#color/material_white_100</item>
<!-- this line defines subtitle text color -->
<item name="android:textColorSecondary">#color/material_white_70</item>
<!-- this line defines up/hamburger/overflow icons color -->
<item name="colorControlNormal">#color/material_black_54</item>
<!-- this line is necessary for proper coloring on lollipop - do not delete it -->
<item name="android:colorControlNormal" tools:ignore="NewApi">?attr/colorControlNormal</item>
</style>

Contextual Actionbar styles

I'm looking for style information on the Contextual Action bar (CAB). I just need to change the colour of the text in fact..
As you can see from the above, this is using the standard Theme.Holo.Light.DarkActionBar theme, so I just need to set the text colour to white!
Can anyone point me in the right direction?
To change the color/etc of the text in a contextual action bar:
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
//mode.setTitle("Contextual Action Bar"); (replace this call)
TextView tv= (TextView)getLayoutInflater().inflate(R.layout.contextual_title, null);
tv.setText("Contextual Action Bar");
mode.setCustomView(tv);
where layout/contextual_title.xml contains a single TextView with your desired color/size/style etc
In fact, almost everything in a contextual action bar can be styled. The only problem is that searching for the word 'contextual' leads nowhere useful. The relevant styling features are all called "actionMode...". Here are some I used (defined in my Theme.)
<item name="android:actionModeCloseDrawable">#drawable/check</item>
<item name="android:actionModeCutDrawable">#drawable/ic_menu_cut_holo_dark</item>
<item name="android:actionModeCopyDrawable">#drawable/ic_menu_copy_holo_dark</item>
<item name="android:actionModePasteDrawable">#drawable/ic_menu_paste_holo_dark</item>
<item name="android:actionModeSelectAllDrawable">#drawable/ic_menu_selectall_holo_dark</item>
<item name="android:actionModeBackground">#drawable/contextual</item>
<item name="android:actionModeCloseButtonStyle">#style/MyCloseButton</item>
<!-- these change the press backgrounds for the vanilla actionBar and for search -->
<item name="android:windowContentOverlay">#null</item>
<item name="android:selectableItemBackground">#drawable/bar_selector</item>
<item name="android:actionBarItemBackground">#drawable/bar_selector</item>
<!-- these were defined in platform/.../data/res/values/... but Eclipse didn't recognize them -->
<!--? item name="android:actionModeShareDrawable">#drawable/icon</item -->
<!--? item name="android:actionModeFindDrawable">#drawable/icon</item -->
<!--? item name="android:actionModeWebSearchDrawable">#drawable/icon</item -->
<!-- item name="android:actionModeBackground">#drawable/red</item -->
<!-- and finally -->
<style name="MyCloseButton" parent="android:style/Widget.ActionButton.CloseMode">
<item name="android:background">#drawable/bar_selector</item>
</style>
You can easily set your own text-editing cut/paste/copy/selectall icons, the bar
background, and the icon background that changes color when you press the icons(bar_selector above). The icons are ImageViews, not buttons, and the edit id's (and the pressable background) are attached to the ImageView's parent (one parent per view) which is an 'internal' type.
It's never clear what goes where in the styles--I found where selectableItemBackground was in the platform Themes.xml, and copied and modified the drawable pointed at.
I posted a comment to my own question, and this is actually a bug in the version of android I was using (Probably an early version of 4.0)
This is the bug described: http://code.google.com/p/android/issues/detail?id=26008
If you're starting the contextual action mode manually, you can call setTheme() with a new theme before launching it (maybe Theme.AppCompat.Light.DarkActionBar if you're trying to avoid the black-on-black text issue). This will not affect the theme of the current activity if you've already set the activity's content view.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity_layout);
// these lines can occur anywhere so long as you've already
// called "setContentView()" on the activity. The theme
// you set here will apply to the action mode, but not to
// the activity.
setTheme(R.style.Theme_AppCompat_Light_DarkActionBar);
startSupportActionMode(myActionModeCallback);
}
it works now, but you have to enter it in values/styles.xml (not values-v#/styles.xml) and enter it in the general (non-API specific tag)
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<item name="android:actionModeCloseDrawable">#drawable/ic_launcher</item>
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
</style>

Categories

Resources