Programing

SearchView의 OnCloseListener가 작동하지 않습니다.

lottogame 2020. 8. 24. 20:51
반응형

SearchView의 OnCloseListener가 작동하지 않습니다.


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

나도이 문제를 만났고, "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;
}

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


이 문제에 대해 저는 이와 같은 것을 생각해 냈습니다.

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);

}

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


나는 결국 내 목적에 잘 맞는 약간의 해킹을 사용했습니다. 모든 목적에서 작동하는지 확실하지 않습니다. 어쨌든 검색 쿼리가 비어 있는지 확인하고 있습니다. 이것은 실제로 SearchView's 와 관련이 없습니다 OnCloseListener-여전히 작동하지 않습니다!

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

음, 이것은 내 문제를 해결했습니다.

메뉴 항목 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;
        }
    });

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

The searchView.setIconified(false) will cause the searchView to open up, despite setting the default to iconified to true in the previous line. In this way, I managed to have both a SearchView that opens up all the time & having it invoke the onCloseListener.


In order to make the OnCloseListener work, make sure that showAsAction is set to always in the search menu item.

<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>

For MenuItemCompat problem I added ViewTreeObserver to track the visibility state. You can check my answer here: https://stackoverflow.com/a/28762632/1633609


Create the menu item with the app:showAsAction set to always.

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

When creating the SearchView in the onCreateOptionsMenu method do something similar

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

The search.setIconifiedByDefault(true) needs to be set to true to call the onClose() method on the SearchView.OnCloseListener() created above.


The reason the OnCloseListener is not called is because there is a bug in the Android code -- the listener is only called if you also call setIconifiedByDefault(true).


seems an old thread already, but I thought I got the same problem API 18 in the first beginning. After googled around, found this thread, another hour read the javadoc tried and errored for something I don't pretend fully understand in javadoc, the following work for me now:

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

I played with true/false a bit, that somehow makes the difference, and it works for me now. Hopefully, it could save someone time.


It's a workaround but has worked for me

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

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

if you click on close searchView ->

D/click: close clicked


I encountered this issue while trying to detect the showing/dismissal of the SearchView. I ended up using a different listener and it worked for what I need:

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

There is no console in Android to log to. Instead, use the android logging framework:

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

See also this question: Why doesn't "System.out.println" work in Android?


There are two common patterns for SearchView.setOnCloseListener(). This is really true of all listeners, but I'm addressing your question specifically. The first way is to create a listener function and attach it to a member variable, and the second is to make the class implement the interface and have the handler be a member function.

Creating a listener object looks like this:

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

Implementing listener at class level looks like this:

public class MyClass implements OnCloseListener {
    private SearchView mSearchView;

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

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

I have not seen any examples that create the OnCloseListener ad-hoc, as you did in your question.

참고URL : https://stackoverflow.com/questions/9327826/searchviews-oncloselistener-doesnt-work

반응형