조각이 있는 Android 검색
표준 Android 검색 인터페이스를 구현하는 방법에 대한 튜토리얼이나 예를 알고 계신 분?Fragment
표준 로 할 수 요? ,, 준준검 with with with with with with with with with with with with with with with with with with with with with with with with with?SearchManager
★★★★★★★★★★★★★★★★★?
한마디로 할 수 없다.하려면 , 가 있습니다.Fragment
아아아아아아아아아아아아아아아아아아아아.
검색 가능 인터페이스를 만들 때 Android 매니페스트에 기본 "검색 가능 활동"을 지정해야 합니다.아시겠지만
Fragment
할 수Activity
그래서 이 분리는 불가능합니다.만약 여러분이 이미 #1을 알아냈다면, 저는 여러분이 이 일을 해낼 수 있는 마법의 "해킹"이 밖에 있기를 바라면서 이 질문을 했을 것이라고 생각합니다.그러나 문서에는 다음과 같이 기술되어 있습니다.
사용자가 검색 대화상자 또는 위젯에서 검색을 실행하면 시스템은 검색 가능한 작업을 시작하고 ACTION_SEARCH 작업을 사용하여 검색 쿼리를 의도 형식으로 전달합니다.검색 가능한 액티비티는 의도의 QUERY 추가에서 쿼리를 검색한 다음 데이터를 검색하여 결과를 표시합니다.
내부 에서는 검색 결과 제공이 합니다.
Activity
이에요.Fragment
검색 되어 있는 경우, 인터페이스가 구현합니다.Activity
기본 시스템 자체를 변경해야 하므로 불가능합니다.내 말을 믿을 수 없는 경우 클래스의 소스 코드를 확인하십시오. : )
그렇다고 해서, 당신이 말하고 있는 것과 같은 것을 달성하는 것은 그다지 어렵지 않을 것 같습니다.를 들어, 검색 가능 액티비티를 할 수 .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
결과를 표시합니다.실장에는 아마 기대했던 것보다 조금 더 많은 작업이 필요하지만, 모듈러형으로 할 수 있는 방법이 있을 것입니다.이 방법이 최선인 것 같습니다.
p.s. 이 방법을 사용할 경우 백스택에 추가/제거되는 활동에 특히 주의해야 할 수 있습니다.그 방법에 대한 자세한 내용은 이 게시물을 참조해 주세요.
p.p.s. 에서 간단한 .Fragment
아래 라그하브의 투고에 기술되어 있습니다.
다음은 fragment를 사용하여 무언가를 검색하는 예입니다.도움이 되기를 바라며, 이것이 당신이 원하는 것입니다.
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);
}
}
}
표준 ActionBar SearchView ActionView API를 사용하여 fragment를 검색할 수 있습니다.이는 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" />
AppCompat 지원 클래스 v7 사용.@Rookie 솔루션에서 @David의 솔루션에 무언가를 추가하여 심플한 방법으로 올바르게 동작할 수 있도록 하고 있습니다.다음은 fragment 코드입니다.
My Fragment:
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;
}
}
는 가했 the the the를 추가했다.onActivityCreated
을 하지 「」를 참조할 수 없기 때문입니다.setHasOptionsMenu(true);
시스템은 이 fragment가 메뉴와 상호작용해야 한다는 것을 인식하지 못합니다.
줄을 요.inflater.inflate(R.menu.main, menu);
액티비티가 을 두 로 늘렸기 메뉴를.
@David와 @Rookie 덕분에
「 」를 Fragments
이렇게 요.Activity
Fragments
이거.Activity
이전과 같이 검색 기능을 사용할 수 있습니다.
에서 '보통'으로 Activity
베이 a a a a Fragment
앱 기반과 검색 기능은 저에게도 똑같이 작동했습니다.
당신은 그것을 시도해 보았지만 성공하지 못했나요?그렇다면 질문에 좀 더 자세히 답해 주세요.
편집:
검색을 는, 모든 fragment를 합니다.Fragments
를 MyFragment
a startSearch
method를 method를 합니다.Activity
의 »startSearch
는 현재의 fragment를 합니다.startSearch
★★★★★★ 。
제 생각에 저는 그것을 달성했다고 생각합니다: 실제로 fragments를 사용하여 fragments를 검색할 수 있도록 액션 바에 검색 아이콘을 추가할 수 있습니다.요령은 액션바, 액션뷰, 그 리스너, 로더 및 어댑터를 사용하는 것입니다.
이것은 안드로이드 플랫폼 검색 메커니즘을 완전히 우회하지만 꽤 잘 작동합니다(그러나 @Alex Lockwood가 설명하는 것을 찾아 fragment에 검색을 전달하는 작업을 통해 완료될 수 있습니다).액티비티의 경우 예상대로 의도에는 반응하지 않지만 기능합니다.사용자는 fragment 내부를 검색할 수 있습니다.
코드는 다음과 같습니다.
SearchInFragment 액티비티
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
fragment 클래스 Search Fragment(위의 액티비티 내에서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
검색 fragment 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>
하다를 사용하세요.ActionBar
★★★★★★★★★★★★★★★★★」SearchView
액티비티에 접속하지 않아도 검색을 처리할 수 있습니다.만 an just just 、 、 、 、 。OnQueryTextListener
검색 뷰입니다.
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;
}
});
커스텀 검색의 상세한 것에 대하여는, 이 투고를 참조해 주세요.
다른 해결책들.. 난 그게 싫어.이게 더 쉬워요.하지만 그건 내 생각이야.당신의 의견을 기다리겠습니다.
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);
}
A Fragment
에 할 수 Activity
, , , , , , A는 할 수 .Fragment
되어 android.intent.action.SEARCH
다른 는른른른른 orintent-filter
.
"VIP"를 Activity
을 하다Fragment
이치노
Fragments into a View Pager의 경우, 검색 바를 주고 싶은 fragment에 없을 때 검색 버튼을 차단하면 됩니다.활동 내용:
@Override
public boolean onSearchRequested() {
if (mPager.getCurrentItem() == mAdapter.getPosition(FragmentType.VIDEO))
return super.onSearchRequested();
else
return false;
}
물리적인 검색 버튼이 없는 경우 fragment에 액션 아이템을 추가했습니다.이것에 의해, 다음의 코드가 트리거 됩니다.
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.search_item) {
return getSherlockActivity().onSearchRequested();
}
return super.onOptionsItemSelected(item);
}
I found a work about :) 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) {
}
}
네, 가능합니다.
액티비티에 검색 뷰를 구현해 주세요.액티비티의 'onQueryTextChange'도 검색을 fragment화해, 「onQueryTextChange」에서 fragment화 여부를 확인할 수 있습니다.fragment 검색 방법을 호출할 수 있는 경우, 이것은 내 코드로 완벽하게 동작합니다.
언급URL : https://stackoverflow.com/questions/7230893/android-search-with-fragments
'programing' 카테고리의 다른 글
비동기 콜용 JNI 인터페이스 포인터(JNIEnv *)를 얻는 방법 (0) | 2022.08.08 |
---|---|
C의 매크로와 기능 (0) | 2022.08.08 |
Vuex 비활성 mapGetters(인수가 전달됨) (0) | 2022.08.08 |
img src에 대해 Vue JS 데이터 바인딩이 작동하지 않음 (0) | 2022.08.08 |
VueJs/NuxtJs에서 Axios 메서드를 동적으로 호출하는 방법 (0) | 2022.08.08 |