조각으로 Android 검색


161

튜토리얼 또는 표준 구현하는 방법에 대한 예제의 누군가 알고합니까 안드로이드 검색 인터페이스Fragment들? 다시 말해, SearchManagerFragment에 표준 검색을 넣을 수 있습니까?


@blackbelt에게 보너스를 부여 할 사람은 누구입니까? 그러나 Alex LockWood도 귀하의 질문의 첫 번째 부분에 답변했습니다.
Snicolas

LockWood의 답변을 수락합니다. 원하는대로 현상금을 수여하십시오 (더 나은 것 같습니다)
Blackbelt

4
다양한 정답과 해결 방법을 얻게되어 기쁩니다. :)
Alex Lockwood

누구든지이 질문에 대한 답을 줄 수 있습니까? 나는 여기에 붙어있다. stackoverflow.com/questions/10600660/…
Rookie

1
이 기술을 사용하여 SearchView를 작업 표시 줄에 추가 한 후 단편 내에 머물러 있습니다 : stackoverflow.com/a/6939735/1068167 . 내 신청은 아직 완료되지 않았지만 잘 작동 할 것입니다.
스팬

답변:


91

요컨대, 당신은 할 수 없습니다. 에 검색 인터페이스를 만들 수없는 데는 몇 가지 이유 Fragment가 있습니다.

  1. 검색 가능한 인터페이스를 만들 때 Android 매니페스트에 기본 "검색 가능한 활동"을 지정해야합니다. 아시다시피 Fragment부모 없이는 존재할 수 Activity없으므로이 분리는 불가능합니다.

  2. 이미 # 1을 이미 알고 있다면 작업을 수행 할 수있는 마법의 "해킹"이 있기를 바랍니다. 그러나 설명서에는

    사용자가 검색 대화 상자 또는 위젯에서 검색을 실행하면 시스템은 검색 가능한 활동을 시작하고 ACTION_SEARCH 조치를 사용하여 검색 쿼리를 인 텐트로 전달합니다. 검색 가능한 활동은 의도의 QUERY Extra에서 쿼리를 검색 한 다음 데이터를 검색하고 결과를 제공합니다.

    검색 결과를 제공하는 기본 내부 시스템 ActivityFragment; 따라서 기본 시스템 자체를Activity 변경해야하므로 완전히 독립적 인 검색 인터페이스를 구현할 수 없습니다 . 나를 믿지 않으면 클래스 의 소스 코드를 확인하십시오 . :).SearchableInfo

말하자면, 당신이 묘사 한 것과 비슷한 것을 달성하기가 너무 어려워 보이지는 않습니다. 예를 들어, 검색 가능한 활동을 구현하여 android.intent.action.SEARCH의도 를 수용 하고 ( ListView예를 들어 결과를 즉시 표시하는 대신 ) 검색 쿼리를에 전달하도록 고려할 수 있습니다 Fragment. 예를 들어 다음과 같은 검색 가능한 활동을 고려하십시오.

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). 그런 다음 컨테이너 활동은 이러한 결과를 포함 된 검색 가능에 전달하여 결과를 Fragment표시합니다. 구현에는 기대했던 것보다 약간 더 많은 작업이 필요하지만 더 모듈화 할 수있는 방법이 있다고 확신하며 이것이 최선의 방법 인 것처럼 보입니다.

ps이 접근법을 사용하는 경우 활동이 백 스택에 추가 / 제거되는 것에 특별한주의를 기울여야 할 수도 있습니다. 이 작업을 수행하는 방법에 대한 자세한 내용 은이 게시물 을 참조하십시오 .

pps 또한 표준 검색 인터페이스를 완전히 잊어 버릴 수 있으며 아래 Raghav의 게시물에Fragment 설명 된대로 간단한 검색을 구현할 수도 있습니다 .


@Alex, 조각을 사용하여 표준 Android 검색 인터페이스를 구현할 수 있습니다. 그러나 많은 작업이 필요합니다 ... :-)
Vinay S Shenoy

그래 @VinaySShenoy, 난 당신이 전체 다시 구현해야 할 것이다 의미 SearchManager에 대한 Fragment권리들? (또는 이와 유사한 것)
Alex Lockwood

1
검색 결과를 제공하기 위해 제안한 것과 비슷한 것을 구현하여 활동에 의도를 전달하여 가시적 인 경우 올바른 조각으로 전달합니다. 가장 어려운 부분은 추천 데이터 표시와 조각 제출 및 제안 제출을 처리 할 수 ​​있도록 올바른 데이터가 포함 된 조각로드시 제안 표를 다시 채우는 것이 었습니다. 그러나 나는 지금 미래의 앱을위한 멋진 프레임 워크를 가지고있다 .. :-)
Vinay S Shenoy

나는 이것이 더 나은 대답이라는 것을 발견했다 : stackoverflow.com/questions/6938952/… 이것은 조각 내에서 "검색"을 허용합니다. 사실 Google에서 제공하는 공식 검색 메커니즘은 아니지만 제대로 작동합니다.
Kyle Falconer

76

다음은 조각을 사용하여 무언가를 검색하는 예입니다. 그것이 도움이되기를 희망하며 이것이 당신이 찾고있는 것입니다 :

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

30
다음에 당신 은 당신의 근원인용 하고 싶을 수도 있습니다 .
Adrian Monk

개발자 사이트에서 검색 인터페이스 작성을 참조하십시오 . OP는 문서에 설명 된대로 표준 Android 검색에서 작동하는 "검색 가능-조각"을 만들 수 있는지 물었습니다.
Alex Lockwood

몇 가지 함정 : 1- 맞춤형 검색 아이콘 사용이 작동하지 않습니다. 2-SearchView에는 콘텐츠 비활성화, 처리 등의 관리 코드가 있어야합니다.
AlikElzin-kilaka

내 경우에는 onQueryTextChange메소드가 호출되지 않습니다.
Shajeel Afzal

57

표준 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과 함께 잘 작동합니다.
Pelanes

1
허용 된 답변을 읽고, 나는 희망을 잃었습니다 .. 다른 답변은 복잡합니다, 나는 당신의 답변을 읽었습니다 !!! 너무 간단합니다! 그것을 먹으 렴 ... 정말 감사합니다
MBH

2
onActivityCreated에 setHasOptionsMenu (true)를 추가해야한다고 생각합니다. @MBH에 의해 발견되었습니다.
Raymond Lukanta

2
@GowthamanM MenuItem.SHOW_AS_ACTION ...을 사용하면 나중에 API에서 AppCompat가 더 이상 사용되지 않습니다.
David

1
안녕하세요 @GowthamanM, 다음과 같이 사용하십시오 : item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | MenuItem.SHOW_AS_ACTION_IF_ROOM); item.setActionView(searchView);
Rod Lima

15

AppCompat 지원 클래스 v7 사용 그냥 뭔가 추가 @ 데이비드 에서의 솔루션을 @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을 호출하지 않고 cuz를 추가하면 setHasOptionsMenu(true);이 조각이 메뉴와 상호 작용해야한다는 것을 알 수 없습니다.

그런 다음 inflater.inflate(R.menu.main, menu);Activity가 메뉴를 팽창시킨 후 Fragment가 다른 메뉴를 팽창시킨 후 메뉴 항목을 두 배로 늘렸으므로 줄을 제거했습니다

@David와 @Rookie 덕분에


7

작업 할 때 Fragments여전히을 사용 Activity하여을 제어하고 할당해야합니다 Fragments. 이것은 Activity이전과 검색 기능을 가질 수 있습니다.

최근에 '일반' Activity기반 앱에서Fragment 했으며 검색 기능이 나에게도 똑같이 작동했습니다.

그 일을 시도했지만 성공하지 못했습니까? 그렇다면 귀하의 질문에 좀 더 자세히 설명하십시오.

편집하다:

프래그먼트 특정 검색을 원하면 모든 Fragments확장 메소드를 MyFragment사용하여 startSearch메소드를 확장하고 ActivitystartSearch메소드가 현재 프래그먼트의 startSearch메소드를 호출하게하십시오 .


요구 사항은 안드로이드 검색이 액티비티가 아닌 특정 조각에 바인딩되어 있어야한다는 것입니다. 그래서, 나는 그것을 시도하지 않았습니다.
Blackbelt

나는 그것을 아직 시도하지 않았지만 이것은 내가 찾고있는 것과 정확하게 들린다. 각각 관련없는 검색 기능을 포함하는 조각이있는 탐색 서랍이 있습니다. 안드로이드 검색 시스템을 완전히 우회하고 싶지 않기 때문에 이와 같은 것이 필요했습니다.
Bassinator

5

나는 그것을 달성했다고 생각합니다 : 실제로 조각을 사용하고 작업 표시 줄에 검색 아이콘을 추가하여 조각 내에서 검색 할 수 있습니다. 요령은 액션 바, 액션 뷰, 리스너, 로더 및 어댑터를 사용하는 것입니다.

이것은 안드로이드 플랫폼 검색 메커니즘을 완전히 우회하지만 잘 작동합니다 (그러나 @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

검색 조각 res / menu / menu_search.xml의 메뉴에 대한 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 SearchView은 복잡성으로 인해 ActionBarSherlock 라이브러리에 대해 구현하지 않기로 결정했습니다 ( 여기의 의견 참조 ). 보시다시피 (그리고 저의 대답에서도 설명했듯이) Android의 검색 구현은 사소한 것입니다 ... 기본 시스템에 뿌리 내리고있어 타사 라이브러리조차 작성하기가 어렵습니다 (그리고 무언가를 말하고 있습니다). .. Jake Wharton은 타사 라이브러리의 척 노리스와 같습니다! : D).
Alex Lockwood

SearchView.java여기 에서 소스 코드를 살펴보십시오 .
Alex Lockwood

2
Alex, Jake Wharton이 마음을 바꾼 것 같습니다 : twitter.com/JakeWharton/status/221169921235755009
Jose_GD

이 두 XML 파일이 동일합니까?
Clocker

@Clocker, 그들이있는 것처럼 보입니다. 솔직히, 2 년 후 말할 수 없다
Snicolas

5

ActionBar및을 사용하십시오 SearchView. 활동에 연결하지 않고도 검색을 처리 할 수 ​​있습니다. 를 OnQueryTextListenerSearchView로 설정 하십시오.

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

사용자 정의 검색에 대한 자세한 내용 은 게시물을 참조하십시오.


3

다른 솔루션 ..... 난 싫어요. 이게 더 편해지지만 내 생각은 너의 의견을 기다리고있어

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

1

A는 Fragment외부 존재할 수 Activity없으며, 캔 FragmentA를 연결할 수 android.intent.action.SEARCH또는 기타 intent-filter.

따라서 Activity를 감싸기 위해 를 사용하지 않으면 Fragment요청한 내용이 불가능합니다.


1

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

1

해결 방법을 찾았습니다 :) 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) {

        }
    }

0

네 가능합니다

귀하의 활동에 대한 검색보기를 구현하십시오. 활동의 'onQueryTextChange'도 조각으로 검색을 수신합니다 .'onQueryTextChange '에서 조각 가시성을 확인할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.