簡體   English   中英

如何在搜索時過濾選定的viewpager片段中的recyclerview?

[英]How can filter recyclerview in selected viewpager fragment on search?

我在帶有標簽的 viewpager 中有 3 個標簽片段。 所有選項卡都有 recyclerview 和 ListAdapter 顯示客戶列表。 每個選項卡代表 1) 所有客戶 2) 新訂購的客戶 3) 付費客戶。 我只想在選項卡選擇的片段上設置搜索過濾器。 如果 Searchview 可以放置在所有片段通用的活動上,那么在我的情況下會更好。 我嘗試了幾種方法,但都失敗了。 我的搜索結果總是只在最后一個標簽(付費)中。 請任何人都可以幫助我提供完整的代碼示例嗎?

還有我的 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. 可以讓你的類 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 片段中執行此操作,您只需要調用當前片段的搜索方法。

Searchview 可以放置在所有片段通用的活動上,在我的情況下會更好。

這是對的。

我嘗試了幾種方法,但都失敗了。 我的搜索總是只在最后一個選項卡(付費)中產生。

所以,我假設現在的問題不在於過濾本身,而是它總是返回最后一個選項卡的結果; 因此,您可能出於這樣的原因沒有提供過濾代碼。

現在我們在ViewPager有 3 個選項卡,每個選項卡代表一個片段; 所以我們需要獲取當前選中的ViewPager片段,以允許 Activity 將搜索到的文本發送給它。

從 ViewPager 獲取當前片段(您的情況):

ViewPagerFragment currentFragment = (ViewPagerFragment) mViewPagerAdapter.instantiateItem(viewPager, viewPager.getCurrentItem());

從 ViewPager2 獲取當前片段:

ViewPager 有getCurrentItem()返回當前頁碼因此,我們需要將每個頁面片段鏈接到頁碼。

但是我們可以通過它的 id (item id) 來獲取一個 ViewPager 片段,所以第一步是讓頁面 Id 等於相應的位置,以便覆蓋 ViewPager 適配器中的getItemId

@Override
public long getItemId(int position) {
    return position;
}

然后在活動過濾部分,假設您正在搜索名為seachString的 var 中的seachString

int pageId = viewpager.getCurrentItem();

Fragment currentFragment = (ViewPagerFragment) getChildFragmentManager()
                                              .findFragmentByTag("f" + pageId);

然后在獲取當前片段后,在其中創建一些接受搜索值的字符串參數的方法:

因此,在ViewPagerFragment ,創建:

public void searchFor(String search) {
    // filter the results of the RecyclerView
}

並在活動中的 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) {

            }
     });

  }

}

然后我像 Zain 的回答中提到的那樣將我的過濾器功能轉移到 Fragment 當我將 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;
            }
        });
Follow the below step to find the clicked tab, 

First add tab select listener 
    
    tabLayout.addOnTabSelectedListener(object:TabLayout.OnTabSelectedListener{
    override fun onTabSelected(tab: TabLayout.Tab?) {
       selectedFragment= fragmentViewPagerAdapter!!.fragments[tab!!.position]
    }
    override fun onTabUnselected(tab: TabLayout.Tab?) {
//               enter code here
            }
    override fun onTabReselected(tab: TabLayout.Tab?) {
//               enter code here
            }
        }) 

and then  setupWithViewPager 
        tabLayout.setupWithViewPager(viewPager)
  

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM