如何在搜索的选定 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过滤数据:

  1. 可以使您的 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) {

            }
        };
    }
}    
  1. 也可以参考这个: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;
            }
        });