【问题标题】:Android search with Fragments使用 Fragments 进行 Android 搜索
【发布时间】:2011-11-06 01:12:42
【问题描述】:

有人知道如何使用Fragments 实现标准Android search interface 的教程或示例吗?换句话说,是否可以在 Fragment 中使用 SearchManager 进行标准搜索?

【问题讨论】:

  • 你会把奖金授予@blackbelt 吗?Raghav 给出了我一直在寻找的答案。但亚历克斯洛克伍德也回答了你问题的第一部分。
  • 我接受 LockWood 的回答。随心所欲地奖励赏金(我认为更好)
  • 我很高兴我们最终得到了如此多的正确答案和解决方法! :)
  • 谁能给我这个问题的答案..?我被困在这里stackoverflow.com/questions/10600660/…
  • 在将 SearchView 添加到操作栏后,我正在使用这种技术留在片段中:stackoverflow.com/a/6939735/1068167。我的申请尚未完成,但希望它会起作用。

标签: java android sqlite android-fragments android-searchmanager


【解决方案1】:

简而言之,你不能。无法在 Fragment 中创建搜索界面的原因有很多。

  1. 创建可搜索界面时,您必须在 Android 清单中指定默认的“可搜索活动”。我相信您知道,如果没有父 ActivityFragment 就无法存在,因此这种分离是不可能的。

  2. 如果您已经想出了 #1,我假设您问这个问题是希望有一些神奇的“黑客”可以完成工作。但是,文档指出,

    当用户在搜索对话框或小部件中执行搜索时, 系统启动您的可搜索活动并将其传递给搜索 使用 ACTION_SEARCH 操作在 Intent 中查询。您的可搜索 活动从意图的 QUERY extra 中检索查询,然后 搜索您的数据并显示结果。

    负责提供搜索结果的底层内部系统需要Activity,而不是Fragment;因此,实现完全独立于Activity 的搜索界面是不可能的,因为它需要更改底层系统本身。如果您不相信我,请查看SearchableInfo 类的源代码:)。

话虽如此,实现与您所描述的类似的东西似乎并不难。例如,您可能会考虑实现您的可搜索活动,以便它接受android.intent.action.SEARCH 意图并且(而不是立即在ListView 中显示结果)将搜索查询传递给您的Fragments。例如,考虑以下可搜索的 Activity:

public class SearchableActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (Intent.ACTION_SEARCH.equals(getIntent().getAction())) {
          String query = intent.getStringExtra(SearchManager.QUERY);
          doMySearch(query);
        }
    }

    /**
     * Performs a search and passes the results to the container
     * Activity that holds your Fragments.
     */
    public void doMySearch(String query) {
        // TODO: implement this
    }
}

当发出搜索请求时,系统将启动您的可搜索 Activity,执行查询,并将结果传递给某个容器 Activity(基于您对 doMySearch 的实现)。然后,容器 Activity 会将这些结果传递给包含的可搜索 Fragment,其中将显示结果。该实现需要比您可能希望的更多的工作,但我确信您可以通过一些方法使其更加模块化,而且这似乎是您能做的最好的。

附言如果您使用这种方法,您可能需要特别注意哪些 Activity 被添加/删除到 backstack。请参阅此post,了解有关如何完成此操作的更多信息。

p.p.s.您可能还完全忘记了标准搜索界面,而只是在 Fragment 中实现一个简单的搜索,如 Raghav's post below 中所述。

【讨论】:

  • @Alex,使用 Fragment 实现标准的 Android 搜索界面绝对是可能的。但这需要做很多工作...... :-)
  • @VinaySShenoy 是的,我的意思是你必须为Fragments 重新实现整个SearchManager 对吗? (或类似的东西)
  • 为了提供搜索结果,我已经实现了与您建议的类似的东西,将意图传递给 Activity,如果它是可见的,它将传递给正确的片段。最困难的部分是使用正确的数据重新填充片段加载的建议表,以让我处理显示建议以及处理搜索提交和单击建议。但是我现在已经为未来的应用程序准备了一个很好的框架.. :-)
  • 我发现这是一个更好的答案:stackoverflow.com/questions/6938952/… 这将允许从片段中“搜索”。诚然,这不是谷歌提供的官方搜索机制,但它工作得很好。
【解决方案2】:

这是使用片段搜索内容的示例。希望它有所帮助,这就是您正在寻找的:

public class LoaderCursor extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        FragmentManager fm = getFragmentManager();

        // Create the list fragment and add it as our sole content.
        if (fm.findFragmentById(android.R.id.content) == null) {
            CursorLoaderListFragment list = new CursorLoaderListFragment();
            fm.beginTransaction().add(android.R.id.content, list).commit();
        }
    }

    public static class CursorLoaderListFragment extends ListFragment
            implements OnQueryTextListener, LoaderManager.LoaderCallbacks<Cursor> {

        // This is the Adapter being used to display the list's data.
        SimpleCursorAdapter mAdapter;

        // If non-null, this is the current filter the user has provided.
        String mCurFilter;

        @Override public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);

            // Give some text to display if there is no data.  In a real
            // application this would come from a resource.
            setEmptyText("No phone numbers");

            // We have a menu item to show in action bar.
            setHasOptionsMenu(true);

            // Create an empty adapter we will use to display the loaded data.
            mAdapter = new SimpleCursorAdapter(getActivity(),
                    android.R.layout.simple_list_item_2, null,
                    new String[] { Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS },
                    new int[] { android.R.id.text1, android.R.id.text2 }, 0);
            setListAdapter(mAdapter);

            // Start out with a progress indicator.
            setListShown(false);

            // Prepare the loader.  Either re-connect with an existing one,
            // or start a new one.
            getLoaderManager().initLoader(0, null, this);
        }

        @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
            // Place an action bar item for searching.
            MenuItem item = menu.add("Search");
            item.setIcon(android.R.drawable.ic_menu_search);
            item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
            SearchView sv = new SearchView(getActivity());
            sv.setOnQueryTextListener(this);
            item.setActionView(sv);
        }

        public boolean onQueryTextChange(String newText) {
            // Called when the action bar search text has changed.  Update
            // the search filter, and restart the loader to do a new query
            // with this filter.
            mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;
            getLoaderManager().restartLoader(0, null, this);
            return true;
        }

        @Override public boolean onQueryTextSubmit(String query) {
            // Don't care about this.
            return true;
        }

        @Override public void onListItemClick(ListView l, View v, int position, long id) {
            // Insert desired behavior here.
            Log.i("FragmentComplexList", "Item clicked: " + id);
        }

        // These are the Contacts rows that we will retrieve.
        static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] {
            Contacts._ID,
            Contacts.DISPLAY_NAME,
            Contacts.CONTACT_STATUS,
            Contacts.CONTACT_PRESENCE,
            Contacts.PHOTO_ID,
            Contacts.LOOKUP_KEY,
        };

        public Loader<Cursor> onCreateLoader(int id, Bundle args) {
            // This is called when a new Loader needs to be created.  This
            // sample only has one Loader, so we don't care about the ID.
            // First, pick the base URI to use depending on whether we are
            // currently filtering.
            Uri baseUri;
            if (mCurFilter != null) {
                baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
                        Uri.encode(mCurFilter));
            } else {
                baseUri = Contacts.CONTENT_URI;
            }

            // Now create and return a CursorLoader that will take care of
            // creating a Cursor for the data being displayed.
            String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND ("
                    + Contacts.HAS_PHONE_NUMBER + "=1) AND ("
                    + Contacts.DISPLAY_NAME + " != '' ))";
            return new CursorLoader(getActivity(), baseUri,
                    CONTACTS_SUMMARY_PROJECTION, select, null,
                    Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
        }

        public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
            // Swap the new cursor in.  (The framework will take care of closing the
            // old cursor once we return.)
            mAdapter.swapCursor(data);

            // The list should now be shown.
            if (isResumed()) {
                setListShown(true);
            } else {
                setListShownNoAnimation(true);
            }
        }

        public void onLoaderReset(Loader<Cursor> loader) {
            // This is called when the last Cursor provided to onLoadFinished()
            // above is about to be closed.  We need to make sure we are no
            // longer using it.
            mAdapter.swapCursor(null);
        }
    }
}

【讨论】:

  • OP 要求提供“标准搜索界面”,但这确实在Fragment 中实现了简单的“搜索”,所以我不会抱怨。恭喜! :P
  • 下次你可能想cite your sources
  • 参见开发者网站上的creating a search interface。 OP 询问是否可以创建一个“可搜索片段”,该片段可与文档中描述的标准 Android 搜索一起使用。
  • 一些陷阱: 1-使用自定义搜索图标不起作用。 2-SearchView 需要有一些管理代码,比如禁用内容,处理返回等。
  • 在我的情况下,onQueryTextChange 方法没有被调用。
【解决方案3】:

使用标准的 ActionBar SearchView ActionView API 在片段中进行搜索是完全可能的。这也可以使用 AppCompat 支持类 v7 回到 Android 2.1(API 级别 7)。

在您的片段中:

@Override
public void onCreateOptionsMenu (Menu menu, MenuInflater inflater){
    inflater.inflate(R.menu.search, menu);
    MenuItem item = menu.findItem(R.id.action_search);
    SearchView sv = new SearchView(((YourActivity) getActivity()).getSupportActionBar().getThemedContext());
    MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
    MenuItemCompat.setActionView(item, sv);
    sv.setOnQueryTextListener(new OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            System.out.println("search query submit");
            return false;
        }

        @Override
        public boolean onQueryTextChange(String newText) {
            System.out.println("tap");
            return false;
        }
    });
}

在您的菜单 XML 中

<item
    android:id="@+id/action_search"
    android:icon="@drawable/ic_action_search"
    android:title="Search Waste Items"
    android:showAsAction="ifRoom|collapseActionView"
    nz.govt.app:actionViewClass="android.support.v7.widget.SearchView"
    nz.govt.app:showAsAction="ifRoom|collapseActionView" />

【讨论】:

  • 这适用于新的 ActionBarActivity appcompat v7,谢谢
  • 阅读接受的答案,我失去了希望..其他答案很复杂,我阅读了你的答案!!!很简单!就是这样......非常感谢你
  • 我认为我们必须在 onActivityCreated 中添加 setHasOptionsMenu(true)。正如@MBH 所发现的那样。
  • @GowthamanM 只需使用 MenuItem.SHOW_AS_ACTION....
  • 嘿@GowthamanM,像这样使用:item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | MenuItem.SHOW_AS_ACTION_IF_ROOM); item.setActionView(searchView);
【解决方案4】:

使用 AppCompat 支持类 v7。只需从 @Rookie 解决方案中向 @David 的解决方案添加一些内容,以使其以简单的方式正常工作,这是我的片段代码:

我的片段

public class MyFragment extends Fragment implements SearchView.OnQueryTextListener {

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        // What i have added is this
        setHasOptionsMenu(true);
    }

    @Override
    public void onCreateOptionsMenu (Menu menu, MenuInflater inflater) {

        //inflater.inflate(R.menu.main, menu); // removed to not double the menu items
        MenuItem item = menu.findItem(R.id.action_search);
        SearchView sv = new SearchView(((MainActivity) getActivity()).getSupportActionBar().getThemedContext());
        MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
        MenuItemCompat.setActionView(item, sv);
        sv.setOnQueryTextListener(this);
        sv.setIconifiedByDefault(false);
        sv.setOnSearchClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Utils.LogDebug("Clicked: ");
            }
        });

        MenuItemCompat.setOnActionExpandListener(item, new MenuItemCompat.OnActionExpandListener() {
            @Override
            public boolean onMenuItemActionCollapse(MenuItem item) {
                // Do something when collapsed
                Utils.LogDebug("Closed: ");
                return true;  // Return true to collapse action view
            }

            @Override
            public boolean onMenuItemActionExpand(MenuItem item) {
                // Do something when expanded
                Utils.LogDebug("Openeed: ");
                return true;  // Return true to expand action view
            }
        });

        super.onCreateOptionsMenu(menu,inflater);
    }

    @Override
    public boolean onQueryTextSubmit(String query) {
        Utils.LogDebug("Submitted: "+query);
        return true;
    }

    @Override
    public boolean onQueryTextChange(String newText) {
        Utils.LogDebug("Changed: "+newText);
        return false;
    }
}

我添加了onActivityCreated,因为不调用setHasOptionsMenu(true);系统不会知道这个片段需要与菜单交互。

然后我删除了 inflater.inflate(R.menu.main, menu); 行,因为它使菜单项增加了一倍,因为 Activity 膨胀了一个菜单,然后 Fragment 膨胀了另一个菜单

感谢@David 和@Rookie

【讨论】:

    【解决方案5】:

    使用Fragments 时,您仍然需要使用Activity 来控制和分配Fragments。 这个Activity 可以像以前一样拥有搜索功能。

    我最近从基于 Activity 的“普通”应用切换到基于 Fragment 的应用,搜索功能对我来说也一样。

    你有没有尝试过,但没有成功?如果是这样,请在您的问题中提供更多详细信息。

    编辑:

    如果您想进行特定于片段的搜索,请让您的所有Fragments 使用startSearch 方法扩展接口startSearch,并让您的ActivitystartSearch 方法调用当前片段的@987654332 @方法。

    【讨论】:

    • 要求是android搜索绑定到特定的片段,而不是活动。所以,不,我没有尝试过。
    • 我还没有尝试过,但这听起来正是我想要的。我有一个带有片段的导航抽屉,每个片段都包含不相关的搜索功能。我不想完全绕过安卓搜索系统,所以我需要这样的东西。
    【解决方案6】:

    我想我做到了:您实际上可以使用片段并将搜索图标添加到操作栏,以便可以在片段内进行搜索。诀窍是使用操作栏、操作视图、监听器、加载器和适配器。

    虽然它完全绕过了 android 平台搜索机制,但它工作得很好(但它可以通过一些工作来完成,以找到 @Alex Lockwood 描述的内容并将搜索传递给片段)。在活动的情况下,它不会像预期的那样对意图做出反应,但它可以工作:用户可以在片段内部搜索。

    代码如下:

    SearchInFragmentActivity

    package com.sof.test.searchfragment;
    
    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentTransaction;
    import android.view.View;
    
    import com.actionbarsherlock.app.ActionBar;
    import com.actionbarsherlock.app.ActionBar.Tab;
    import com.actionbarsherlock.app.ActionBar.TabListener;
    import com.actionbarsherlock.app.SherlockFragmentActivity;
    import com.sof.test.searchfragment.SearchFragment;
    import com.sof.test.R;
    
    
    public class SearchInFragmentActivity extends SherlockFragmentActivity implements TabListener {
    
        private SearchFragment tab1 = new SearchFragment();
        private SearchFragment tab2 = new SearchFragment();
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView( R.layout.search_in_fragments );
    
            getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
            createTab( R.string.tab1, R.drawable.ic_menu_search );
            createTab( R.string.tab2, R.drawable.ic_menu_search );
            getSupportActionBar().setSelectedNavigationItem( 0 );
            invalidateOptionsMenu();
        }
    
        private void createTab(int tabNameResId, int tabIconResId) {
            ActionBar.Tab tab = getSupportActionBar().newTab();
            tab.setText( tabNameResId );
            tab.setTabListener(this);
            getSupportActionBar().addTab(tab);
        }// met
    
        @Override
        public void onTabSelected(Tab tab, FragmentTransaction ft) {
            if( ft == null ) {
                return;
            }//if
            View fragmentSlot = findViewById( R.id.fragment );
            Fragment newFragment = null;
            if( fragmentSlot != null ) {
                newFragment = (tab.getPosition() == 0) ? tab1 : tab2;
                ft.replace(R.id.fragment, newFragment );
                ft.setTransition( FragmentTransaction.TRANSIT_FRAGMENT_FADE);
            }//if
        }
    
        @Override
        public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        }
    
        @Override
        public void onTabReselected(Tab tab, FragmentTransaction ft) {
        }
    
    }//class
    

    片段类 SearchFragment(我在上面的活动中使用了 2 个实例)。

    package com.sof.test.searchfragment;
    
    
    import java.util.ArrayList;
    import java.util.List;
    
    import android.content.Context;
    import android.os.Bundle;
    import android.support.v4.app.LoaderManager.LoaderCallbacks;
    import android.support.v4.content.AsyncTaskLoader;
    import android.support.v4.content.Loader;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ArrayAdapter;
    import android.widget.SearchView;
    import android.widget.TextView;
    
    import com.sof.test.R;
    import com.actionbarsherlock.app.SherlockListFragment;
    import com.actionbarsherlock.view.Menu;
    import com.actionbarsherlock.view.MenuInflater;
    
    public class SearchFragment extends SherlockListFragment {
    
        private StringLoader loader = null;
        private StringAdapter adapter = null;
        private List<String> listData = new ArrayList<String>();
        private String query;
    
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View view = super.onCreateView(inflater, container, savedInstanceState);
            createListData();
    
            loader = new StringLoader( getActivity(), this );
            adapter = new StringAdapter(listData);
            setListAdapter(adapter);
    
            getLoaderManager().initLoader(0, null,  new LoaderCallBacks() );
            loader.forceLoad();
            setHasOptionsMenu( true );
            return view;
        }
    
        @Override
        public void onCreateOptionsMenu(Menu menu, MenuInflater inflater ) {
            super.onCreateOptionsMenu(menu, inflater);
            inflater.inflate( R.menu.menu_search, menu);
            System.out.println( "inflating menu");
    
            final SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
            final SearchView.OnQueryTextListener queryTextListener = new SearchView.OnQueryTextListener() {
                @Override
                public boolean onQueryTextChange(String newText) {
                    showFilteredItems( newText );
                    return true;
                }
    
                @Override
                public boolean onQueryTextSubmit(String query) {
                    return true;
                }
            };
    
            searchView.setOnQueryTextListener(queryTextListener);
    
            return;
        }//met
    
        private void showFilteredItems( String query ) {
            this.query = query;
            loader.onContentChanged();
        }
    
        private void createListData() {
            for( int i = 0; i < 100 ; i ++ ) {
              listData.add( "String "+ i ); 
            }
        }
    
        public List<String> getData() {
            List<String> listFilteredData = new ArrayList<String>();
            for( String string : listData ) {
                if( query == null || string.contains( query ) ) {
                    listFilteredData.add( string );
                }
            }
            return listFilteredData;
        }//met
    
        private class LoaderCallBacks implements LoaderCallbacks< List<String>> {
            @Override
            public void onLoadFinished(Loader<List<String>> loader,
                    List<String> listData) {
                adapter.setListData( listData );
            }// met
    
            @Override
            public void onLoaderReset(Loader<List<String>> listData) {
                adapter.setListData( new ArrayList<String>() );
            }// met
    
            @Override
            public Loader<List<String>> onCreateLoader(int arg0,
                    Bundle arg1) {
                return loader;
            }// met
        }//class
    
        private class StringAdapter extends ArrayAdapter< String > {
    
            private List<String> listDataToDisplay = new ArrayList<String>();
            private LayoutInflater mInflater;
    
            public StringAdapter( List<String> listData ) {
                super( getActivity(), android.R.layout.simple_list_item_1, android.R.id.text1, listData );
                listDataToDisplay = listData;
                mInflater = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            }//cons
    
            private void setListData( List<String> newListData ) {
                this.listDataToDisplay.clear();
                this.listDataToDisplay.addAll( newListData );
                notifyDataSetChanged();
            }//met
    
              /**
             * Populate new items in the list.
             */
            @Override public View getView(int position, View convertView, ViewGroup parent) {
                View view;
    
                if (convertView == null) {
                    view = mInflater.inflate(android.R.layout.simple_list_item_1, parent, false);
                } else {
                    view = convertView;
                }
    
                ((TextView)view.findViewById( android.R.id.text1)).setText( listDataToDisplay.get( position ) );
    
                return view;
            }
        }//inner class
    }//class
    
    class StringLoader extends AsyncTaskLoader<List<String>> {
    
        SearchFragment fragment = null;
    
        public StringLoader(Context context, SearchFragment fragment) {
            super(context);
            this.fragment = fragment;
        }// cons
    
        @Override
        public List<String> loadInBackground() {
            return fragment.getData();
        }// met
    }// class
    

    搜索片段菜单的xml文件res/menu/menu_search.xml:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:baselineAligned="false"
        android:orientation="horizontal" >
        <FrameLayout
            android:id="@+id/fragment"
            android:layout_width="0px"
            android:layout_height="match_parent"
            android:layout_weight="1" />
    </LinearLayout>
    

    还有xml布局文件res/layout/search_in_fragments.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:baselineAligned="false"
        android:orientation="horizontal" >
        <FrameLayout
            android:id="@+id/fragment"
            android:layout_width="0px"
            android:layout_height="match_parent"
            android:layout_weight="1" />
    </LinearLayout>
    

    【讨论】:

    • 我还想指出,Jake Wharton 决定不为他的 ActionBarSherlock 库实现 SearchView,因为它很复杂 (see his comment here)。正如你所看到的(正如我在回答中所描述的那样),Android 的搜索实现绝不是微不足道的......它在底层系统中根深蒂固,这使得即使是 3rd 方库也难以编写(这说明了一些事情。 .. Jake Wharton 就像是第三方图书馆的 Chuck Norris!:D).
    • 在这里查看SearchView.java源代码。
    • Alex,Jake Wharton 似乎改变了主意:twitter.com/JakeWharton/status/221169921235755009
    • 这两个xml文件一样吗?
    • @Clocker,看起来像。老实说,两年后我不能说
    【解决方案7】:

    使用ActionBarSearchView。您将能够处理搜索,而无需任何与 Activity 的连接。只需将 OnQueryTextListener 设置为 SearchView。

    MenuItem item = menu.add("Search");
    SearchView sv = new SearchView(getActionBar().getThemedContext());
    item.setActionView(sv);
    item.setIcon(R.drawable.ic_search);
    item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW
            | MenuItem.SHOW_AS_ACTION_IF_ROOM);
    sv.setOnQueryTextListener(new OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            //...
            return false;
        }
        @Override
        public boolean onQueryTextChange(String newText) {
            //...
            return false;
        }
    });
    

    有关自定义搜索的更多详细信息,请参阅this 帖子。

    【讨论】:

      【解决方案8】:

      其他解决方案.....我不喜欢那样。 这对我来说更容易。但这是我的想法。我正在等待你的意见

      public interface SearchImpl {
          public void searchQuery(String val);
      }
      

      片段

      public class MyFragment extends Fragment implements SearchImpl {
          View view;
      
          @Override
          public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                   Bundle savedInstanceState) {
              view = inflater.inflate(R.layout.fragment_almanca, container, false);
              return view;
          }
      
          @Override
          public void searchQuery(String val) {
              Log.e("getted", val);
          }
      }
      

      活动

       @Override
      public boolean onCreateOptionsMenu(Menu menu) {
      
          getMenuInflater().inflate(R.menu.main, menu);
      
          SearchView searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.action_search));
      
          searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
              @Override
              public boolean onQueryTextSubmit(String query) {
                  Log.e("setted", "" + query);
                  try {
                      MyFragment myFGM=new MyFragment();
                      myFGM.searchQuery(query);
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
                  return false;
              }
      
              @Override
              public boolean onQueryTextChange(String newText) {
                  return false;
              }
          });
          return super.onCreateOptionsMenu(menu);
      }
      

      【讨论】:

        【解决方案9】:

        Fragment 不能存在于 Activity 之外,Fragment 也不能链接到 android.intent.action.SEARCH 或任何其他 intent-filter

        因此,如果不使用Activity 来包装Fragment,您的要求是不可能的。

        【讨论】:

          【解决方案10】:

          如果 Fragments 进入 ViewPager,当我不在想要提供搜索栏的片段上时,我可以通过阻止搜索按钮来做到这一点。进入活动:

          @Override
          public boolean onSearchRequested() {
          
              if (mPager.getCurrentItem() == mAdapter.getPosition(FragmentType.VIDEO))
                  return super.onSearchRequested();
              else
                  return false;
          }
          

          并且在没有物理搜索按钮的情况下,我在片段中添加了一个操作项,这会触发以下代码:

          @Override
          public boolean onOptionsItemSelected(MenuItem item) {
          
              if (item.getItemId() == R.id.search_item) {
          
                  return getSherlockActivity().onSearchRequested();
              }
              return super.onOptionsItemSelected(item);
          }
          

          【讨论】:

            【解决方案11】:

            我找到了解决方法:) 您可以在 BaseActivity 中覆盖此方法(startActivity(Intent)),然后检查该操作是否为 ACTION_SEARCH,然后执行您的特殊工作:D

            @Override
                public void startActivity(Intent intent) {
                    try {
                        if (intent.getAction().equals(Intent.ACTION_SEARCH))
                            toast("hello");
                    } catch (Exception e) {
            
                    }
                }
            

            【讨论】:

              【解决方案12】:

              是的,有可能,

              请在您的 Activity 上实现搜索视图,Activity 中的“onQueryTextChange”也会监听片段中的搜索,您可以在“onQueryTextChange”中检查片段可见性,如果可见,您可以调用片段的搜索方法,它的工作完美在我的代码中

              【讨论】:

                猜你喜欢
                • 2014-10-23
                • 1970-01-01
                • 2011-07-07
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多