Поиск Android с помощью фрагментов

Кто-нибудь знает учебник или пример того, как реализовать стандартный интерфейс поиска Android с Fragments ? Другими словами, можно ли поместить во фрагмент стандартный поиск с SearchManager?


person Blackbelt    schedule 29.08.2011    source источник
comment
Кому вы дадите бонус для @blackbelt? Рагхав дал ответ, который я искал. но Alex LockWood также ответил на первую часть вашего вопроса.   -  person Snicolas    schedule 07.05.2012
comment
Я принимаю ответ LockWood. Награждайте награду, как хотите (я думаю, что лучше)   -  person Blackbelt    schedule 07.05.2012
comment
Я рад, что мы получили такое множество правильных ответов и обходных путей! :)   -  person Alex Lockwood    schedule 07.05.2012
comment
Кто-нибудь может дать мне ответ на этот вопрос ..? Я застрял здесь, stackoverflow.com/questions/ 10600660 /   -  person Rookie    schedule 28.05.2012
comment
Я использую этот метод, чтобы оставаться внутри фрагмента после добавления SearchView на панель действий: stackoverflow.com/a/6939735/1068167. Мое приложение еще не готово, но, надеюсь, оно будет работать.   -  person span    schedule 10.08.2012
comment
Я успешно реализовал поиск по фрагментам с помощью интерфейса поиска Android (SearchView в панели действий) с настраиваемыми предложениями и отображением результатов. Каждый фрагмент динамически загружает свои собственные предложения из сети (кешируется в локальную БД). Потребовалось много работы, но работает очень хорошо. Добавьте комментарий, если хотите, чтобы я ответил, потому что это потребует много объяснений .. :-)   -  person Vinay S Shenoy    schedule 01.01.2013
comment
вперед, продолжать. может быть полезно другим людям. Благодарность   -  person Blackbelt    schedule 01.01.2013


Ответы (12)


Короче, нельзя. Существует несколько причин, по которым создание интерфейса поиска в Fragment невозможно.

  1. При создании интерфейса с возможностью поиска вы должны указать "действие с возможностью поиска" по умолчанию в манифесте Android. Как я уверен, вы знаете, Fragment не может существовать без родителя Activity, и поэтому такое разделение невозможно.

  2. # P3 #
    # P4 #
    # P5 #

При этом не похоже, что было бы слишком сложно достичь чего-то похожего на то, что вы описываете. Например, вы можете подумать о реализации своей активности с возможностью поиска, чтобы она принимала намерение android.intent.action.SEARCH и (например, вместо того, чтобы сразу отображать результаты в ListView) передавала поисковый запрос вашим Fragments. Например, рассмотрим следующее действие с возможностью поиска:

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

Когда выполняется поисковый запрос, система запускает ваше действие с возможностью поиска, выполняет запрос и передает результаты некоторому действию контейнера (в зависимости от вашей реализации doMySearch). Контейнер Activity затем передаст эти результаты в содержащий доступный для поиска Fragment, в котором результаты будут отображены. Реализация требует немного больше работы, чем вы, вероятно, надеялись, но я уверен, что есть способы сделать ее более модульной, и, похоже, это лучшее, что вы можете сделать.

p.s. Если вы используете этот подход, вам, возможно, придется обратить особое внимание на то, какие действия добавляются / удаляются в backstack. См. Это сообщение для получения дополнительной информации о том, как это можно сделать.

p.p.s. Вы также можете полностью забыть о стандартном интерфейсе поиска и просто реализовать простой поиск в Fragment, как описано в сообщении Рагхава ниже .

person Alex Lockwood    schedule 03.05.2012
comment
@Alex, Реализовать стандартный интерфейс поиска Android по фрагментам однозначно можно. Но это требует ОЧЕНЬ много работы ... :-) - person Vinay S Shenoy; 01.01.2013
comment
@VinaySShenoy да, я имею в виду, что вам придется заново реализовать SearchManager для Fragments, верно? (или что-то подобное) - person Alex Lockwood; 01.01.2013
comment
Для доставки результатов поиска я реализовал нечто похожее на то, что вы предложили, доставляя намерение в действие, которое доставляет его в нужный фрагмент, если он виден. Самым сложным было повторное заполнение таблицы предложений при загрузке фрагмента правильными данными, чтобы я мог обрабатывать отображение предложений, а также обрабатывать отправку результатов поиска и нажатие на предложения. Но теперь у меня есть хорошая структура для будущих приложений .. :-) - person Vinay S Shenoy; 02.01.2013
comment
Я нашел, что это лучший ответ: stackoverflow.com/questions/6938952/ Это позволит выполнять поиск из фрагментов. Правда, это не официальный механизм поиска, предоставляемый Google, но он работает нормально. - person Kyle Falconer; 05.08.2013

Вот пример поиска по фрагментам. Надеюсь, это поможет, и это то, что вы ищете:

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);
        }
    }
}
person Rookie    schedule 07.05.2012
comment
OP запросил стандартный интерфейс поиска, но это обеспечивает простой поиск в Fragment, так что я бы не стал жаловаться. Поздравляю! :П - person Alex Lockwood; 07.05.2012
comment
В следующий раз вы, возможно, захотите процитировать свои источники . - person Adrian Monk; 07.05.2012
comment
См. создание интерфейса поиска. на сайте разработчика. OP спросил, можно ли создать доступный для поиска фрагмент, который работает со стандартным поиском Android, как описано в документации. - person Alex Lockwood; 07.05.2012
comment
Некоторые подводные камни: 1-Использование настраиваемого значка поиска не работает. 2-SearchView должен иметь некоторый управляющий код, например, для отключения контента, обратной обработки и т. Д. - person AlikElzin-kilaka; 02.05.2013
comment
В моем случае метод onQueryTextChange не вызывается. - person Shajeel Afzal; 06.08.2015

Поиск по фрагменту вполне возможен с помощью стандартного ActionBar SearchView ActionView API. Это также будет работать в Android 2.1 (уровень API 7) с использованием классов поддержки AppCompat v7.

В вашем фрагменте:

@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" />
person David    schedule 20.03.2014
comment
Это отлично работает с новым приложением ActionBarActivity v7, спасибо - person Pelanes; 09.04.2014
comment
Вам понадобится менеджер поиска? - person ImAtWar; 18.02.2015
comment
прочитав принятый ответ, я потерял надежду .. другие ответы сложны, я прочитал ваш ответ !!! Так просто! вот оно ... большое вам спасибо - person MBH; 02.09.2015
comment
это хорошо работает, спасибо! Есть ли у вас какие-либо советы по реализации недавних предложений запросов? - person hornet2319; 06.10.2015
comment
Я думаю, нам нужно добавить setHasOptionsMenu (true) в onActivityCreated. Как заметил @MBH. - person Raymond Lukanta; 11.01.2016
comment
@RaymondLukanta прав, но я добавил setHasOptionsMenu (true) в метод onCreate фрагмента. - person MorZa; 12.01.2016
comment
Я единственный, кто получает удвоенный результат от onQuertTextSubmit? - person deadfish; 05.02.2016
comment
Это все еще зависит от Activity. Вы должны установить theme, который поддерживает ActionBar на нем. - person klimat; 01.06.2016
comment
MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | MenuItemCompat.SHOW_AS_ACTION_IF_ROOM); MenuItemCompat.setActionView(item, sv); это строки устарели, пожалуйста, помогите мне в этом случае, братан - person Gowthaman M; 04.11.2017
comment
@GowthamanM Просто используйте MenuItem.SHOW_AS_ACTION .... если вы можете, AppCompat устарел в более поздних API - person David; 08.02.2018
comment
Привет, @GowthamanM, используйте вот так: item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | MenuItem.SHOW_AS_ACTION_IF_ROOM); item.setActionView(searchView); - person Rod Lima; 14.12.2018

Использование классов поддержки AppCompat v7. Просто добавьте что-то в решение @David из решения @Rookie, чтобы оно работало правильно и простым способом, вот мой код фрагмента:

MyFragment:

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

person MBH    schedule 02.09.2015

При работе с Fragments вам все равно нужно использовать Activity для управления и назначения Fragments. Этот Activity может иметь функцию поиска, как и раньше.

Недавно я перешел с «обычного» приложения на основе Activity на приложение на основе Fragment, и функции поиска у меня работали точно так же.

Вы пытались над этим поработать, и у вас ничего не вышло? Если да, опишите подробнее в своем вопросе.

РЕДАКТИРОВАТЬ:

Если вы хотите выполнить поиск по конкретному фрагменту, пусть все ваши Fragments расширяют интерфейс MyFragment с помощью startSearch метода, а метод Activity startSearch вызывает метод startSearch текущего фрагмента.

person marmor    schedule 03.05.2012
comment
Требование заключалось в том, чтобы поиск андроида был ограничен конкретным фрагментом, а не активностью. Итак, нет, я не пробовал. - person Blackbelt; 03.05.2012
comment
Я еще не пробовал, но это ТОЧНО похоже на то, что я ищу. У меня есть панель навигации с фрагментами, каждый из которых содержит несвязанные функции поиска. Я не хочу полностью обходить поисковую систему Android, поэтому мне понадобилось что-то вроде этого. - person Bassinator; 01.12.2017

Я думаю, что добился этого: вы действительно можете использовать фрагменты и добавить значок поиска на панель действий, чтобы поиск был возможен внутри фрагментов. Уловка состоит в том, чтобы использовать панель действий, представление действий, прослушиватель для них, загрузчик и, конечно же, адаптер.

Это работает довольно хорошо, хотя полностью обходит механизм поиска на платформе 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>
person Snicolas    schedule 07.05.2012
comment
Я также хотел бы отметить, что Джейк Уортон решил не реализовывать SearchView для своей библиотеки ActionBarSherlock из-за ее сложности ( см. его комментарий здесь). Как видите (и как я также описал в своем ответе), реализация поиска в Android совсем не тривиальна ... она укоренилась в базовой системе, и это затрудняет написание даже сторонних библиотек (и это о чем-то говорит. .. Джейк Уортон похож на Чака Норриса из сторонних библиотек!: D). - person Alex Lockwood; 07.05.2012
comment
Взгляните на _ 1_ исходный код здесь. - person Alex Lockwood; 07.05.2012
comment
Алекс, похоже, Джейк Уортон передумал: twitter.com/JakeWharton/status/221169921235755009 - person Jose_GD; 07.07.2012
comment
Оба эти XML-файла одинаковы? - person Clocker; 06.08.2014
comment
@Clocker, похоже, они есть. Честно говоря, через 2 года не могу сказать - person Snicolas; 06.08.2014

Используйте ActionBar и SearchView. Вы сможете выполнять поиск без подключения к 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;
    }
});

Дополнительные сведения о пользовательском поиске см. В этом сообщении.

person AlikElzin-kilaka    schedule 07.05.2013

другие решения ..... мне это не нравится. Для меня это проще. Но это моя идея. Жду твоего мнения.

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);
}
person Numan Turkeri    schedule 22.06.2016

Fragment не может существовать вне Activity, а Fragment не может быть связан с android.intent.action.SEARCH или любым другим intent-filter.

Таким образом, без использования Activity для обертывания Fragment то, о чем вы просите, невозможно.

person Louth    schedule 03.05.2012

В случае фрагментов в 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);
}
person galex    schedule 07.05.2012

Я нашел работу :) вы можете переопределить этот метод (startActivity (Intent)) в своей BaseActivity, а затем проверить, является ли действие ACTION_SEARCH, а затем выполнить свою особую работу: D

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

        }
    }
person S. Alawadi    schedule 12.12.2016

да это возможно,

пожалуйста, реализует представление поиска в вашей деятельности, onQueryTextChange в Activity также будет прослушивать поиск во фрагменте, вы можете проверить видимость фрагмента в onQueryTextChange, если он виден, вы можете вызвать свой метод поиска для фрагмента, он отлично работает в моем коде

person Libin Thomas    schedule 28.01.2016