在没有ActionBarSherlock的情况下更改SearchView中光标的颜色

8

我正试图改变ICS+中SearchView小部件上闪烁光标的颜色。 我尝试了以下方法:

  • <item name="android:textCursorDrawable">@null</item>添加到我的主题中
  • 为我的主题添加AutoCompleteTextViews的样式,并将该样式的textCursorAttribute设置为@null
  • 直接在SearchView上设置android:textCursorDrawable="@null"

我在这里阅读了答案(Custom cursor color in SearchView),但是搜索AutoCompleteTextView没有非ABS风格,因此无法尝试。 我还寻找了一种Java方法来设置文本光标可绘制物,但是找不到 - 如果有可用的方法,我将修改SearchView的其他方面并能够对光标进行修改。

我已经相当详细地定制了SearchView,但最后一个更改使其无法看起来正确 - 光标是白色的,背景也是白色的,因此不容易看到。 有其他任何想法可以尝试吗?


1
如果你深入挖掘Android源代码,你会发现mCursorDrawableRes只在三参数构造函数中设置一次。不幸的是,这意味着没有简单的方法在运行时更改它。看起来你的选择可能被限制为使用反射,或将你的自定义SearchView移动到android.widget中以便访问包保护成员。 - MH.
MH,感谢你的提示 - 我能够使用反射来获取TextView中的mCursorDrawableRes并将其更改为0 - 这相当于将其设置为@null,颜色显示正确 - 如果您将此作为答案发布,我会接受它。 - Eric Brynsvold
很高兴这个方案能够奏效,尽管它并不是最理想的解决方案。 - MH.
同意这并不理想 - SearchView在默认情况下很难定制。我必须使用findViewById和内部ID更改其他组件,以从SearchView获取组件。所以这是一种类似的解决方案。 - Eric Brynsvold
4个回答

57

根据以上的评论和回答,我使用反射制作了一个示例,展示了如何解决我的应用程序中的问题。希望这能为其他人节省一些时间。

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.entity_list_actions, menu);
    final SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
    final int textViewID = searchView.getContext().getResources().getIdentifier("android:id/search_src_text",null, null);
    final AutoCompleteTextView searchTextView = (AutoCompleteTextView) searchView.findViewById(textViewID);
    try {
        Field mCursorDrawableRes = TextView.class.getDeclaredField("mCursorDrawableRes");
        mCursorDrawableRes.setAccessible(true);
        mCursorDrawableRes.set(searchTextView, 0); //This sets the cursor resource ID to 0 or @null which will make it visible on white background
    } catch (Exception e) {}
    return super.onCreateOptionsMenu(menu);
}

那个0可以是任何其他资源ID,例如R.drawable.my_cursor。


20
我曾试图将第5和第6行替换为final EditText searchTextView = (EditText) searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);,这对我有用。 - user1923613
API 16+上运行良好。是一个很棒的解决方案,在stackoverflow上从未找到过。 - djdance
谢谢,回答很好。关于您的评论,有一点需要注意,您说:“这将光标资源ID设置为0或@null,这将使其在白色背景上可见”。实际上将其设置为null会使光标颜色默认与文本颜色相同,因此如果您已经正确设置了文本颜色,则可以在任何背景上使用它。 - gkee
哇,很不错!运作得像魔术一样。 - Edward van Raak
@EricBrynsvold 这是正确的答案。请将此标记为正确答案。 - Sufian
我不得不在Appcompat中使用这个:int textViewID = searchView.getContext().getResources().getIdentifier("id/search_src_text", null, searchView.getContext().getPackageName()); - Matt

3
<style name="CustomTheme" parent="android:Theme.Holo.Light">
    ...
    <item name="android:autoCompleteTextViewStyle">@style/SearchViewStyle</item>
    ...
</style>

<style name="SearchViewStyle" parent="@android:style/Widget.Holo.Light.AutoCompleteTextView">
    <item name="android:textCursorDrawable">@drawable/action_mode_close</item>
</style>

“action_mode_close”是什么?是否可以设置颜色代替? - android developer
action_mode_close 只是一个 png 文件。通常是带有白色的 ☑ 标志。你也可以使用白色以外的颜色。 - evan
1
你能演示一下如何在新的 Material Design 支持库中实现吗?我认为唯一的方法就是要么设置真正的可绘制对象来替换插入符号,要么使用 colorControlActivated(但这也会改变其他内容)。 - android developer

1

这将更改文本颜色,同样适用于Android 8:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main_menu_search, menu);
        MenuItem searchItem = menu.findItem(R.id.action_search);
        SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
        SearchView.SearchAutoComplete theTextArea = (SearchView.SearchAutoComplete) searchView
                .findViewById(R.id.search_src_text);
        theTextArea.setTextColor(getResources().getColor(R.color.yourColor));
    ...

1
不适用于带有KitKat的S5和S4。尚未在其他设备上进行测试。 - tomrozb

1
根据之前的评论:
如果你深入研究Android源代码,你会发现只在3参数构造函数中设置一次。不幸的是,这意味着没有简单的方法在运行时更改它。看起来你的选择可能被限制为使用反射,或将你的自定义移动到包中以便访问受包保护的成员。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接