在这里,我在一个Activity
中有一个toolbar
,它包含一个SearchView
。这个Activity有多个片段。其中一个主片段有10个以上的片段。所有10个片段都在列表视图中显示数据。现在我尝试通过MainActivity
的SearchView
来过滤所有片段列表。但是它从来没有过滤每个片段的列表。现在,我将向您展示我是如何实现这一切的。
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.action_search));
SearchManager searchManager = (SearchManager) getSystemService(SEARCH_SERVICE);
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
changeSearchViewTextColor(searchView);
return true;
}
}
Fragment.java
public class CurrencyFragment2 extends android.support.v4.app.Fragment implements SearchView.OnQueryTextListener {
@Override
public void setMenuVisibility(boolean menuVisible) {
super.setMenuVisibility(menuVisible);
if (menuVisible && getActivity() != null) {
SharedPreferences pref = getActivity().getPreferences(0);
int id = pref.getInt("viewpager_id", 0);
if (id == 2)
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());
changeSearchViewTextColor(sv);
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);
super.onCreateOptionsMenu(menu, inflater);
}
private void changeSearchViewTextColor(View view) {
if (view != null) {
if (view instanceof TextView) {
((TextView) view).setTextColor(Color.WHITE);
((TextView) view).setHintTextColor(Color.WHITE);
((TextView) view).setCursorVisible(true);
return;
} else if (view instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) view;
for (int i = 0; i < viewGroup.getChildCount(); i++) {
changeSearchViewTextColor(viewGroup.getChildAt(i));
}
}
}
}
@Override
public boolean onQueryTextSubmit(String query) {
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
if (adapter != null) {
adapter.filter2(newText);
}
return true;
}
Adapter类内的Filter方法。
// Filter Class
public void filter2(String charText) {
charText = charText.toLowerCase(Locale.getDefault());
items.clear();
if (charText.length() == 0) {
items.addAll(arraylist);
} else {
for (EquityDetails wp : arraylist) {
if (wp.getExpert_title().toLowerCase(Locale.getDefault()).contains(charText)) {
items.add(wp);
}
}
}
notifyDataSetChanged();
}
3条答案
按热度按时间ryhaxcpt1#
你可以通过使用Observable/Observer模式来管理嵌套列表上的过滤器,这将从一个Observable parent更新每个嵌套列表。我修复了all troubles,它现在工作得很好,可以实现正确的行为。
因此,以下是我为实现这一目标所做的工作:
1.在
Activity
中使用一个父SearchView
1.(可选)在嵌套列表
Adapter
中创建Filter
类(* android. widget. Filter *)1.然后,使用
Observable
/Observer
模式来嵌套Fragment
和Activity
onQueryTextChange
似乎从未在Fragment
s中调用过。当我点击搜索图标时,我觉得SearchView
(编辑文本、图标等)似乎没有与搜索小部件连接(而是与Activity的小部件连接)。filter2
:我的意思是,当我解决了前面的问题时,这个方法不起作用。实际上,我不得不使用Filter
扩展的自定义类及其两个方法:performFiltering
和publishResults
。如果没有它,当我点击搜索栏中的一个单词时,我会得到一个空白屏幕。然而,这可能只是我的代码,也许filter2()
非常适合你...SearchView
。在我看来,您在嵌套片段中重复调用了这一行SearchView sv = new SearchView(...);
。因此,每次我切换到下一个片段时,扩展的搜索视图都会删除它之前的文本值。无论如何,经过一些研究,我在SO上找到了关于实现Search fragment的this answer。几乎和你的代码一样,除了你在父活动和片段中"复制"了选项菜单代码。你不应该这样做-我认为这是我前面第一个问题的原因。
此外,答案链接中使用的模式(一个片段中的一个搜索)可能不适用于您的模式(多个片段中的一个搜索),您应该在父
Activity
中调用一个SearchView
来表示所有嵌套的Fragment
。SearchView
:*这将避免重复的功能,并让父Activity监督它的所有子Activity。此外,这将避免菜单中出现重复图标。
这是
Activity
的主要父类:Filter
小工具:*就像我之前说的,我不能让它与
filter2()
一起工作,所以我创建了一个Filter
类,作为Web上的任何示例。它快速地看起来像,在适配器的嵌套片段中,如下所示:
Observable
/Observer
模式:*Activity(带有searchview)是
Observable
对象,嵌套片段是Observer
s(see Observer pattern)。基本上,当onQueryTextChange
被调用时,它将触发现有观察器中的update()
方法。下面是父
Activity
中的声明:这是
Observable
类,它将侦听并"传递"更新的数据:为了添加observer片段来侦听searchview值,我在
FragmentStatePagerAdapter
中初始化它们时这样做。因此,在父片段中,我通过传递
FilterManager
:适配器将add the observer到父可观察对象,并在子片段被破坏时将其移除。
下面是父片段的
ViewPagerAdapter
:最后,当使用
onQueryTextChange()
调用活动中的filterManager.setQuery()
时,将在实现Observer
的update()
方法中的嵌套片段中接收此消息。这是要过滤的带有
ListView
的嵌套片段:这样做效果很好,所有嵌套片段中的列表都可以通过一个searchview按预期进行更新。但是,在我上面的代码中有一个不方便的地方,你应该注意:
Fragment
通用对象并将其添加为观察者。实际上,我必须使用特定的片段类(这里是NestedFragment
)进行转换和初始化;也许有一个简单解决办法,但我暂时没有找到。尽管如此,我还是得到了正确的行为,而且--我认为--让一个搜索小工具保持在顶部的活动状态可能是一个很好的模式。因此,通过这个解决方案,你可以得到一个线索,一个正确的方向,来实现你想要的。我希望你会喜欢。
Fragment
类扩展来添加观察器。通过创建
ObserverFragment
类,如下所示:然后,通过扩展和重写嵌套片段中的
update()
:nzk0hqpo2#
为了更好地理解问题。1.操作栏中有一个搜索视图2.有多个片段(来自图片Advisory/TopAdvisors...)3.在每个片段中,每个选项卡都有多个片段(例如Equity...等)4.您希望片段中的所有列表视图根据搜索内容筛选其数据
对不对?
在您当前的实施中,状态是什么?当前显示的列表视图是否已过滤?
然后你需要检查notifydatasetChanged是否正确地传播到适配器。这意味着它应该在UIThread本身上。
对于所有片段的更新,即当您键入搜索文本时不在屏幕上的片段,您需要考虑片段的生命周期,并在片段的onResume中包含代码,以确保列表在用于初始化适配器之前已被过滤。这适用于您已键入搜索文本,现在正在选项卡/片段之间移动的情况。因此,片段会在屏幕上显示和显示,因此需要onResume。
更新:包括检查搜索框的文本,如果它有东西调用adapter.filter2()在onResume,因为这基本上是什么过滤您的列表。
zvms9eto3#
我假设你的viewpager/tabs是以这样一种方式实现的:每当你切换可见片段时,它们就会被破坏。
进行以下更改(阅读注解)
现在,在你所有的片段中这样做-
同样,在你的SearchView.OnQueryTextListener片段中,这样做
我希望你能大致了解
我不推荐这种设计,我宁愿做的是