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
이 문제가 나뿐만 아니라 다행입니다. 누구든지 아래의 것 외에 다른 해킹이 있습니까?
bencallis

2
showAsAction로 설정된 경우 두 가지를 배웠습니다 always. 검색 창에는 자체 닫기 버튼이 있지만 설정되어 ifRoom | collapseActionView있으면 작업 표시 줄에서 확장됩니다.
Beraki 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;
}

우리는 단지 벌집 +입니다 액션 바의 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

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)를 사용하여 확장했다면 어떻게됩니까? 작동하지 않습니다 ... :(
Joan Casadellà

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

오 좋아, 지금 봐. 그러나 어쨌든 상태 변경 리스너를 사용한이 해결 방법은 다른 사람들에게도 유용 할 수 있습니다.
Dario

OnCloseListener가 생각대로 작동하지 않는다는 점은 실망 스럽지만 실제로는 훌륭하고 깨끗한 솔루션입니다. 명성!
welshk91

10

나는 결국 내 목적에 잘 맞는 약간의 해킹을 사용했습니다. 모든 목적에서 작동하는지 확실하지 않습니다. 어쨌든 검색 쿼리가 비어 있는지 확인하고 있습니다. 이것은 실제로 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; }
        });

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하면 문제가 해결됩니다. 중요한 것은입니다 alwaysis not에 존재하는이 showAsAction확장 SearchView선물 쿼리는 경우에만 닫기 버튼 (크로스 아이콘) SearchViewnull 이외의 문자열입니다. 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;
}

searchView.setIconified (false)는 이전 행에서 기본값을 iconified로 설정 했음에도 불구하고 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"/>

SearchViewin 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과 같은 문제가 있다고 생각했습니다. 주위를 훑어 본 후이 스레드를 찾은 후 한 시간 더 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 () 추가를 시도했지만 아무것도 표시하지 않았습니다.
Michell Bak

오, 이런! System.out.println을 Log.i에 출력하기로 결정한 길을 따라 보이는 것 같습니다. 행운을 빕니다
Chris Knight

-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귀하의 질문에서했던 것처럼 ad-hoc 을 만드는 예 를 보지 못했습니다.


안녕하세요 Sparky, 이에 대해 의견을 보내 주셔서 감사합니다. 나는 그것이 어떤 것을 어떻게 바꾸어야하는지 정말로 모른다. 중첩 된 리스너는이를 만드는 유효한 방법이며 여기에있는 주석을 기반으로 볼 수 있듯이 Honeycomb에서 작동합니다. 나는 Honeycomb에서 다시 작동하는 ICS의 중첩 된 리스너와 관련된 문제가 없었습니다.
Michell Bak 2012

중첩 된 리스너 란 익명의 내부 클래스를 의미합니다.
Michell Bak 2012

나는 그것이 중요하지 않다는 데 동의합니다. 나는 코드베이스에있는 것에 대해서만 언급하고있다. onClose가 재정의 된 조건이 있는지 살펴 보겠습니다.
Sparky

Java를 이해하고 있는지 잘 모르겠습니다. 익명의 내부 클래스라고합니다.
Joseph Earl
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.