如何在搜索的选定 viewpager 片段中过滤 recyclerview?
How can filter recyclerview in selected viewpager fragment on search?
我在 viewpager 中有 3 个带标签的标签片段。所有选项卡都有 recyclerview,ListAdapter 显示客户列表。每个选项卡代表 1) 所有客户 2) 新订购的客户 3) 付费客户。我只想在选项卡选定的片段 上 设置搜索过滤器。如果 Searchview 可以放置在所有片段通用的 activity 上,对我来说会更好。我尝试了几种方法但都失败了。我的搜索结果总是只出现在最后一个选项卡(付费)中。请任何人帮助我提供完整的代码示例?
还有我的 MainActivity
private void initializeTab(){
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
viewPager = (MyViewPager) findViewById(R.id.view_pager);
viewPager.setOffscreenPageLimit(5);
viewPager.setAdapter(mSectionsPagerAdapter);
tabLayout = (SmartTabLayout) findViewById(R.id.tabs);
tabLayout.setViewPager(viewPager);
viewPager.setPagingEnabled(true);
}
private class SectionsPagerAdapter extends FragmentStatePagerAdapter {
protected int currentPosition = -1;
protected Fragment currentFragment;
public SectionsPagerAdapter(FragmentManager fm) {
super(fm,BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
@Override
public Fragment getItem(int position) {
return ViewPagerFragment.newInstance(getPageTitle(position)+"");
}
@Override
public int getCount() {
// Show 3 total pages.
return 3;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "All";
case 1:
return "New";
case 2:
return "Paid";
}
return null;
}
@Override
public void setPrimaryItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
super.setPrimaryItem(container, position, object);
this.currentPosition = position;
if (object instanceof Fragment){
this.currentFragment = (Fragment)object;
}
}
public Fragment getCurrentFragment() {
return currentFragment;
}
public void setCurrentFragment(Fragment currentFragment) {
this.currentFragment = currentFragment;
}
}
和我的片段
public class ViewPagerFragment extends AbstractFragment {
............
public static ViewPagerFragment newInstance(String title) {
ViewPagerFragment fragment = new ViewPagerFragment();
Bundle args = new Bundle();
args.putString("TITLE",title);
fragment.setArguments(args);
return fragment;
}
@Override
public void onViewCreated(final View view, Bundle savedInstanceState) {
swipeLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipeToRefresh);
recycler = (RecyclerView) view.findViewById(R.id.recycler);
adapter = new CustomerAdapter(getContext());
recycler.setLayoutManager(new LinearLayoutManager(getContext()));
recycler.setHasFixedSize(true);
recycler.addItemDecoration(new ItemDecoration(1,false, dpToPx(0),true,2));
recycler.setItemAnimator(new DefaultItemAnimator());
recycler.setAdapter(adapter);
changeFragment(swipeLayout);
}
public void changeFragment(final SwipeRefreshLayout swipeLayout){
final String tab = getArguments().getString("TITLE");
loadDatas(allRecords,tab);
swipeLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
swipeLayout.setRefreshing(true);
utils.getDetails(getContext());
utils.setOnDataLoaded(new MyUtils.DataLoadingListener() {
@Override
public void onDataLoaded(ArrayList<Customers> list) {
loadDatas(list, tab);
swipeLayout.setRefreshing(false);
}
});
}
});
// Scheme colors for animation
swipeLayout.setColorSchemeColors(
getResources().getColor(android.R.color.holo_blue_bright),
getResources().getColor(android.R.color.holo_green_light),
getResources().getColor(android.R.color.holo_orange_light),
getResources().getColor(android.R.color.holo_red_light)
);
}
void loadDatas(List<Customers> list, String tab){
if (list != null && list.size() > 0) {
List<Customers> tabList = new ArrayList<>();
if (tab.equals("All")) {
tabList = list;
}else {
for (Customers item : list) {
if (item.getStatus().equals(tab)) {
tabList.add(item);
}else {
Log.d(TAG, "loadDatas: "+item.getStatus());
}
}
}
adapter.submitList(tabList);
}
}
}
关于recyclerview过滤数据:
- 可以使您的 class CustomerAdapter 实现 Filterable
喜欢:
class Adapter extends RecyclerView.Adapter implements Filterable {
......
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
return ...;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
}
};
}
}
- 也可以参考这个:https://github.com/xaverkapeller/Searchable-RecyclerView-Demo
关于如何在选中的viewpager fragment中实现,只需要调用当前fragment的search方法即可。
the Searchview can place on activity which is common for all fragments, will be better in my case.
没错。
I tried several ways but was failed. My search was resulting always only in last tab (Paid).
所以,我假设现在的问题不在于过滤本身,而是它总是 returns 最后一个选项卡的结果;因此,您可能出于这种原因没有提供过滤代码。
现在 ViewPager
中有 3 个选项卡,每个选项卡代表一个片段;所以我们需要获取 ViewPager
的当前选定片段,以便 activity 将搜索到的文本发送给它。
从 ViewPager 获取当前片段(您的情况):
ViewPagerFragment currentFragment = (ViewPagerFragment) mViewPagerAdapter.instantiateItem(viewPager, viewPager.getCurrentItem());
从ViewPager2获取当前片段:
ViewPager 有 getCurrentItem()
当前页码 returns
所以,我们需要link每个页面片段到页码。
但是我们可以通过它的id(item id)得到一个ViewPager fragment,所以第一步是让page Ids等于相应的位置,这样做覆盖ViewPager适配器中的getItemId
。
@Override
public long getItemId(int position) {
return position;
}
然后在 activity 过滤部分假设您正在搜索名为 seachString
:
的 var 中的字符串
int pageId = viewpager.getCurrentItem();
Fragment currentFragment = (ViewPagerFragment) getChildFragmentManager()
.findFragmentByTag("f" + pageId);
然后在获取当前片段后,在其中创建一些接受搜索值的 String 参数的方法:
因此,在 ViewPagerFragment
中,创建:
public void searchFor(String search) {
// filter the results of the RecyclerView
}
然后在 activity:
中的 ViewPager 的当前片段上调用该方法
currentFragment.searchFor(seachString);
最后我成功了,我觉得不是很专业,但效果很好。为了帮助一些受苦的人,我在这里分享。
首先我添加了 tabScrollingListener 以获取 MainActivity 中的选定片段
public class MainActivity extends AppCompatActivity{
..........
private ViewPagerFragment selectedFragment;
private void initializeTab(){
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
viewPager = (MyViewPager) findViewById(R.id.view_pager);
viewPager.setOffscreenPageLimit(5);
viewPager.setAdapter(mSectionsPagerAdapter);
tabLayout = (SmartTabLayout) findViewById(R.id.tabs);
tabLayout.setViewPager(viewPager);
viewPager.setPagingEnabled(true);
viewPager.setCurrentItem(0);
tabLayout.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
selectedFragment = (ViewPagerFragment) mSectionsPagerAdapter.getCurrentFragment();
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
}
然后我将我的过滤函数转移到 Fragment 中,就像 Zain 的回答 中提到的那样。由于我正在为我的回收商使用 ListAdapter,因此很容易将我的过滤器列表提交给适配器。我在 loadData 函数上加载了我的过滤器列表。
public class ViewPagerFragment extends AbstractFragment {
............
private List<Customers> filterList;
public static ViewPagerFragment newInstance(String title) {
ViewPagerFragment fragment = new ViewPagerFragment();
Bundle args = new Bundle();
args.putString("TITLE",title);
fragment.setArguments(args);
return fragment;
}
@Override
public void onViewCreated(final View view, Bundle savedInstanceState) {
swipeLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipeToRefresh);
recycler = (RecyclerView) view.findViewById(R.id.recycler);
adapter = new CustomerAdapter(getContext());
recycler.setLayoutManager(new LinearLayoutManager(getContext()));
recycler.setHasFixedSize(true);
recycler.addItemDecoration(new ItemDecoration(1,false, dpToPx(0),true,2));
recycler.setItemAnimator(new DefaultItemAnimator());
recycler.setAdapter(adapter);
changeFragment(swipeLayout);
}
public void changeFragment(final SwipeRefreshLayout swipeLayout){
final String tab = getArguments().getString("TITLE");
loadDatas(allRecords,tab);
swipeLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
swipeLayout.setRefreshing(true);
utils.getDetails(getContext());
utils.setOnDataLoaded(new MyUtils.DataLoadingListener() {
@Override
public void onDataLoaded(ArrayList<Customers> list) {
loadDatas(list, tab);
swipeLayout.setRefreshing(false);
}
});
}
});
// Scheme colors for animation
swipeLayout.setColorSchemeColors(
getResources().getColor(android.R.color.holo_blue_bright),
getResources().getColor(android.R.color.holo_green_light),
getResources().getColor(android.R.color.holo_orange_light),
getResources().getColor(android.R.color.holo_red_light)
);
}
void loadDatas(List<Customers> list, String tab){
if (list != null && list.size() > 0) {
List<Customers> tabList = new ArrayList<>();
if (tab.equals("All")) {
tabList = list;
}else {
for (Customers item : list) {
if (item.getStatus().equals(tab)) {
tabList.add(item);
}else {
Log.d(TAG, "loadDatas: "+item.getStatus());
}
}
}
filterList = tabList; // this fills filter list
adapter.submitList(tabList);
}
}
}
public void filter(String text, String filter) {
ArrayList<Customers> filteredlist = new ArrayList<>();
// running a for loop to compare elements.
if (filterList != null && filterList.size() > 0) {
if (text.length() > 0) {
for (Customers item : filterList) {
// here filter options gone
}
}else {
filteredlist.addAll(filterList);
}
}
adapter.submitList(filteredlist);
}
是的,现在我在 MainActivity 中得到了带有过滤功能的 currentSelectedFragment
在 searchListener 中,我可以将其称为 selectedFragment.filter(query).
searchview.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
selectedFragment.filter(newText); // search filter here
return true;
}
});
我在 viewpager 中有 3 个带标签的标签片段。所有选项卡都有 recyclerview,ListAdapter 显示客户列表。每个选项卡代表 1) 所有客户 2) 新订购的客户 3) 付费客户。我只想在选项卡选定的片段 上 设置搜索过滤器。如果 Searchview 可以放置在所有片段通用的 activity 上,对我来说会更好。我尝试了几种方法但都失败了。我的搜索结果总是只出现在最后一个选项卡(付费)中。请任何人帮助我提供完整的代码示例?
还有我的 MainActivity
private void initializeTab(){
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
viewPager = (MyViewPager) findViewById(R.id.view_pager);
viewPager.setOffscreenPageLimit(5);
viewPager.setAdapter(mSectionsPagerAdapter);
tabLayout = (SmartTabLayout) findViewById(R.id.tabs);
tabLayout.setViewPager(viewPager);
viewPager.setPagingEnabled(true);
}
private class SectionsPagerAdapter extends FragmentStatePagerAdapter {
protected int currentPosition = -1;
protected Fragment currentFragment;
public SectionsPagerAdapter(FragmentManager fm) {
super(fm,BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
@Override
public Fragment getItem(int position) {
return ViewPagerFragment.newInstance(getPageTitle(position)+"");
}
@Override
public int getCount() {
// Show 3 total pages.
return 3;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "All";
case 1:
return "New";
case 2:
return "Paid";
}
return null;
}
@Override
public void setPrimaryItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
super.setPrimaryItem(container, position, object);
this.currentPosition = position;
if (object instanceof Fragment){
this.currentFragment = (Fragment)object;
}
}
public Fragment getCurrentFragment() {
return currentFragment;
}
public void setCurrentFragment(Fragment currentFragment) {
this.currentFragment = currentFragment;
}
}
和我的片段
public class ViewPagerFragment extends AbstractFragment {
............
public static ViewPagerFragment newInstance(String title) {
ViewPagerFragment fragment = new ViewPagerFragment();
Bundle args = new Bundle();
args.putString("TITLE",title);
fragment.setArguments(args);
return fragment;
}
@Override
public void onViewCreated(final View view, Bundle savedInstanceState) {
swipeLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipeToRefresh);
recycler = (RecyclerView) view.findViewById(R.id.recycler);
adapter = new CustomerAdapter(getContext());
recycler.setLayoutManager(new LinearLayoutManager(getContext()));
recycler.setHasFixedSize(true);
recycler.addItemDecoration(new ItemDecoration(1,false, dpToPx(0),true,2));
recycler.setItemAnimator(new DefaultItemAnimator());
recycler.setAdapter(adapter);
changeFragment(swipeLayout);
}
public void changeFragment(final SwipeRefreshLayout swipeLayout){
final String tab = getArguments().getString("TITLE");
loadDatas(allRecords,tab);
swipeLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
swipeLayout.setRefreshing(true);
utils.getDetails(getContext());
utils.setOnDataLoaded(new MyUtils.DataLoadingListener() {
@Override
public void onDataLoaded(ArrayList<Customers> list) {
loadDatas(list, tab);
swipeLayout.setRefreshing(false);
}
});
}
});
// Scheme colors for animation
swipeLayout.setColorSchemeColors(
getResources().getColor(android.R.color.holo_blue_bright),
getResources().getColor(android.R.color.holo_green_light),
getResources().getColor(android.R.color.holo_orange_light),
getResources().getColor(android.R.color.holo_red_light)
);
}
void loadDatas(List<Customers> list, String tab){
if (list != null && list.size() > 0) {
List<Customers> tabList = new ArrayList<>();
if (tab.equals("All")) {
tabList = list;
}else {
for (Customers item : list) {
if (item.getStatus().equals(tab)) {
tabList.add(item);
}else {
Log.d(TAG, "loadDatas: "+item.getStatus());
}
}
}
adapter.submitList(tabList);
}
}
}
关于recyclerview过滤数据:
- 可以使您的 class CustomerAdapter 实现 Filterable
喜欢:
class Adapter extends RecyclerView.Adapter implements Filterable {
......
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
return ...;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
}
};
}
}
- 也可以参考这个:https://github.com/xaverkapeller/Searchable-RecyclerView-Demo
关于如何在选中的viewpager fragment中实现,只需要调用当前fragment的search方法即可。
the Searchview can place on activity which is common for all fragments, will be better in my case.
没错。
I tried several ways but was failed. My search was resulting always only in last tab (Paid).
所以,我假设现在的问题不在于过滤本身,而是它总是 returns 最后一个选项卡的结果;因此,您可能出于这种原因没有提供过滤代码。
现在 ViewPager
中有 3 个选项卡,每个选项卡代表一个片段;所以我们需要获取 ViewPager
的当前选定片段,以便 activity 将搜索到的文本发送给它。
从 ViewPager 获取当前片段(您的情况):
ViewPagerFragment currentFragment = (ViewPagerFragment) mViewPagerAdapter.instantiateItem(viewPager, viewPager.getCurrentItem());
从ViewPager2获取当前片段:
ViewPager 有 getCurrentItem()
当前页码 returns
所以,我们需要link每个页面片段到页码。
但是我们可以通过它的id(item id)得到一个ViewPager fragment,所以第一步是让page Ids等于相应的位置,这样做覆盖ViewPager适配器中的getItemId
。
@Override
public long getItemId(int position) {
return position;
}
然后在 activity 过滤部分假设您正在搜索名为 seachString
:
int pageId = viewpager.getCurrentItem();
Fragment currentFragment = (ViewPagerFragment) getChildFragmentManager()
.findFragmentByTag("f" + pageId);
然后在获取当前片段后,在其中创建一些接受搜索值的 String 参数的方法:
因此,在 ViewPagerFragment
中,创建:
public void searchFor(String search) {
// filter the results of the RecyclerView
}
然后在 activity:
中的 ViewPager 的当前片段上调用该方法currentFragment.searchFor(seachString);
最后我成功了,我觉得不是很专业,但效果很好。为了帮助一些受苦的人,我在这里分享。
首先我添加了 tabScrollingListener 以获取 MainActivity 中的选定片段
public class MainActivity extends AppCompatActivity{
..........
private ViewPagerFragment selectedFragment;
private void initializeTab(){
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
viewPager = (MyViewPager) findViewById(R.id.view_pager);
viewPager.setOffscreenPageLimit(5);
viewPager.setAdapter(mSectionsPagerAdapter);
tabLayout = (SmartTabLayout) findViewById(R.id.tabs);
tabLayout.setViewPager(viewPager);
viewPager.setPagingEnabled(true);
viewPager.setCurrentItem(0);
tabLayout.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
selectedFragment = (ViewPagerFragment) mSectionsPagerAdapter.getCurrentFragment();
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
}
然后我将我的过滤函数转移到 Fragment 中,就像 Zain 的回答 中提到的那样。由于我正在为我的回收商使用 ListAdapter,因此很容易将我的过滤器列表提交给适配器。我在 loadData 函数上加载了我的过滤器列表。
public class ViewPagerFragment extends AbstractFragment {
............
private List<Customers> filterList;
public static ViewPagerFragment newInstance(String title) {
ViewPagerFragment fragment = new ViewPagerFragment();
Bundle args = new Bundle();
args.putString("TITLE",title);
fragment.setArguments(args);
return fragment;
}
@Override
public void onViewCreated(final View view, Bundle savedInstanceState) {
swipeLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipeToRefresh);
recycler = (RecyclerView) view.findViewById(R.id.recycler);
adapter = new CustomerAdapter(getContext());
recycler.setLayoutManager(new LinearLayoutManager(getContext()));
recycler.setHasFixedSize(true);
recycler.addItemDecoration(new ItemDecoration(1,false, dpToPx(0),true,2));
recycler.setItemAnimator(new DefaultItemAnimator());
recycler.setAdapter(adapter);
changeFragment(swipeLayout);
}
public void changeFragment(final SwipeRefreshLayout swipeLayout){
final String tab = getArguments().getString("TITLE");
loadDatas(allRecords,tab);
swipeLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
swipeLayout.setRefreshing(true);
utils.getDetails(getContext());
utils.setOnDataLoaded(new MyUtils.DataLoadingListener() {
@Override
public void onDataLoaded(ArrayList<Customers> list) {
loadDatas(list, tab);
swipeLayout.setRefreshing(false);
}
});
}
});
// Scheme colors for animation
swipeLayout.setColorSchemeColors(
getResources().getColor(android.R.color.holo_blue_bright),
getResources().getColor(android.R.color.holo_green_light),
getResources().getColor(android.R.color.holo_orange_light),
getResources().getColor(android.R.color.holo_red_light)
);
}
void loadDatas(List<Customers> list, String tab){
if (list != null && list.size() > 0) {
List<Customers> tabList = new ArrayList<>();
if (tab.equals("All")) {
tabList = list;
}else {
for (Customers item : list) {
if (item.getStatus().equals(tab)) {
tabList.add(item);
}else {
Log.d(TAG, "loadDatas: "+item.getStatus());
}
}
}
filterList = tabList; // this fills filter list
adapter.submitList(tabList);
}
}
}
public void filter(String text, String filter) {
ArrayList<Customers> filteredlist = new ArrayList<>();
// running a for loop to compare elements.
if (filterList != null && filterList.size() > 0) {
if (text.length() > 0) {
for (Customers item : filterList) {
// here filter options gone
}
}else {
filteredlist.addAll(filterList);
}
}
adapter.submitList(filteredlist);
}
是的,现在我在 MainActivity 中得到了带有过滤功能的 currentSelectedFragment 在 searchListener 中,我可以将其称为 selectedFragment.filter(query).
searchview.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
selectedFragment.filter(newText); // search filter here
return true;
}
});