ChatGPT解决这个技术问题 Extra ChatGPT

软键盘关闭时自动折叠 ActionBar SearchView

我目前正在使用 ActionBar 菜单项在操作栏中显示 SearchView。当搜索菜单项展开时,会显示我想要的软键盘。现在,当用户按下后退按钮关闭软键盘时,我还想折叠操作栏中的 SearchView。

我尝试在 MenuItem 和 ActionView 上实现以下侦听器 OnKeyListener 和 OnFocusChangeListener。我也尝试在 Activity 中使用 OnBackPressed()。以上都没有检测到何时使用后退按钮关闭软键盘。

有任何想法吗?

我已经实现了 OnActionExpandListener 以了解 SearchView 何时可见。

这是一个非常受欢迎的答案stackoverflow.com/questions/1109022/…
这对他没有帮助,他需要拦截键盘上的后退键
@acrespo 什么答案?你对一个问题发表评论...

J
Jared Rummler

我将扩展 @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);
        }
    }
});

完美运行。如果您在代码中添加 searchView,您可能需要改用 menu.getItem(yourSearchViewItemPosition)
@AlexBonel 怎么样?我知道 S3 和 S4 有白痴硬件按钮,但我不清楚这会如何影响这个片段。可能是因为 ActionBar 菜单是隐藏的,而 searchMenuItem 的行为不同。我手头有S4,我得测试一下。
@JonWillis 如果对您来说并不困难,您能否分享您在 S4 上的此类行为的经验?
很好,经过数小时的研究和实施尝试这样做,我找到了您的答案 :) ...我首先想到的是使用焦点侦听器,但我使用了 setOnFocusChangeListener() 而不是 setOnQueryTextFocusChangeListener()。使用您的方法,一切正常。谢谢你。
@IonutNegru,不客气!有时必须喜欢 Android SDK。我希望看到他们以一种理智、现代的方式重写它并放弃遗留支持,但这永远不会发生。
N
NagarjunaReddy

我找到了更好的解决方案。

searchView.setOnQueryTextFocusChangeListener(). 

OnQueryTextFocusChangeListener 在键盘显示或隐藏时被调用。当显示键盘并且搜索视图将具有焦点时首先调用。当 keyboard 被隐藏并且搜索视图将失去焦点时再次调用,close search view然后可以使用

menuItem.collapseActionView().

这是误导。显示或隐藏键盘时不会调用 OnQueryTextFocusChangeListener。只有当 searchView 进入焦点和/或失去焦点时才会调用它。因此,当 SearchView 第一次成为焦点时,会调用 OnQueryTextFocusChangeListener 并显示键盘。现在,如果按下后退按钮,键盘将被隐藏,但不会调用 OnQueryTextFocusChangeListener。第二次按下后退按钮时,searchView 折叠并调用 OnQueryTextFocusChangeListener
C
Codeversed

只需像这样覆盖 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”这两个全局变量都添加到活动中。


我认为这行不通;根据我的经验,如果键盘启动,则不会调用 onBackPressed 方法;它只是关闭键盘,您需要再次按下以使其调用该方法。这是2.3;我还没有尝试过 3.x 和 4.0,但我怀疑这也是一样的。
@Kevlar 我认为您可能是正确的。我将再次对此进行测试并确保没有办法。似乎我的解决方案与他们想要的略有不同。据我所知,在显示软键盘时,我认为没有办法处理任何背部。我的解决方案肯定会在键盘关闭后处理。将在不同的 SDK 上进行测试。
我曾尝试使用以下方法折叠搜索:searchMenuItem.collapseActionView();但结果是 searchView.onActionViewCollapsed();为我做了诀窍-谢谢!
我认为您不应该直接调用...函数。这些函数不会直接从您的代码中调用...
如何在 api 级别 11 上使用 collapseActionView()。
J
Jared Rummler

乔恩威利斯的回答很好。这是对他的回答的改进。

首先,创建一个实现 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,然后搜索图标按我的意愿出现。但是,搜索图标突出显示(有焦点),我希望它没有焦点。我尝试了几种清除方法,但没有运气。有任何想法吗?
R
Rodrigo de Blas

只需在菜单布局中放入“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”以关闭键盘。


P
Parnit

这就是我为使键盘消失所做的。您可以尝试看看这是否适合您。我将 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();恢复操作栏
G
GaRRaPeTa

可以这样实现:

   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 更正确,因为它更准确地描述了提交文本的事件。


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

g
geniushkg

如果您想在用户单击键盘上的搜索图标时折叠键盘,这可以通过简单的方式来实现

inside onquerytextsubmitted {

searchView.clearfocus()

}


D
David 'mArm' Ansermot

您需要调用 setIconified 两次。

实际折叠您的搜索视图并关闭键盘。使用第二个呼叫键盘清除搜索视图的第一个呼叫文本并关闭搜索视图。


b
bastien

由于某种原因,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);
        }
    }
});

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅