Toolbar+SearchView+textSelection = 文本选择栏位置错误
Toolbar+SearchView+textSelection = bad position of text selection bar
背景
我正在尝试 my app 主题以具有更多 material 设计外观,因此,我有一个工具栏被设置为 activity 的 actionBar。
我有一个 SearchView,它允许搜索下面列表视图的项目。
问题
事实是,您可以 select SearchView 中的文本(复制、剪切等...),但是当发生这种情况时,工具栏会得到文本 -selection 工具栏在它上面,隐藏它和文本本身:
文本前 selection:
文字后select离子:
我试过的
我尝试使用以下代码禁用文本 selection:
final EditText searchTextView=(EditText)searchView.findViewById(R.id.search_src_text);
if(searchTextView!=null&&VERSION.SDK_INT>=VERSION_CODES.HONEYCOMB)
searchTextView.setTextIsSelectable(false);
但它什么也没做。我还尝试搜索如何监听文本 selection 的偶数(以便我可以将工具栏设置为 marginTop 或其他东西),但我没有找到它。
我唯一成功的是使用这段代码,它告诉我何时出现 text-selection 工具栏(但不会在它消失时):
searchTextView.setOnCreateContextMenuListener(new OnCreateContextMenuListener()
{
@Override
public void onCreateContextMenu(final ContextMenu menu,final View v,final ContextMenuInfo menuInfo)
{
Log.d("AppLog","onCreateContextMenu");
}
});
这没有帮助。我什至无法关闭菜单。我认为它甚至无济于事,因为某些设备可能会显示其他内容而不是工具栏(例如在 LG 设备上,它们有一个小弹出窗口)。
密码
布局基本上是垂直的LinearLayout,其中第一项是工具栏:
<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"/>
...
使用的主题设置为隐藏正常操作栏:
<style name="AppTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
...
操作栏菜单的 XML 非常基本,有 3 个操作项,其中第一个是搜索视图:
<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"/>
SearchView 的处理是通过我制作的特殊 class 完成的,它甚至支持旧的 Android 版本。这是处理 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);
}
}
该函数在应该有 searchView 的任何 activity/fragment 的 "onCreateOptionsMenu" 末尾调用,例如:
_searchHolder.init(menu.findItem(R.id.menuItem_search),R.string.search_for_apps,onQueryTextListener,onActionExpandListener);
问题
我该如何解决这个问题?显然这是因为工具栏只是一个视图,所以文本-select离子栏显示在它上面,但是有什么办法可以解决这个问题吗?
如何避免额外的工具栏出现在我使用过的工具栏之上?
有没有办法在这方面支持所有设备?
看Google的app,好像一般都不用官方的searchView,而是自己的一个。只有在 Youtube 上它看起来像官方的,但似乎他们也使用官方的 actionBar(加上它在 selecting 文本时有奇怪的颜色)。
我发现在许多应用程序(Google 信使、联系人等)中,文本选择在搜索视图中被禁用。您可以将工具栏主题设置为。
<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>
或者,如果您希望它像 youtube 一样,请在您的主题中添加这一行
<item name="windowActionModeOverlay">false</item>
感谢 Max 的回答,我尝试通过点击一个又一个的参考来查看 AppCompat 样式文件,我找到了 Widget.AppCompat.AutoCompleteTextView
。在您的工具栏主题中覆盖它:
<item name="android:autoCompleteTextViewStyle">@style/AppTheme.SearchViewStyle</item>
<style name="AppTheme.SearchViewStyle" parent="Widget.AppCompat.AutoCompleteTextView">
<item name="android:longClickable">false</item>
</style>
它禁用了 SearchView 中的长按。这至少适用于 API 14(未尝试以前的版本)到 API 22.1.1 的设备。
背景
我正在尝试 my app 主题以具有更多 material 设计外观,因此,我有一个工具栏被设置为 activity 的 actionBar。
我有一个 SearchView,它允许搜索下面列表视图的项目。
问题
事实是,您可以 select SearchView 中的文本(复制、剪切等...),但是当发生这种情况时,工具栏会得到文本 -selection 工具栏在它上面,隐藏它和文本本身:
文本前 selection:
文字后select离子:
我试过的
我尝试使用以下代码禁用文本 selection:
final EditText searchTextView=(EditText)searchView.findViewById(R.id.search_src_text);
if(searchTextView!=null&&VERSION.SDK_INT>=VERSION_CODES.HONEYCOMB)
searchTextView.setTextIsSelectable(false);
但它什么也没做。我还尝试搜索如何监听文本 selection 的偶数(以便我可以将工具栏设置为 marginTop 或其他东西),但我没有找到它。
我唯一成功的是使用这段代码,它告诉我何时出现 text-selection 工具栏(但不会在它消失时):
searchTextView.setOnCreateContextMenuListener(new OnCreateContextMenuListener()
{
@Override
public void onCreateContextMenu(final ContextMenu menu,final View v,final ContextMenuInfo menuInfo)
{
Log.d("AppLog","onCreateContextMenu");
}
});
这没有帮助。我什至无法关闭菜单。我认为它甚至无济于事,因为某些设备可能会显示其他内容而不是工具栏(例如在 LG 设备上,它们有一个小弹出窗口)。
密码
布局基本上是垂直的LinearLayout,其中第一项是工具栏:
<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"/>
...
使用的主题设置为隐藏正常操作栏:
<style name="AppTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
...
操作栏菜单的 XML 非常基本,有 3 个操作项,其中第一个是搜索视图:
<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"/>
SearchView 的处理是通过我制作的特殊 class 完成的,它甚至支持旧的 Android 版本。这是处理 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);
}
}
该函数在应该有 searchView 的任何 activity/fragment 的 "onCreateOptionsMenu" 末尾调用,例如:
_searchHolder.init(menu.findItem(R.id.menuItem_search),R.string.search_for_apps,onQueryTextListener,onActionExpandListener);
问题
我该如何解决这个问题?显然这是因为工具栏只是一个视图,所以文本-select离子栏显示在它上面,但是有什么办法可以解决这个问题吗?
如何避免额外的工具栏出现在我使用过的工具栏之上?
有没有办法在这方面支持所有设备?
看Google的app,好像一般都不用官方的searchView,而是自己的一个。只有在 Youtube 上它看起来像官方的,但似乎他们也使用官方的 actionBar(加上它在 selecting 文本时有奇怪的颜色)。
我发现在许多应用程序(Google 信使、联系人等)中,文本选择在搜索视图中被禁用。您可以将工具栏主题设置为。
<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>
或者,如果您希望它像 youtube 一样,请在您的主题中添加这一行
<item name="windowActionModeOverlay">false</item>
感谢 Max 的回答,我尝试通过点击一个又一个的参考来查看 AppCompat 样式文件,我找到了 Widget.AppCompat.AutoCompleteTextView
。在您的工具栏主题中覆盖它:
<item name="android:autoCompleteTextViewStyle">@style/AppTheme.SearchViewStyle</item>
<style name="AppTheme.SearchViewStyle" parent="Widget.AppCompat.AutoCompleteTextView">
<item name="android:longClickable">false</item>
</style>
它禁用了 SearchView 中的长按。这至少适用于 API 14(未尝试以前的版本)到 API 22.1.1 的设备。