【问题标题】:Android ActionBar: collapsible SearchView with action buttonAndroid ActionBar:带有操作按钮的可折叠 SearchView
【发布时间】:2013-03-03 13:59:43
【问题描述】:

当搜索视图展开时,如何使用可折叠的搜索视图构建ActionBar,并显示单个操作项?为了更具描述性,这就是我需要的:

请注意,还有其他菜单项,android:uiOptions="splitActionBarWhenNarrow" 定义在 AndroidManifest.xml 中。

我尝试设置自定义搜索项布局:

menu.xml

<item
    android:id="@+id/menu_search"
    android:actionLayout="@layout/actionbar_search"
    android:icon="@drawable/action_search"
    android:showAsAction="always|collapseActionView"
    android:title="@string/search" />

actionbar_search.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="right"
    android:orientation="horizontal" >

    <com.actionbarsherlock.widget.SearchView
        android:id="@+id/search_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:iconifiedByDefault="false"
        android:queryHint="@string/search_hint" />

    <ImageButton
        android:id="@+id/add_item"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        style="@style/Widget.Sherlock.ActionButton"
        android:src="@drawable/content_new"/>

</LinearLayout>

但默认情况下,搜索视图会占用所有可用宽度,并且按钮不可见。我不知道如何强制SearchView 填充应用程序图标和菜单项之间的所有可用空间。我发现的只是android:maxWidth 属性,但这只允许硬编码维度,我正在寻找一些更灵活的解决方案。我还尝试了RelativeLayoutandroid:layout_toRightOf="@id/search_view",但没有成功。

【问题讨论】:

    标签: android android-actionbar searchview


    【解决方案1】:

    只是一个更改菜单 xml。应用名称的 showaction 前缀

    <menu xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto" >
    
    <item
        android:id="@+id/menu_search"
        android:actionLayout="@layout/actionbar_search"
        android:icon="@drawable/action_search"
        app:showAsAction="always|collapseActionView"
        android:title="@string/search"
    />
    
    </menu>
    

    【讨论】:

      【解决方案2】:

      在考虑了cmets的建议后,经过多次谷歌搜索和测试,成功获得了预期的效果。我对这个解决方案并不感到自豪,但它很有效,它并不太复杂,对于这种情况应该足够了。

      在简历中我做了什么:

      1. ActionBarcustomView 中放置SearchView 和自定义“添加项目”按钮。
      2. menu.xml 的搜索项中删除了collapseActionViewandroid:actionLayout
      3. 以编程方式折叠/展开SearchView

      一些代码可以更好地理解我做了什么。也许这对某人有用。

      menu.xml

      <item
          android:id="@+id/menu_search"
          android:icon="@drawable/action_search"
          android:showAsAction="always"
          android:title="@string/search" />
      
      // ... other menu items
      

      actionbar_search.xml

      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:gravity="right"
          android:orientation="horizontal">
      
          <com.actionbarsherlock.widget.SearchView
              android:id="@+id/search_view"
              android:layout_width="wrap_content"
              android:layout_height="match_parent"
              android:iconifiedByDefault="false"
              android:queryHint="@string/search_hint"
              android:visibility="invisible" />
      
          <ImageButton
              android:id="@+id/add_item"
              android:layout_width="wrap_content"
              android:layout_height="match_parent"
              style="@style/Widget.Sherlock.ActionButton"
              android:src="@drawable/content_new"
              android:title="@string/add_item" />
      
      </LinearLayout>
      

      MainActivity.java

      @Override
      public void onCreate(Bundle savedInstanceState) {
          // ...
          actionBar.setCustomView(R.layout.actionbar_search);
          actionBarCustomView = ab.getCustomView();
          searchView = ((SearchView) actionBarCustomView.findViewById(R.id.search_view));
          searchView.setOnCloseListener(new SearchView.OnCloseListener() {
              @Override
              public boolean onClose() {
                  searchView.setVisibility(View.INVISIBLE);
                  return false;
              }
          });
      }
      
      @Override
      public boolean onOptionsItemSelected(MenuItem item) {
          switch (item.getItemId()) {
              // ...
              case R.id.menu_search:
                  if (searchView.getVisibility() == View.VISIBLE) {
                      searchView.setIconified(true);
                      searchView.setVisibility(View.INVISIBLE);
                  } else {
                      searchView.setMaxWidth(abCustomView.getWidth() - addButton.getWidth());
                      searchView.setVisibility(View.VISIBLE);
                      searchView.setIconified(false);
                  }
                  break;
              // ...
          }
          return true;
      }
      
      @Override
      public void onBackPressed() {
      
          if (searchView.getVisibility() == View.VISIBLE) {
              searchView.setIconified(true);
              searchView.setVisibility(View.INVISIBLE);
              return;
          }
      
          // ...
      }
      

      【讨论】:

      • 您好,我已经尝试过您的上述解决方案,但它根本不起作用。事实上,我看不到任何行动项目。
      • 您可以发布您的代码片段(例如,作为要点)吗?我花了几天时间弄清楚并测试,认为我可以提供帮助。
      • 我应该在哪里发布我的代码片段??我不能在这里发布我的问题代码作为评论。另外,您能帮我实现这一目标吗:stackoverflow.com/questions/15947557/…
      • 您可以使用,例如gist.github.com 在此处发布代码片段并粘贴链接。如果我今天有时间,我会尽力帮助您解决问题。
      • 只是让您知道,通过在 actionbar_search.xml 中使用 RelativeLayout 并简单地给 imageButton alignParentRight=true 来实现这一点要容易得多。您还需要将 android:layout_toLeftOf="@+id/add_item" 添加到您的 SearchView。刚刚测试,工作正常
      【解决方案3】:

      你可以这样做

      @Override
      public boolean onCreateOptionsMenu(Menu menu) {
           getMenuInflater().inflate(R.menu.main, menu);
           MenuItem searchItem = menu.findItem(R.id.action_search);
           searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
           searchView.setIconified(true); //to be opened collapsed
          return true;
      }
      
      @Override
      public boolean onOptionsItemSelected(MenuItem item) {
          switch(item.getItemId()){
      
              case R.id.action_search:
                  searchView.setIconified(false);// to Expand the SearchView when clicked
                  return true;
          }    
          return false;
      }
      

      并且在 menu.xml 中的搜索项 make

      showAsAction="always"

      注意:我使用的是 android.support.v7.widget.SearchView 但在你的情况下没关系

      【讨论】:

      • @salma 是的,你说得对 android.support.v7.widget.SearchView 和 android.widget.searchview 很重要
      【解决方案4】:

      您只能使用 yourmenu.xml 来做到这一点。

      将您的其他菜单图标设置为始终显示为操作。 您的 menu.xml 应如下所示:

      <item
          android:id="@+id/menu_search"
          android:actionLayout="@layout/actionbar_search"
          android:icon="@drawable/action_search"
          android:showAsAction="always|collapseActionView"
          android:title="@string/search"
      />
      <item
          android:id="@+id/your_other_menu_id"
          android:showAsAction="always"
          android:icon="@android:drawable/your_other_menu_ic"
       />
      

      【讨论】:

      • 试过这种方法。正如我提到的,还有其他菜单项,它们都溢出到底部操作栏。我需要这个添加动作总是放在右上角。
      • 本例中的细节是拆分操作栏,而不是可折叠的搜索视图。检查下面的链接。无法使用本机对象设置此行为。您需要创建自己的自定义操作栏。 stackoverflow.com/questions/8571754/…
      • 感谢您的建议,但我也已经尝试过这个。当 SearchView 折叠时,自定义 ActionBar 为我提供自定义视图。然后我在顶部栏有我的单个按钮,在底部有那些表单 menu.xml。问题是当 SearchView 展开时。我需要强制它填充应用程序图标和单个操作项之间的所有可用空间。我试图了解 SearchView 类的onMeasure() 中发生了什么,但并不完全了解我能用它做什么,如果它完全是一个正确的方向。任何帮助将不胜感激。
      • 您是否尝试过创建自己的操作视图类?也许您可以简单地扩展 SearchView 类,但我不确定。在resume中,你可以做的是: 1.创建一个实现CollapsibleActionView的类(可能是扩展SearchView);您可以在哪里实现 onActionViewExpanded() 在 TextEdit 之后为您的菜单项添加一个按钮。 2.在你的菜单项上设置这个类作为动作视图类:android:actionViewClass="your.package.YourSearchView"