Android searchView关于Iconified表现行为不一致的探讨

菜鸟写第一篇csdn博文,仅仅是因为自己遇到的问题百度而不得解,本着探索精神自己尝试后得到解决,感觉不错,分享出来给需要的朋友。

问题其实很简单,但是绕了好久。。。


目前在学习安卓,在一个项目中要用到search view组件。我想要的效果是:

1、顶部工具栏的搜索按钮点击后,在工具栏下方出现搜索栏。

2、这个搜索栏需要有关闭按钮,使得搜索栏可以从界面上消失。

3、当需要搜索时点击顶部工具栏按钮再出现。


最终实现布局如下:

图1:点击搜索按钮前:



图2:点击搜索按钮后:



图3:点击搜索栏右侧的关闭按钮后,恢复到图1。


很简单也很合理的要求,但是在实现的时候遇到个问题困扰了很久:searchview的两个方法:setIconifiedByDefault 和 setIconified。

searchview在布局中可以设置默认的形式,如下,iconified是指图标化。

<span style="font-size:18px;">android:iconifiedByDefault="true"</span>
当iconifiedByDefault属性被设置为true时(java代码使用setIconifiedByDefault (true)设置),搜索栏的默认表现为一个单一的搜索图标,当点击这个图标后,才会展开显示完整的搜索图标、搜索输入框、关闭X按钮。如下:

图3:图标化搜索栏(收起状态)



图4:点击图标,展开搜索栏



为了达到我的目标,我希望默认为展开状态。所以,我将该值设置为false,也就是默认为非图标化。

但问题来了,设置iconifiedByDefault为false后,组件运行效果为:

图5:设置iconifiedByDefault为false后的组件表现


现象1:放大镜图标不在搜索框内,不如图4那样好看。

现象2:搜索内容为空时,搜索栏右侧的关闭按钮不显示

现象3:搜索内容不为空时,显示关闭按钮,但点击关闭按钮后清空文本,关闭按钮消失,无法关闭或收起搜索栏为图标化状态。

现象4:在现象2、3中,无法响应搜索栏关闭事件OnCloseListener()


显然,以上4点完全不满足我的要求(我要求关闭按钮时刻显示),而且我觉得也十分不合理。。。在排除了我的代码问题后,又百度没有发现有人遇到和我这样的情况。。。

好在刚学会了看android源码,抱着试一试的态度查看了setIconifiedByDefault 的源码,如下:

<span style="font-size:18px;">    public void setIconifiedByDefault(boolean iconified) {
        if (mIconifiedByDefault == iconified) return;
        mIconifiedByDefault = iconified;
        updateViewsVisibility(iconified);
        updateQueryHint();
    }</span>
跟踪updateViewsVisibility,如下:

<span style="font-size:18px;">    private void updateViewsVisibility(final boolean collapsed) {
        mIconified = collapsed;
        // Visibility of views that are visible when collapsed
        final int visCollapsed = collapsed ? VISIBLE : GONE;
        // Is there text in the query
        final boolean hasText = !TextUtils.isEmpty(mQueryTextView.getText());

        mSearchButton.setVisibility(visCollapsed);
        updateSubmitButton(hasText);
        mSearchEditFrame.setVisibility(collapsed ? GONE : VISIBLE);
        mSearchHintIcon.setVisibility(mIconifiedByDefault ? GONE : VISIBLE);
        updateCloseButton();
        updateVoiceButton(!hasText);
        updateSubmitArea();
    }</span>
我的关注点在关闭按钮,于是继续跟踪:updateCloseButton

<span style="font-size:18px;">    private void updateCloseButton() {
        final boolean hasText = !TextUtils.isEmpty(mQueryTextView.getText());
        // Should we show the close button? It is not shown if there's no focus,
        // field is not iconified by default and there is no text in it.
        final boolean showClose = hasText || (mIconifiedByDefault && !mExpandedInActionView);
        mCloseButton.setVisibility(showClose ? VISIBLE : GONE);
        mCloseButton.getDrawable().setState(hasText ? ENABLED_STATE_SET : EMPTY_STATE_SET);
    }</span>
关键来了。注释翻译为:

如果搜索框没有焦点,或者未被设置为【默认图标化】或搜索框内无文本时,不显示关闭按钮!

从代码和注释里可以知道,关闭按钮只在有搜索文本或者被【默认图标化(iconifiedByDefault为true)】且展开后才显示。


难道就不能默认展开,同时又允许关闭按钮一直显示吗?

我找到了另外一个类似的方法:setIconified (这个属性只可以用Java代码实现,而不是布局属性),该方法的说明文档如下:

<span style="font-size:18px;">Open Declaration void android.widget.SearchView.setIconified(boolean iconify)


Iconifies or expands the SearchView. Any query text is cleared when iconified. This is a temporary state and does not override the default iconified state set by setIconifiedByDefault(boolean). If the default state is iconified, then a false here will only be valid until the user closes the field. And if the default state is expanded, then a true here will only clear the text field and not close it.

Parameters:
iconify a true value will collapse the SearchView to an icon, while a false will expand it.</span>

也就是说,setIconified不能改变iconifiedByDefault设置的默认行为,只是一个临时的状态

若默认图标化,setIconified(false)在用户关闭搜索栏之前有效【注意翻译be valid until closed】

若默认非图标化,也就是默认展开,setIconified(true)只会清空文本而不关闭搜索栏


搞懂后,我的解决方案就很简单了:

<span style="font-size:18px;">svSearch.setIconifiedByDefault(true);
svSearch.setIconified(false);</span>
也就是,默认图标化(这样才能一直显示关闭按钮),然后展开。成功。


问题其实很简单,但是被英文的表达方式搞得有点绕。至于默认非图标化时,现象1怎么解决我就不深究了,能达到目的就好~~

在API14,SearchView有onActionViewCollapsed和onActionViewExpanded方法来控制搜索栏的展开与关闭,经过试验仍然不能有效解决我的问题。


好了就到这了。第一篇菜鸟文章,希望对大家有用~~~欢迎指正。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值