[英]How to use onQueryTextChange with many fragments
我有很多片段,它們在2個標簽布局中顯示,在每個片段中使用FragmentStatePagerAdapter
有一個Recycler視圖,我想在應用欄中使用搜索欄來過濾結果。
首先,我使用onCreateOptionsMenu中的onQueryTextChange listener
此操作,並且它與一些片段一起正常工作但是當我將實現添加到其他片段(只是ctrl + c和ctrl + v)時它停止工作,甚至在使用的片段上也沒有結果工作我然后在這里讀到,最好將onQueryTextChange listener in onPrepareOptionsMenu
粘貼onQueryTextChange listener in onPrepareOptionsMenu
上以試圖避免invalidateOptionsMenu的問題,但我決定嘗試一下也有效,然后當我將方法添加到我所有其他片段時它再次失敗,但它確實對一些片段起作用,奇怪的是這些片段恰好全部附加到同一個父片段,但是4個父片段的代碼,以及用於調用它們的代碼是相同的。
我已經閱讀的另一種方法是creating an interface
並通過獲取對當前片段的引用從我的主要活動中使用它,然后id必須從我的viewpager獲取當前顯示的片段,我不知道是否有可能任何人稱重對我來說,
非常感謝
並感謝偉大的編輯大聲笑
編輯嘗試接口方法無濟於事,雖然我還是初學者,我確實需要找到附加的片段,並且使用fragmentstateviewpager它是不可能的,如果不使用黑客,必須有一些理由為什么它在某些工作而不是在其他工作一點也不
編輯2
所以即時通訊仍然擺弄這個,我幾乎沒有回復所以讓我的肉體這一點,所以我在主要活動中添加菜單布局,像這樣
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.dashboard, menu);
SearchView searchView =
(SearchView)menu.findItem(R.id.action_search).getActionView();
SearchManager searchManager = (SearchManager)
getSystemService(SEARCH_SERVICE);
searchView.setSearchableInfo(searchManager
.getSearchableInfo(getComponentName()));
return true;
}
然后從onPrepareOptionsMenu中的片段添加一個監聽器,就像這樣
@Override
public void onPrepareOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
//in this instance we wont as it will create a duplicate
SearchView searchView = (SearchView)
menu.findItem(R.id.action_search).getActionView();
searchView.setOnQueryTextListener(null);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener(){
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
showResults(newText);
return false;
}
});
super.onPrepareOptionsMenu(menu);
}
我在片段的onCreateView中調用了setHasOptionsMenu(true),這個工作完美但我有大約20個片段循環通過,當我將其添加到其他片段時它失敗了它或者什么也不做或者使視圖空白或者在極少數情況下工作,但對我來說,我的代碼是好的,也許它是一個生命周期的事情,我嘗試從碎片的onCreateOptionsMenu調用它,並取得了相同的結果,並且我試圖不在onCreateOptions中調用MainActivity中的任何東西,除了膨脹菜單和允許片段使用調用搜索活動
SearchView searchView = (SearchView)menu.findItem
(R.id.action_search).getActionView();
SearchManager searchManager = (SearchManager)
getActivity().getSystemService(getActivity().SEARCH_SERVICE);
searchView.setSearchableInfo(searchManager.getSearchableInfo
(getActivity().getComponentName()));
它再次起作用大約8個碎片,但我的20左右只會導致它落在它的劍上,有什么我不做的可以幫助
編輯3好吧所以通過添加一些,檢查它,添加更多,檢查它,它似乎是我的父片段的問題所以我有主要活動4片段,每個片段持有一個片段狀態尋呼機,每個片段包含7個左右的片段,如果我將查詢偵聽器的方法添加到第一個父片段中的前7個左右片段,它們都可以很好地工作,如果我然后將方法添加到第二個父節點中的下一組7個左右片段只有第二個父節點子片段工作,如果我然后退出我的應用程序並再次打開它只有第一個父母片段工作,將繼續調查任何幫助表示我將很快發布我的父片段的代碼。
編輯4只是為我的主要活動添加我用於父片段和fragmentstatepager的代碼
所以從我的主要活動中我設置了像這樣的fragmentstatepager
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new
ViewPagerAdapter(getSupportFragmentManager());
adapter.addFrag(new sentenceMakers(), "QUICKS");
adapter.addFrag(new tabFragOne(), "NOUNS");
adapter.addFrag(new tabFragTwo(), "VERBS");
adapter.addFrag(new tabFragThree(), "OBJECTS");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentStatePagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public void restoreState(Parcelable arg0, ClassLoader arg1) {
//do nothing here! no call to super.restoreState(arg0, arg1);
}
@Override
public int getCount() {
return mFragmentList.size();
}
public void addFrag(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
我的父母片段看起來像這樣
public class sentenceMakers extends Fragment{
public ImageView imageView;
private ViewPager viewPager;
public static TabLayout tabLayout;
public sentenceMakers() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState){
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate
(R.layout.tab_frag_one, container, false);
// Inflate the layout for this fragment
//setRetainInstance(true);
viewPager = (ViewPager) rootView.findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) rootView.findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
setupTabIcons();
return rootView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
}
private void setupTabIcons() {
TextView tabZero2 = (TextView)
LayoutInflater.from(getActivity()).inflate(R.layout.custom_tab, null);
tabZero2.setText("FAVOURITES");
//tabOne.setGravity(View.TEXT_ALIGNMENT_CENTER);
tabZero2.setCompoundDrawablesWithIntrinsicBounds(0,
R.drawable.ic_star_white_24dp, 0, 0);
tabLayout.getTabAt(0).setCustomView(tabZero2);
TextView tabZero = (TextView)
LayoutInflater.from(getActivity()).inflate(R.layout.custom_tab, null);
tabZero.setText("FREQUENTS");
//tabOne.setGravity(View.TEXT_ALIGNMENT_CENTER);
tabZero.setCompoundDrawablesWithIntrinsicBounds(0,
R.drawable.ic_people_outline_white_24dp, 0, 0);
tabLayout.getTabAt(1).setCustomView(tabZero);
TextView tabOne = (TextView)
LayoutInflater.from(getActivity()).inflate(R.layout.custom_tab, null);
tabOne.setText("PRONOUNS");
//tabOne.setGravity(View.TEXT_ALIGNMENT_CENTER);
tabOne.setCompoundDrawablesWithIntrinsicBounds(0,
R.drawable.ic_accessibility_white_24dp, 0, 0);
tabLayout.getTabAt(2).setCustomView(tabOne);
TextView tabTwo = (TextView)
LayoutInflater.from(getActivity()).inflate(R.layout.custom_tab, null);
tabTwo.setText("CONJUCTIONS");
tabTwo.setCompoundDrawablesWithIntrinsicBounds(0,
R.drawable.ic_add_white_24dp, 0, 0);
tabLayout.getTabAt(3).setCustomView(tabTwo);
TextView tabThree = (TextView)
LayoutInflater.from(getActivity()).inflate(R.layout.custom_tab, null);
tabThree.setText("ADJECTIVES");
tabThree.setCompoundDrawablesWithIntrinsicBounds(0,
R.drawable.ic_favorite_border_white_24dp, 0, 0);
tabLayout.getTabAt(4).setCustomView(tabThree);
tabLayout.getTabAt(0).getCustomView().setSelected(true);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new
ViewPagerAdapter(getChildFragmentManager());
adapter.addFrag(new favouriteCards(), "FAVOURITES");
adapter.addFrag(new predictedCards(), "FREQUENTS");
adapter.addFrag(new pronouns(), "PRONOUNS");
adapter.addFrag(new conjuctions(), "CONJUNCTIONS");
adapter.addFrag(new Others(), "ADJECTIVES");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
public void addFrag(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
}
}
仍然在努力解決這個問題,我不能為我的生活找出原因,為什么它會在很多片段中起作用,直到我將它添加到下一組,同樣的代碼與相同的代碼一樣,它必須只是初始化最后的片段要求它可以幫助我嗎? 謝謝你的幫助
基本上,在使用片段時必須記住: 不要保留對片段的引用 :只需創建它們並添加到布局中,或者提供給ViewPager,然后使用其他方法來檢索它們,例如FragmentManager.findFragmentBy ...
那就是說,你的代碼應該是(讓我用兩個片段簡化):
主要活動
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new MyViewPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(adapter);
}
class MyViewPagerAdapter extends FragmentStatePagerAdapter {
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
@Override
public Fragment getItem(int position) {
switch(position) {
case 0:
return new sentenceMakers();
case 1:
return new tabFragOne();
// add here fragments for any other position
}
}
@Override
public int getCount() {
return 2;
}
@Override
public CharSequence getPageTitle(int position) {
switch(position) {
case 0:
return "QUICKS";
case 1:
return "NOUNS";
// add here titles for any other position
}
}
}
sentenceMakers
你必須在你的sentenceMakers片段中使用的代碼與前一個代碼非常相似,但你必須使用子fragmentManager(就像你在代碼中所做的那樣),再次,不要將你的片段保存在List中,讓系統在需要時創建它們。
好吧我修復它所以問題是父fragmentstatepager將fragmentA + fragmentB加載到內存中,然后子fragmentstatepagers加載自己的childfragmentA + childfragmentB所以我們現在有2個父母和4個孩子,onPrepareOptionsMenu從子片段調用所以第一個加載了childfragmentA(fragmentA的子進程)然后加載了childFragmentA(fragmentB的子進程)並竊取了搜索視圖,我的'修復'對此可能有點粗糙我是自學成才,我不是很清楚如何管理內存或者如果它不能保持引用等等,我離題,在父片段中我檢查哪個片段是可見的
setMenuVisibility(final boolean visible)
在那里我設置了一個公共的靜態布爾值,並在我的childfragments中檢查它,它對我來說完美無缺,因為提到這可能是一個可怕的事情,希望有人在這里可以提供更好的解決方案
檢查哪個父項可見
public static boolean tabFragOneVisible;
@Override
public void setUserVisibleHint(boolean isVisible){
super.setUserVisibleHint(isVisible);
if(!isVisible){
tabFragOneVisible = false;
}else{
tabFragOneVisible = true;
}
}
檢查父項是否可見掛鈎搜索視圖
@Override
public void onPrepareOptionsMenu(Menu menu) {
// need to check if fragment is visible
if (tabFragOne.tabFragOneVisible) {
SearchView searchView = (SearchView)
menu.findItem(R.id.action_search).getActionView();
SearchManager searchManager = (SearchManager) getActivity()
.getSystemService(getActivity().SEARCH_SERVICE);
searchView.setSearchableInfo(searchManager
.getSearchableInfo(getActivity().getComponentName()));
// searchView.setOnQueryTextListener(null);
searchView.setOnQueryTextListener(new
SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
showResults(newText);
return false;
}
});
}
else{
}
super.onPrepareOptionsMenu(menu);
}
也許,它仍然可以幫助有人努力使一個SearchView適用於多個碎片。 我發現onQueryTextListener可以在Fragment 1(最初創建SearchView的地方)上工作,但是不會在Fragment 2,3上等等。
當onPrepareOptionsMenu被覆蓋並且onViewCreated包含setHasOptionsMenu(true)時,片段2工作。 例如:
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setHasOptionsMenu(true);
...the rest of your code goes here...
}
@Override
public void onPrepareOptionsMenu(Menu menu) {
MenuItem item = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) item.getActionView();
searchView.setOnQueryTextListener(this);
super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
Toast.makeText(getActivity(),"It Worked!!",Toast.LENGTH_SHORT).show();
return true;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.