SearchViewのOnCloseListenerが機能しない


101

SearchViewAndroid 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

私はを通じて見てきたドキュメントやサンプルが、何もそれを変えたようだっありません。Asus 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

10
バグの発生、25758
PJL

3
私だけがこの問題を抱えているのではないことをうれしく思います。以下のハック以外のハックがありますか?
ベンカリス、2012年

2
showAsActionがに設定されてalwaysいる場合、2つのことを学びました。検索ボックスには独自の閉じるボタンがありますが、設定されてifRoom | collapseActionViewいる場合、アクションバーで展開されます。
ベラキ2016

回答:


153

私もこの問題に直面しており、「oncloselistener」をあきらめるしかありません。代わりに、menuItem、次にを取得できますsetOnActionExpandListener。次に、実装されていないメソッドをオーバーライドします。

@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

onCloseListenerを使用するのではなく、メニュー項目でこれを使用してください。
Robert

12
私は、以前のAPIレベルのMenuItemCompat.OnActionExpandListenerを使用することができると思う: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 2017

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)を使用して展開した場合はどうなりますか?それはうまくいきません... :(
JoanCasadellà

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


はい、そのバグは私がこの質問を投稿した直後に作成されました。元の質問のコメントを参照してください。
Michell Bak、2014

ああ、わかりました。しかし、とにかく、状態変更リスナーを使用したこの回避策は、他の人にも役立つかもしれません。
ダリオ

OnCloseListenerが思ったように機能しないのは残念ですが、これは実際には素晴らしいクリーンなソリューションです。賞賛!
welshk91

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
属性にalways値を設定showAsActionすると、問題が解決します。重要なことは、にalways値がis not存在する場合、クエリがnull以外の文字列である場合にのみshowAsAction、展開SearchViewすると閉じるボタン(クロスアイコン)が表示されることSearchViewです。SearchView.onCloseClickedハンドル閉じるボタンのイベントはにそのコールバックを伝えることOnCloseListener、それが最初にクリアしています- -しかし、その後、クエリ閉じるボタンが消えるをクリアした後、我々は提供することができない、クエリが空である場合にのみ呼び出されることはありません場合onCloseにコールバックをOnCloseListener
bpawlowski

1
ヒント:このメソッドは、ユーザーが検索ビューを閉じたときに呼び出されます(明らかですが、実現するまでに数回かかりました)。ユーザーが最初にXをクリックするとテキストが消去され、更新は取得されませんでした。Xの2回目のクリックでSearchViewが閉じ、onCloseが呼び出されます。それが役に立てば幸い!
フェデリコアルバレス

4

機能させるにはOnCloseListener、それshowAsActionalways検索メニュー項目でに設定されていることを確認してください。

<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

onCloseListenerがSearchViewを呼び出さないと同じ問題が発生しました。25758で発生したバグの問題と、私が読んだいくつかの投稿から、onCloseListenerを呼び出すには、次のように設定する必要があることを理解してください。

searchView.setIconifiedByDefault(true);

しかし、私の場合は、常に検索ビューを開いてアイコン化しないようにしたいと考えました。以下の行を1行追加することで、この問題を解決しています。

@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;
}

searchView.setIconified(false)を使用すると、前の行でデフォルトをiconifiedにtrueに設定しても、searchViewが開きます。このようにして、常に開くSearchViewと、onCloseListenerを呼び出すようにすることができました。


2

app:showAsActionalwaysに設定したメニュー項目を作成します。

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

メソッドでを作成するときSearchViewに、onCreateOptionsMenu同様のことを行います

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 2017

0

すでに古いスレッドのようですが、最初は同じ問題のAPI 18を取得したと思いました。グーグルで回った後、このスレッドを見つけ、さらに1時間、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;
   }

私は少しtrue / 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
    }

close 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...");

この質問もご覧ください:Androidで「System.out.println」が機能しないのはなぜですか?


2
本当ではない、それはうまく働きます。私の更新された質問を参照してください-私はそれを証明するためにonQueryTextChangeメソッドに行を追加しました。Log.d()の追加も試みましたが、何も表示されませんでした。
Michell Bak

ああ、悪い!彼らがSystem.out.printlnをLog.iに出力することに決めた途中のどこかのように見えます。幸運
クリスナイト

-3

には2つの一般的なパターンがありますSearchView.setOnCloseListener()。これは本当にすべてのリスナーに当てはまりますが、私は具体的にあなたの質問に取り組んでいます。1つ目は、リスナー関数を作成してメンバー変数にアタッチする方法で、2つ目は、クラスにインターフェイスを実装させ、ハンドラーをメンバー関数にする方法です。

リスナーオブジェクトの作成は次のようになります。

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でも動作します。
ミシェルバック

ネストされたリスナーとは、匿名の内部クラスを意味します。
Michell Bak、2012

それは問題ではないことに同意します。私はコードベースに何が存在するかについてのみコメントしています。onCloseが再定義された条件を調べてみます。
Sparky、

私はあなたがJavaを理解しているとは思いません-それは匿名の内部クラスと呼ばれています
ジョセフアール
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.