소프트 키보드의 ActionBar SearchView 자동 축소 닫기


79

현재 ActionBar 메뉴 항목을 사용하여 작업 표시 줄에 SearchView를 표시하고 있습니다. 검색 메뉴 항목이 확장되면 내가 원하는 소프트 키보드가 표시됩니다. 이제 사용자가 뒤로 버튼을 눌러 소프트 키보드를 닫을 때 작업 표시 줄에서 SearchView도 축소하고 싶습니다.

MenuItem 및 ActionView에서 다음 리스너 OnKeyListener 및 OnFocusChangeListener를 구현하려고 시도했습니다. 나는 또한 활동에서 OnBackPressed ()를 사용해 보았습니다. 위의 어느 것도 소프트 키보드를 닫기 위해 뒤로 버튼을 사용하는 경우를 감지하지 않습니다.

어떤 아이디어?

SearchView가 표시되는시기를 알기 위해 OnActionExpandListener를 구현했습니다.


여기에 매우 인기있는 답변입니다 stackoverflow.com/questions/1109022/...은
jmishra은

2
그것은 그에게 도움이되지 않습니다, 그는 키보드에서 다시 키를 가로 챌 필요
dor506

@acrespo 무슨 대답? 질문에 댓글을 달았습니다 ...
The 믿을 수없는 Jan

답변:


100

게으른 사람에 대한 @ user1258568의 답변을 확장하겠습니다. 이것은 나를 위해 일했습니다. 포커스를 잃으면 쿼리가 지워집니다.

final MenuItem searchMenuItem = optionsMenu.findItem(R.id.search);
final SearchView searchView = (SearchView) searchMenuItem.getActionView();

searchView.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View view, boolean queryTextFocused) {
        if(!queryTextFocused) {
            searchMenuItem.collapseActionView();
            searchView.setQuery("", false);
        }
    }
});

1
완벽하게 작동합니다. 코드에 searchView를 추가하면 menu.getItem(yourSearchViewItemPosition)대신 사용해야 할 수도 있습니다 .
GeeF 2013

@AlexBonel 어떻게 그렇게? S3와 S4에 멍청한 하드웨어 버튼이 있다는 것을 알고 있지만 이것이이 스 니펫에 어떤 영향을 미칠지 확실하지 않습니다. 아마도 ActionBar 메뉴가 숨겨져 있고 searchMenuItem이 다르게 작동하기 때문일 수 있습니다. 손에 S4가 있는데 이것을 테스트해야합니다.
Jon Willis 2013 년

@JonWillis 어렵지 않다면 S4에서 그러한 행동에 대한 경험을 공유해 주시겠습니까?
알렉스 Bonel

4
좋아, 몇 시간의 연구와 구현을 통해 답을 찾았습니다. :) ... 처음에는 포커스 리스너를 사용하는 것으로 생각했지만 setOnFocusChangeListener()대신 setOnQueryTextFocusChangeListener(). 당신의 방법으로 모든 것이 잘 작동합니다. 감사합니다.
Ionut Negru 2014 년

2
@IonutNegru 천만에요! 때때로 Android SDK를 좋아해야합니다. 나는 그들이 정상적이고 현대적인 방식으로 그것을 다시 작성하고 레거시 지원을 중단하는 것을보고 싶지만 결코 일어나지 않을 것입니다.
Jon Willis

37

더 나은 해결책을 찾았습니다.

searchView.setOnQueryTextFocusChangeListener(). 

OnQueryTextFocusChangeListener키보드가 표시되거나 숨겨 때 호출됩니다. 키보드가 표시되고 검색보기에 포커스가있을 때 먼저 호출됩니다. keyboard가 숨겨지고 검색보기가 포커스를 잃을 때 다시 호출 되며 close search view다음을 사용할 수 있습니다.

menuItem.collapseActionView().

5
이것은 오해의 소지가 있습니다. 는 OnQueryTextFocusChangeListener키보드가 표시되거나 숨겨 때 호출되지 않습니다. searchView초점이 맞거나 초점이 맞지 않을 때만 호출됩니다 . 따라서에 SearchView처음으로 초점이 맞춰지면 OnQueryTextFocusChangeListener이 호출되고 키보드도 표시됩니다. 이제 뒤로 버튼을 누르면 키보드가 숨겨 지지만 OnQueryTextFocusChangeListener호출되지 않습니다. 뒤로 버튼을 두 번 누르면 searchView축소되고 OnQueryTextFocusChangeListener호출됩니다.
faizal

11

다음과 같이 onBackPressed를 재정의하십시오.

@Override
    public void onBackPressed() {
        if (searchView.isShown()){
            searchView.onActionViewCollapsed();  //collapse your ActionView
            searchView.setQuery("",false);       //clears your query without submit
            isClosed = true;                     //needed to handle closed by back
        } else{
            super.onBackPressed();
        }
    }

onCreateOptionsMenu는 다음과 같이 mSearchView를 팽창시킵니다.

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        getMenuInflater().inflate(R.menu.menu_search, menu);
        mSearchView = (SearchView) menu.findItem(R.id.menu_action_search).getActionView();
        mSearchView.setOnQueryTextListener(this);
        mSearchView.setOnSearchClickListener(this);
        mSearchView.setOnCloseListener(this);
        isClosed = true;
        return true;
    }

클래스가 다음과 같이 구현 했습니까?

public class myActivity extends FragmentActivity implements
    SearchView.OnQueryTextListener, View.OnClickListener, SearchView.OnCloseListener {

또한 다음이 필요합니다.

@Override
public void onClick(View view) {
    isClosed = false;
}

@Override
public boolean onClose() {
    isClosed = true;
    return false;
}

활동에 대해 "mSearchView"및 "isClosed"를 모두 전역 변수로 만들어야합니다.


3
나는 그것이 효과가 있다고 생각하지 않는다. 내 경험상 키보드가 켜져 있으면 onBackPressed 메서드가 호출되지 않습니다. 단순히 키보드를 닫고 해당 메서드를 호출하려면 다시 눌러야합니다. 이것은 2.3에 있습니다. 나는 3.x와 4.0으로 실험하지 않았지만 이것이 거기에서도 동일하다고 생각합니다.
Kevlar

@Kevlar 나는 당신이 맞을 것이라고 생각합니다. 나는 이것을 다시 테스트하고 방법이 없는지 확인합니다. 내 솔루션이 원하는 것과 약간 다른 것 같습니다. 내가 아는 한 소프트 키보드가 표시되는 동안 등을 처리 할 방법이 없다고 생각합니다. 내 솔루션은 키보드가 확실히 닫힌 후에 처리됩니다. 다른 SDK에서 테스트합니다.
Codeversed

1
다음을 사용하여 검색을 축소하려고했습니다. searchMenuItem.collapseActionView (); 그러나 그것은 searchView.onActionViewCollapsed (); 나를 위해 트릭을 해주셨습니다-감사합니다!
bkurzius

나는 당신이 직접 호출해야한다고 생각하지 않습니다 ... 함수. 이러한 기능은 ... 사용자 코드에서 직접 호출 할 이루어지지
user457015

API 레벨 11에서 collapseActionView ()를 사용하는 방법
madan V

3

Jon Willis의 답변은 훌륭합니다. 이것은 그의 대답에 대한 개선입니다.

먼저 View.OnFocusChangeListener다음 을 구현하는 새 클래스를 만듭니다 .

public class SearchViewFocusListener implements View.OnFocusChangeListener {

    private final MenuItem mMenuItem;

    public SearchViewFocusListener(MenuItem menuItem) {
        mMenuItem = menuItem;
    }

    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (!hasFocus) {
            mMenuItem.collapseActionView();
            if (v instanceof SearchView) {
                ((SearchView) v).setQuery("", false);
            }
        }
    }

}

다음으로 리스너를 설정하십시오 SearchView.

searchView.setOnQueryTextFocusChangeListener(new SearchViewFocusListener(menuItem));

잘 작동하지만 검색 아이콘에서 초점을 지우려면 어떻게해야합니까? FocusChangeListener는 장치에서 뒤로 버튼을 누르면 소프트 키보드를 닫고 SearchView를 닫으면 원하는대로 검색 아이콘이 나타납니다. 그러나 검색 아이콘이 강조 표시되고 (포커스 있음) 포커스가없는 것이 좋습니다. 몇 가지 방법을 시도했지만 운이 없었습니다. 어떤 아이디어?
AJW

2

메뉴 레이아웃에 "collapseActionView"속성 만 넣으면됩니다.

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/menu_item_search"
        android:title="@string/search"
        android:iconifiedByDefault="true"
        android:icon="@drawable/ic_action_search" 
        app:actionViewClass="android.support.v7.widget.SearchView"
        app:showAsAction="ifRoom|collapseActionView"/> <--this one
</menu>

그 자체로 모든 기능을 찾을 수 있습니다. 쿼리를 보낸 후에는 SearchView에서 "clearFocus"메서드를 호출하여 키보드를 닫는 것을 잊지 마십시오.


1

이것이 제가 키보드를 사라지게하기 위해 한 것입니다. 이것이 당신을 위해 작동하는지 확인할 수 있습니다. searchView를 숨김으로 설정 한 다음 다시 표시합니다.

    //set query change listener
     searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener(){
        @Override
        public boolean onQueryTextChange(String newText) {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public boolean onQueryTextSubmit(String query) {
            /**
             * hides and then unhides search tab to make sure keyboard disappears when query is submitted
             */
                  searchView.setVisibility(View.INVISIBLE);
                  searchView.setVisibility(View.VISIBLE);
            return false;
        }

     });

나를 위해 일했지만 getActivity (). supportInvalidateOptionsMenu (); 작업 표시 줄을 복원
almisoft

1

다음과 같이 달성 할 수 있습니다.

   private void setupSearchView(Menu menu) {
        final MenuItem searchMenuItem = menu.findItem(R.id.action_search);
        final SearchView searchView = (SearchView) searchMenuItem.getActionView();

        [...]

        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                searchMenuItem.collapseActionView();
                return false;
            }
            @Override
            public boolean onQueryTextChange(String newText) {
                return true;
            }
        });
    }

이벤트가 시작되지 않았기 때문에 setOnQueryTextFocusChangeListener () 기반 솔루션이 작동하지 않았습니다. 검색 뷰가 포함 된 동일한 활동에서 검색을 수행했기 때문에 searchView가 제출 될 때 포커스를 잃지 않았습니다.

어쨌든 OnQueryTextListener를 사용하는 것이 텍스트를 더 정확하게 제출하는 이벤트를 설명하기 때문에 더 정확하다고 생각합니다.


0
@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getSupportMenuInflater().inflate(R.menu.home_screen, menu);

        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        final MenuItem searchMenuItem = menu.findItem(R.id.menu_search);
        final SearchView searchView = (SearchView) searchMenuItem
                .getActionView();
        searchView.setIconifiedByDefault(false);
        if (searchManager != null && searchView != null) {
            searchView.setSearchableInfo(searchManager
                    .getSearchableInfo(getComponentName()));

            searchView
                    .setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {

                        @Override
                        public void onFocusChange(View v, boolean hasFocus) {

                            if (!hasFocus) {
                                if (searchMenuItem != null) {
                                    searchMenuItem.collapseActionView();
                                }// end if
                                if (searchView != null) {
                                    searchView.setQuery("", false);

                                }// end if
                            }// end if

                        }
                    });

            searchView
                    .setOnQueryTextListener(new SearchView.OnQueryTextListener() {

                        @Override
                        public boolean onQueryTextSubmit(String query) {
                            /**
                             * hides and then unhides search tab to make sure
                             * keyboard disappears when query is submitted
                             */
                            if (searchView != null) {
                                searchView.setVisibility(View.INVISIBLE);
                                searchView.setVisibility(View.VISIBLE);

                            }
                            return false;
                        }

                        @Override
                        public boolean onQueryTextChange(String newText) {
                            // TODO Auto-generated method stub
                            return false;
                        }
                    });

        }

        return super.onCreateOptionsMenu(menu);
    }

0

사용자가 키보드에서 검색 아이콘을 클릭 할 때 키보드를 접으려면 간단하게 수행 할 수 있습니다.

inside onquerytextsubmitted {

searchView.clearfocus()

}


0

setIconified를 두 번 호출해야합니다.

실제로 검색보기를 축소하고 키보드를 닫습니다.
첫 번째 통화로 검색보기의 텍스트가 두 번째 통화 키보드로 지워지고 검색보기가 닫힙니다.


0

왠지 menuItem.collapseActionView()작동하지 않아 searchView.setIconified(true)대신 사용 했습니다.

이것은 코드 샘플로 아래 결과를 제공합니다.

final MenuItem searchItem = (MenuItem) menu.findItem(R.id.menu_item_search);
final SearchView searchView = (SearchView) searchItem.getActionView();

searchView.setOnQueryTextFocusChangeListener(new SearchView.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (!hasFocus) {
            searchView.setIconified(true);
        }
    }
});
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.