Tự động thu gọn Hành động trên thanh Tìm kiếmXem trên Bàn phím mềm Đóng


79

Tôi hiện đang sử dụng mục menu ActionBar để hiển thị SearchView trong thanh tác vụ. Khi mục menu tìm kiếm được mở rộng, bàn phím mềm được hiển thị, đó là những gì tôi muốn. Bây giờ, khi người dùng nhấn nút quay lại để đóng bàn phím mềm, tôi cũng muốn thu gọn SearchView trong thanh tác vụ.

Tôi đã thử triển khai các trình nghe sau OnKeyListener và OnFocusChangeListener trên MenuItem và ActionView. Tôi cũng đã thử sử dụng OnBackPressed () trong Hoạt động. Không có cách nào ở trên phát hiện khi nào nút quay lại được sử dụng để đóng bàn phím mềm.

Có ý kiến ​​gì không?

Tôi đã triển khai OnActionExpandListener để biết khi nào SearchView hiển thị.


Đây là một câu trả lời rất phổ biến stackoverflow.com/questions/1109022/…
jmishra Ngày

2
nó sẽ không giúp anh ta, anh ta cần phải ngăn chặn chìa khóa lại từ bàn phím
dor506

@acrespo Câu trả lời nào? Bạn nhận xét về một câu hỏi ...
Đáng kinh ngạc

Câu trả lời:


100

Tôi sẽ mở rộng về câu trả lời của @ user1258568 cho kẻ lười biếng. Điều này đã làm việc cho tôi. Lưu ý rằng nó sẽ xóa truy vấn của bạn khi mất tiêu điểm.

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
Hoạt động hoàn hảo. Nếu bạn thêm một searchView trong mã, bạn có thể cần sử dụng menu.getItem(yourSearchViewItemPosition)thay thế.
GeeF

@AlexBonel Như thế nào? Tôi biết rằng S3 và S4 có các nút phần cứng ngu ngốc, nhưng tôi không rõ điều đó sẽ ảnh hưởng đến đoạn mã này như thế nào. Có lẽ đó là do menu ActionBar bị ẩn và searchMenuItem hoạt động khác. Tôi đã có một chiếc S4 trên tay, tôi sẽ phải kiểm tra cái này.
Jon Willis

@JonWillis Nếu nó không khó đối với bạn, bạn có thể chia sẻ kinh nghiệm của bạn về hành vi đó trên S4 được không?
Alex Bonel

4
Thật tuyệt, sau nhiều giờ nghiên cứu và triển khai để cố gắng làm điều này, tôi đã tìm thấy câu trả lời của bạn :) ... Điều đầu tiên tôi nghĩ là sử dụng một bộ lắng nghe tập trung nhưng tôi đã sử dụng setOnFocusChangeListener()thay vì setOnQueryTextFocusChangeListener(). Với phương pháp của bạn, mọi thứ đều hoạt động tốt. Cảm ơn bạn.
Ionut Negru

2
@IonutNegru, bạn được chào đón! đôi khi phải yêu thích Android SDK. Tôi muốn thấy họ viết lại nó theo cách lành mạnh, hiện đại và loại bỏ hỗ trợ cũ, nhưng điều đó sẽ không bao giờ xảy ra.
Jon Willis

37

Tôi đã tìm thấy một giải pháp tốt hơn.

searchView.setOnQueryTextFocusChangeListener(). 

Được OnQueryTextFocusChangeListenergọi khi bàn phím được hiển thị hoặc ẩn. Được gọi đầu tiên khi bàn phím được hiển thị và chế độ xem tìm kiếm sẽ có tiêu điểm. Được gọi lại khi keyboardbị ẩn và chế độ xem tìm kiếm sẽ mất tiêu điểm, close search viewsau đó có thể sử dụng

menuItem.collapseActionView().

5
Điều này gây hiểu lầm. Các OnQueryTextFocusChangeListenerKHÔNG được gọi khi bàn phím được hiển thị hoặc ẩn. Nó chỉ được gọi khi được searchViewlấy nét và hoặc mất nét. Vì vậy, khi SearchViewtiêu điểm lần đầu tiên, phím OnQueryTextFocusChangeListenerđược gọi và bàn phím cũng được hiển thị. Bây giờ nếu nút quay lại được nhấn, bàn phím sẽ bị ẩn nhưng OnQueryTextFocusChangeListenerkhông được gọi. Khi nhấn nút quay lại lần thứ hai, nút sẽ searchViewsụp đổ và OnQueryTextFocusChangeListenerđược gọi.
faizal

11

Chỉ cần ghi đè onBackPressed như thế này:

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

và onCreateOptionsMenu của bạn sẽ làm phồng mSearchView như thế này:

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

lớp bạn có triển khai những điều sau như thế này không:

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

mà bạn cũng sẽ cần:

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

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

Bạn sẽ cần đặt "mSearchView" và "isClosed" cả hai biến toàn cục cho hoạt động.


3
Tôi không nghĩ rằng điều đó hiệu quả; theo kinh nghiệm của tôi, phương thức onBackPressed không được gọi nếu bàn phím bật lên; nó chỉ đơn giản là loại bỏ bàn phím và bạn cần nhấn lại lần nữa để gọi phương thức đó. Đây là ngày 2.3; Tôi chưa thử nghiệm với 3.x và 4.0 nhưng tôi nghi ngờ điều này cũng giống như vậy.
Kevlar

@Kevlar Tôi nghĩ bạn có thể đúng. Tôi sẽ kiểm tra điều này một lần nữa và chắc chắn rằng không có cách nào. Có vẻ như giải pháp của tôi hơi khác những gì họ muốn. Theo như tôi biết, tôi không nghĩ có cách nào để xử lý bất kỳ trở lại nào trong khi bàn phím mềm được hiển thị. Giải pháp của tôi xử lý sau khi đóng bàn phím. Sẽ thử nghiệm trên các SDK khác nhau.
Được đảo mã

1
tôi đã cố gắng thu gọn tìm kiếm bằng cách sử dụng: searchMenuItem.collapseActionView (); nhưng hóa ra là searchView.onActionViewCollapsed (); đã làm thủ thuật cho tôi - cảm ơn!
bkurzius

Tôi không nghĩ bạn nên gọi trực tiếp vào ... hàm. Những chức năng này không thực hiện để được gọi trực tiếp từ mã của bạn ...
user457015

làm thế nào để sử dụng collapseActionView () trên mức api 11.
Madan V

3

Câu trả lời từ Jon Willis rất tuyệt. Đây là một cải tiến cho câu trả lời của anh ấy.

Đầu tiên, tạo một lớp mới triển khai 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);
            }
        }
    }

}

Tiếp theo, đặt người nghe trên SearchView:

searchView.setOnQueryTextFocusChangeListener(new SearchViewFocusListener(menuItem));

hoạt động tốt, nhưng làm cách nào để xóa tiêu điểm khỏi biểu tượng tìm kiếm? FocusChangeListener ghi lại một lần nhấn nút Quay lại trên thiết bị và thao tác này sẽ đóng bàn phím mềm và đóng Chế độ xem tìm kiếm và sau đó biểu tượng tìm kiếm xuất hiện như tôi muốn. Tuy nhiên, biểu tượng tìm kiếm được tô sáng (có tiêu điểm) và tôi muốn nó không có tiêu điểm. Tôi đã thử một số cách để xóa nhưng không có may mắn. Có ý kiến ​​gì không?
AJW

2

Bạn chỉ cần đặt thuộc tính "sậpActionView" trong bố cục menu

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

Điều đó sẽ cung cấp cho bạn chức năng mà bạn tự tìm kiếm. Đừng quên gọi phương thức "clearFocus" trên SearchView để đóng bàn phím sau khi bạn gửi truy vấn.


1

Đây là những gì tôi đã làm để làm cho bàn phím biến mất. Bạn có thể thử xem cách này có phù hợp với bạn không. Tôi đặt thành ẩn searchViewvà sau đó hiển thị lại.

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

     });

Cũng phù hợp với tôi, nhưng bạn phải thêm getActivity (). SupportInvalidateOptionsMenu (); để khôi phục lại thanh hành động
almisoft

1

Nó có thể đạt được như thế này:

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

Các giải pháp dựa trên setOnQueryTextFocusChangeListener () không hoạt động với tôi vì sự kiện không được khởi chạy - Chế độ xem tìm kiếm không bị mất tiêu điểm khi được gửi, có thể do tôi thực hiện tìm kiếm trong cùng một hoạt động có Chế độ xem tìm kiếm.

Dù sao, tôi nghĩ sử dụng OnQueryTextListener là đúng hơn, vì nó mô tả sự kiện gửi văn bản chính xác hơn.


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

Nếu bạn muốn thu gọn bàn phím khi người dùng nhấp vào biểu tượng tìm kiếm trên bàn phím, điều này có thể đạt được bằng cách đơn giản

inside onquerytextsubmitted {

searchView.clearfocus()

}


0

Bạn cần gọi setIconified hai lần.

Để thực sự thu gọn chế độ xem tìm kiếm của bạn và đóng bàn phím.
Với cuộc gọi đầu tiên, văn bản của chế độ xem tìm kiếm sẽ bị xóa bằng bàn phím cuộc gọi thứ hai và chế độ xem tìm kiếm sẽ đóng lại.


0

Vì một số lý do, menuItem.collapseActionView()không hoạt động vì vậy tôi đã sử dụng searchView.setIconified(true)thay thế.

Điều này cho kết quả dưới đây là mẫu mã.

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);
        }
    }
});
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.