SearchView的OnCloseListener不起作用


101

我正在尝试SearchView在Android 3.0+ ActionBar中添加对的支持,但无法OnCloseListener正常工作。

这是我的代码:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu, menu);
    searchView = (SearchView) menu.findItem(R.id.search_textbox).getActionView();
    searchView.setOnQueryTextListener(new OnQueryTextListener() {
        @Override
        public boolean onQueryTextChange(String newText) {
            searchLibrary(newText);
            return false;
        }
        @Override
        public boolean onQueryTextSubmit(String query) { return false; }
    });
    searchView.setOnCloseListener(new OnCloseListener() {
        @Override
        public boolean onClose() {
            System.out.println("Testing. 1, 2, 3...");
            return false;
        }
    });
    return true;
}

搜索效果很好,除以外的所有功能都在工作OnCloseListener。什么都没有打印到Logcat。这是当我按下“关闭”按钮时的Logcat:

02-17 13:01:52.914: I/TextType(446): TextType = 0x0
02-17 13:01:57.344: I/TextType(446): TextType = 0x0
02-17 13:02:02.944: I/TextType(446): TextType = 0x0

我浏览了文档和示例,但似乎没有什么改变。我正在华硕Transformer Prime和Galaxy Nexus上运行它,两者都在Ice Cream Sandwich上运行。有任何想法吗?

更新:

是- System.out.println() 的工作。这是证明:

   @Override
 public boolean onQueryTextChange(String newText) {
    System.out.println(newText + "hello");
    searchLibrary(newText);
    return false;
 }

此Logcat中的结果:

02-17 13:04:20.094: I/System.out(21152): hello
02-17 13:04:24.914: I/System.out(21152): thello
02-17 13:04:25.394: I/System.out(21152): tehello
02-17 13:04:25.784: I/System.out(21152): teshello
02-17 13:04:26.064: I/System.out(21152): testhello

嗯,我可以在Android 3.2上正常运行,但不能在4.0+上运行
PJL 2012年


3
我很高兴这不仅是我遇到的问题。除了下面的黑客,还有其他黑客吗?
bencallis'3

2
如果showAsAction设置为,我学到了两件事always。搜索框具有其自己的关闭按钮,但如果设置为关闭按钮,则会ifRoom | collapseActionView在操作栏上展开。
Beraki 2016年

Answers:


153

我也遇到了这个问题,我别无选择,只能放弃“ oncloselistener”。相反,您可以获取menuItem,然后获取setOnActionExpandListener。然后重写unimplents方法。

@Override
public boolean onMenuItemActionExpand(MenuItem item) {
    // TODO Auto-generated method stub
    Log.d("*******","onMenuItemActionExpand");
    return true;
}

@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
    //do what you want to when close the sesarchview
    //remember to return true;
    Log.d("*******","onMenuItemActionCollapse");
    return true;
}

我相信我们只是在谈论ActionBar的SearchView,它只是蜂窝+
NKijak 2013年

不要打扰onCloseListener,只需将它与菜单项一起使用即可。
罗伯特

12
我想你可以使用MenuItemCompat.OnActionExpandListener较早API级别:developer.android.com/reference/android/support/v4/view/...
Ripityom

2
完整答案:if (Build.VERSION.SdkInt > BuildVersionCodes.NMr1) item.SetOnActionExpandListener(this); else MenuItemCompat.SetOnActionExpandListener(item, this);
FindOutIslamNow

61

对于Android API 14+(ICS和更高版本),请使用以下代码:

// When using the support library, the setOnActionExpandListener() method is
// static and accepts the MenuItem object as an argument
MenuItemCompat.setOnActionExpandListener(menuItem, new OnActionExpandListener() {
    @Override
    public boolean onMenuItemActionCollapse(MenuItem item) {
        // Do something when collapsed
        return true;  // Return true to collapse action view
    }

    @Override
    public boolean onMenuItemActionExpand(MenuItem item) {
        // Do something when expanded
        return true;  // Return true to expand action view
    }
});

有关更多信息:http : //developer.android.com/guide/topics/ui/actionbar.html#ActionView

参考:onActionCollapse / onActionExpand


31

对于这个问题,我想出了类似的方法,

private SearchView mSearchView;

@TargetApi(14)
@Override
public boolean onCreateOptionsMenu(Menu menu)
{

    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.conversation_index_activity_menu, menu);

    mSearchView = (SearchView) menu.findItem(R.id.itemSearch).getActionView();

    MenuItem menuItem = menu.findItem(R.id.itemSearch);

    int currentapiVersion = android.os.Build.VERSION.SDK_INT;
    if (currentapiVersion >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    {
        menuItem.setOnActionExpandListener(new OnActionExpandListener()
        {

            @Override
            public boolean onMenuItemActionCollapse(MenuItem item)
            {
                // Do something when collapsed
                Log.i(TAG, "onMenuItemActionCollapse " + item.getItemId());
                return true; // Return true to collapse action view
            }

            @Override
            public boolean onMenuItemActionExpand(MenuItem item)
            {
                // TODO Auto-generated method stub
                Log.i(TAG, "onMenuItemActionExpand " + item.getItemId());
                return true;
            }
        });
    } else
    {
        // do something for phones running an SDK before froyo
        mSearchView.setOnCloseListener(new OnCloseListener()
        {

            @Override
            public boolean onClose()
            {
                Log.i(TAG, "mSearchView on close ");
                // TODO Auto-generated method stub
                return false;
            }
        });
    }


    return super.onCreateOptionsMenu(menu);

}

1
如果始终使用setIconofiedByDefault(false)进行扩展会发生什么?它
行不通

19

我在android 4.1.1上遇到了同样的问题。看来这是一个已知的错误:https : //code.google.com/p/android/issues/detail?id=25758

无论如何,作为一种解决方法,我使用了状态更改侦听器(当SearchView与操作栏分离时,它显然也已关闭)。

view.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {

    @Override
    public void onViewDetachedFromWindow(View arg0) {
        // search was detached/closed
    }

    @Override
    public void onViewAttachedToWindow(View arg0) {
        // search was opened
    }
});

上面的代码在我的情况下效果很好。


我在这里发布了相同的答案:https : //stackoverflow.com/a/24573266/2162924


是的,该错误是在我发布此问题后立即创建的。请参阅原始问题的评论。
米歇尔·巴克

哦,好的,现在看看。但是无论如何,这种状态更改侦听器的变通办法也许对其他人也很有用。
达里奥

虽然令人失望的是,OnCloseListener无法按您的想象工作,但这实际上是一个不错的解决方案。荣誉!
welshk91 '16

10

我最终使用了一点技巧,可以很好地达到我的目的-不确定它是否可以满足所有目的。无论如何,我正在检查搜索查询是否为空。这是不是真的涉及到SearchViewOnCloseListener,虽然-这仍然没有工作!

searchView.setOnQueryTextListener(new OnQueryTextListener() {
            @Override
            public boolean onQueryTextChange(String newText) {
                if (newText.length() > 0) {
                    // Search
                } else {
                    // Do something when there's no input
                }
                return false;
            }
            @Override
            public boolean onQueryTextSubmit(String query) { return false; }
        });

7

好吧,这解决了我的问题:

菜单项 showAsAction="always"

<item
    android:id="@+id/action_search"
    android:icon="@drawable/ic_action_search"
    android:title="Search"
    app:actionViewClass="android.support.v7.widget.SearchView"
    app:showAsAction="always"/>

并在活动中

searchView.setOnCloseListener(new OnCloseListener() {

        @Override
        public boolean onClose() {

            Log.i("SearchView:", "onClose");
            searchView.onActionViewCollapsed();
            return false;
        }
    });

1
alwaysshowAsAction属性设置值可以解决此问题。重要的是,当in中的alwaysis not存在时showAsActionSearchView仅当in SearchView中的查询为非null字符串时,expanded 才会显示关闭按钮(十字图标)。在SearchView.onCloseClicked该手柄关闭按钮的事件告诉回调OnCloseListener被称为只有当查询为空,如果它不是-它首先被清除-但是,结算查询关闭按钮消失后,我们无法提供onClose回调OnCloseListener
bpawlowski

1
只是一个提示:当用户关闭搜索视图时会调用此方法(很明显,但是我花了好几次时间才意识到)。用户第一次单击X会删除文本,而我没有得到该更新,第二次单击X会关闭SearchView并调用onClose。希望能帮助到你!
Federico Alvarez

4

为了使OnCloseListener工作正常,请确保在搜索菜单项中将其showAsAction设置为always

<menu 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"
      tools:context=".SearchActivity">

    <item
        android:id="@+id/search"
        android:title="@string/search"
        android:icon="@drawable/ic_search_toolbar"
        app:showAsAction="always"
        app:actionViewClass="android.support.v7.widget.SearchView"/>
</menu>

2

我在不调用SearchView的onCloseListener上遇到了相同的问题。了解25758中引发的错误问题以及我已阅读的一些帖子,以调用onCloseListener,您需要设置:

searchView.setIconifiedByDefault(true);

但是对于我来说,我想一直打开搜索视图,并且一直没有图标化。我设法通过在下面添加一行来解决此问题:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.search_bar, menu);
    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    searchView = (SearchView) menu.findItem(R.id.search).getActionView();
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    searchView.setOnQueryTextListener(queryTextListener);
    searchView.setIconifiedByDefault(true);
    searchView.setIconified(false);
    return true;
}

尽管在上一行中将默认设置设置为true,但searchView.setIconified(false)仍将导致searchView打开。通过这种方式,我设法同时拥有一个始终打开的SearchView和它调用的onCloseListener。


2

将菜单项app:showAsAction设置为始终创建。

<item   
 android:id="@+id/action_search"  
 android:title="..."  
 android:icon="..."  
 app:actionViewClass="android.support.v7.widget.SearchView"  
 app:showAsAction="always"/>

SearchViewonCreateOptionsMenu方法中创建时,请执行类似操作

inflater.inflate(R.menu.menu_search, menu);
final MenuItem item = menu.findItem(R.id.action_search);
final SearchView search = (SearchView) item.getActionView();
search.setQueryHint(getString(R.string.search_brand_item));
search.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
  @Override
  public boolean onQueryTextSubmit(String query) {
    // add your code
    return false;
  }

  @Override
  public boolean onQueryTextChange(String newText) {
    // add your code 
    return false;
  }
});
search.setOnCloseListener(new SearchView.OnCloseListener() {
  @Override
  public boolean onClose() {
    // add your code here
    return false;
  }
});
search.setIconifiedByDefault(true); // make sure to set this to true

search.setIconifiedByDefault(true)需要被设定为true调用onClose()的方法SearchView.OnCloseListener()之上创建的。



0

OnCloseListener未调用的原因是因为Android代码中存在错误-仅在您还调用的情况下才调用侦听器setIconifiedByDefault(true)


7
我只是尝试添加setIconifiedByDefault(true),但未调用
Giuseppe

@Joseph Earl:我在这里也遇到类似的问题: stackoverflow.com/questions/43702055/…。有关如何解决的任何想法或想法?
AJW

0

似乎已经是旧线程了,但是我想我在一开始就遇到了同样的问题API 18。到处搜寻之后,找到了这个线程,又花了一个小时阅读了我尝试并出错的javadoc,以了解我在Javadoc中没有完全理解的东西,现在对我来说以下工作:

searchView.setIconifiedByDefault(true);

   // OnQueryTextListener
   @Override
   public boolean onQueryTextSubmit(String query) {
      Log.d(tag, "onQueryTextSubmit: " + query);
      return true;
   }

   @Override
   public boolean onQueryTextChange(String query) {
      Log.d(tag, "onQueryTextChange: " + query);
      return true;
   }

   // OnCloseListener
   @Override
   public boolean onClose() {
      Log.w(tag, "onClose: ");
      return false;
   }

我玩过对/错的游戏,以某种方式有所作为,现在对我有用。希望它可以节省某人的时间。


0

这是一种解决方法,但对我有用

  searchView.setOnQueryTextListener(new android.widget.SearchView.OnQueryTextListener() {

                String lastText;

                @Override
                public boolean onQueryTextChange(final String newText) {
                    if (lastText != null && lastText.length() > 1 && newText.isEmpty()) {
                        // close ctn clicked

                        return true;
                    }
}

0
    searchView.setOnCloseListener {
        d("click", "close clicked")
        return@setOnCloseListener false
    }

如果单击关闭searchView->

D /点击:关闭点击


1
带有一小段代码和一些晦涩的单词的答案不是特别清楚。只需使用自然语言来描述为什么您认为这可以解决问题,然后说明解决方案的实现。

0

我在尝试检测SearchView的显示/关闭时遇到了此问题。我最终使用了另一个侦听器,它可以满足我的需要:

        setOnQueryTextFocusChangeListener { _, hasFocus ->
            if (hasFocus) {
                // SearchView is being shown
            } else {
                // SearchView was dismissed
            }
        }

0

我使用了SearchView关闭按钮,并在其上设置了setOnClickListener

searchView.findViewById<ImageView>(R.id.search_close_btn).setOnClickListener {
    searchView.setQuery("", false)
    searchView.clearFocus()
}

-2

Android中没有可登录的控制台。相反,请使用android日志记录框架:

Log.d("Test Tag", "Testing.  1, 2, 3...");

另请参阅以下问题:为什么“ System.out.println”在Android中不起作用?


2
不正确,它工作正常。请查看我更新的问题-我在onQueryTextChange方法中添加了一行以证明这一点。还尝试添加Log.d(),但也未显示任何内容。
米歇尔·巴克

哦,我不好!看起来他们决定将System.out.println输出到Log.i的过程中的某个地方。祝你好运
克里斯·奈特

-3

有两种常见的模式SearchView.setOnCloseListener()。所有听众都确实如此,但是我正在专门解决您的问题。第一种方法是创建侦听器函数并将其附加到成员变量,第二种方法是使类实现接口并使处理程序成为成员函数。

创建一个侦听器对象如下所示:

private SearchView mSearchView;
private final SearchView.OnCloseListener mOnCloseListener = 
    new SearchView.OnCloseListener() {
        public boolean onClose() {
            doStuff();
            return myBooleanResult;
        }
    };
mSearchView.setOnCloseListener(mOnCloseListener);

在类级别实现侦听器如下所示:

public class MyClass implements OnCloseListener {
    private SearchView mSearchView;

    public MyClass(...) {
        mSearchView.setOnCloseListener(this);
    }

    @Override
    public boolean onClose() {
        doStuff();
        return false;
    }
}

OnCloseListener正如您在问题中所做的那样,我还没有看到任何创建临时的示例。


嘿Sparky,感谢您对此发表评论。我真的不知道那应该如何改变任何东西。嵌套的侦听器也是一种有效的制作方法,它可以在Honeycomb上运行,您可以根据此处的评论看到它。除此之外,我在ICS上的嵌套侦听器都没有任何问题-再次适用于Honeycomb。
米歇尔·巴克

嵌套侦听器是指匿名内部类。
米歇尔·巴克

我同意这没关系。我只是评论代码库中的内容。我将看看是否可能重新定义了onClose的条件。
Sparky 2012年

我不确定您是否了解Java,它被称为匿名内部类。
约瑟夫·厄尔
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.