【问题标题】:Calling Adapter from Fragments in ViewPager从 ViewPager 中的片段调用适配器
【发布时间】:2016-05-24 11:53:41
【问题描述】:

我有 Fragment ,它有一个 searchview 和 viewpager 。我的 viewpager 有 3 个片段,每个片段都调用适配器。现在要实现 searchview ,我需要在视图寻呼机中调用可见片段的适配器。

SlidingTab(带有 searchview 和 ViewPager 的片段):

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/frame_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.RareMediaCompany.BDTrial.SlidingTab">

    <include
        android:id="@+id/toolbar1"
        layout="@layout/toolbar_job" />

    <com.RareMediaCompany.BDTrial.Utils.CustomTabLayout
        android:id="@+id/sliding_tabs"
        style="@style/CustomTabLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#eeeeee"
        app:tabIndicatorColor="#f39220"
        app:tabIndicatorHeight="3dp"
        app:tabMaxWidth="0dp"
        app:tabMode="fixed"
        app:tabPaddingEnd="0dp"
        app:tabPaddingStart="0dp"
        app:tabTextAppearance="@android:style/TextAppearance.Widget.TabWidget"
        app:tabSelectedTextColor="#808080" />

    <LinearLayout
        android:id="@+id/linear1"
        android:background="@android:color/white"
        android:layout_width="match_parent"
        android:layout_height="70dp"
        android:orientation="horizontal"
        android:weightSum="1">

        <android.support.v7.widget.SearchView
        android:layout_width="300dp"
        android:layout_height="45dp"
        android:id="@+id/searchView"
        android:layout_weight="0.9"
        android:layout_marginRight="5dp"
        android:layout_gravity="center"
        style="@style/CitySearchView"
        android:background="@drawable/searchview"
        android:layout_marginLeft="10dp"/>

        <LinearLayout
            android:id="@+id/list_linearlayout"
            android:layout_width="45dp"
            android:layout_height="45dp"
            android:layout_weight="0"
            android:layout_gravity="center"
            android:background="#f39220">
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:layout_weight="0.3"
                android:src="@drawable/list_icon_white"/>

        </LinearLayout>

        <LinearLayout
            android:layout_width="45dp"
            android:layout_height="45dp"
            android:layout_gravity="center"
            android:layout_weight="0"
            android:layout_marginRight="10dp"
            android:background="#75aadb">
            <ImageView
                android:layout_width="20dp"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:layout_marginRight="2dp"
                android:layout_weight="0.3"
                android:src="@drawable/mapmarker"/>

        </LinearLayout>


    </LinearLayout>
        <!--android:layout_width="320dp"-->
        <!--android:layout_height="wrap_content"-->
        <!--android:layout_marginLeft="10dp"-->
        <!--android:layout_marginTop="10dp"-->
        <!--android:id="@+id/searchview"/>-->

    <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="@android:color/white" />

</LinearLayout>

SlidingTab.class(实现 SearchView)

public class SlidingTab extends Fragment {
    private static final String TAG = "TabLayout";
    private static String POSITION = "POSITION";
    private Context context;
    private SearchView searchview;
    private Toolbar toolbar ;


    /*searching/filteration query*/
    private SearchView.OnQueryTextListener OnQuerySearchView = new SearchView.OnQueryTextListener() {

        @Override
        public boolean onQueryTextSubmit(String arg0) {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public boolean onQueryTextChange(String arg0) {
            // TODO Auto-generated method stub
//            if (searchCheck) {
            Log.i("Recycler query", arg0);

//            Fragment frag = new PageAdapter(getChildFragmentManager(),context).getItem(viewPager.getCurrentItem());
            PageAdapter adapter = ((PageAdapter) viewPager.getAdapter());
            Fragment fragment = adapter.getFragment(viewPager.getCurrentItem());
            return false;
        }
    };

    public SlidingTab() {
    }
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.sliding_tab, container, false);
         viewPager = (ViewPager) v.findViewById(R.id.view_pager);
        viewPager.setOffscreenPageLimit(2);
        viewPager.setAdapter(new PageAdapter(getChildFragmentManager(), context));
        slidingTab = (TabLayout) v.findViewById(R.id.sliding_tabs);
        searchview = (SearchView)v.findViewById(R.id.searchView);
        searchview.setOnQueryTextListener(OnQuerySearchView);
        return v;
    }

PageAdapter.class

public class PageAdapter extends FragmentStatePagerAdapter {
    private static final String TAG = "PageAdapter";
    final int PAGE_COUNT = 3;
    private String tabTitles[] = new String[]{"New", "In Progress", "Completed"};
    private Context context;

    public PageAdapter(FragmentManager fm, Context context) {
        super(fm);
        this.context = context;
    }


    @Override
    public Fragment getItem(int position) {
        Log.d(TAG, "New Instance Created :" + position);
        switch (position) {
            case 0:
                return new JobFragment();

            case 1:
                return new InProgressJobFragment();
            case 2:
                return new CompletedJobFragment();
        }
        return null;
    }


    @Override
    public CharSequence getPageTitle(int position) {
        return tabTitles[position];
    }
    @Override
    public int getCount() {
        return PAGE_COUNT;
    }


}

Fragment RecyclerView Adapter(视图分页器中的每个片段调用并具有searchview过滤方法)

public class JobAdapter extends RecyclerView.Adapter<JobAdapter.ViewHolder> {
    private static final String TAG = "EMPLOYEE ADAPTER";
    private static final int VIEW_NORMAL = 0;
    private ArrayList<Info> mDataset;
    private ArrayList<Info> filterList;
    private Context mAct;

    public class ViewHolder extends RecyclerView.ViewHolder {

        }
    }

    public void addApplications(ArrayList<Info> candidates) {
      }

    public void clearApplications() {
     }

    public JobAdapter(ArrayList<Info> myDataset, Context context) {
        this.mDataset = myDataset;
        this.mAct = context;
    }



    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.job_card_new, parent, false);
        ViewHolder fh = new ViewHolder(v);
        return fh;
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, final int position) {

//      }



**//    *searching/filtration on List*/**
    public void filter(String charText) {
        filterList.clear();
        if (charText.length() == 0) {
            if(mDataset != null) {
                filterList.addAll(mDataset);
            }
        } else {
            if (mDataset != null){
                for (Info wp : mDataset) {
                    if(wp.jobNumber !=null){
                        if(Pattern.compile(Pattern.quote(charText), Pattern.CASE_INSENSITIVE).matcher(wp.jobNumber).find()){
//                    if (wp.heading1.toLowerCase().contains(charText.toLowerCase())) {
                            filterList.add(wp);
                        }}else{

                    }

                    this.notifyItemRangeRemoved(0, filterList.size());

                }
            }
        }
        notifyDataSetChanged();
    }


    @Override
    public int getItemCount() {
        return mDataset.size();
    }
}

请帮助我在 viewpager 中实现 searchview。

【问题讨论】:

    标签: android android-fragments android-viewpager android-recyclerview


    【解决方案1】:

    借助上传的代码 我能看出来

    在名为 search 和 调用适配器过滤方法

    public void search(String text)
    {
    adapter.filter(text)
    }
    

    您可以在此行之后检查片段的实例并调用片段的搜索方法

     Fragment fragment = adapter.getFragment(viewPager.getCurrentItem());
    

    【讨论】:

    • 我就是这么做的。 public boolean onQueryTextChange(final String arg0) { Log.i("Recycler query", arg0); int id = viewPager.getCurrentItem(); PageAdapter 适配器 = ((PageAdapter) viewPager.getAdapter());片段片段 = adapter.getFragment(viewPager.getCurrentItem()); if(JobFragment 的片段实例){ ((JobFragment) 片段).recycleAdapter.filter(arg0); }但我收到错误:在 NULL 对象上调用过滤器方法。
    • 不,还是不行。每次我打电话时,我的适配器都会为空。
    • 可以上传JobFragment类的代码吗?所以我可以检查为什么适配器会为空
    • 我接受了你的回答,因为它真的很有帮助。非常感谢。此外,如果您支持这个问题,那就太好了。
    • @youund_08 随时提供帮助:)
    【解决方案2】:

    我认为最好的设计是使用Activity 作为需要去片段的事件的中心“中心”。

    所以我会这样做:

    • 首先从一个监听器接口开始。这可以声明为Activity的内部接口:

      static interface QueryListener {
      
          void onQueryChange(String query);
      }
      
    • Activity 获取用于保存侦听器的属性以及用于添加和删除侦听器的方法(声明为同步以防止那些讨厌的ConcurrentModificationExceptions:

      private List<QueryListener> mQueryListeners = new ArrayList<>();
      
      public synchronized void addQueryListener(@NonNull QueryListener listener) {
      
         // check if the listener was already added
         // you could also use a Set instead of a List for this
         if (mQueryListeners.contains(listener)) return;   
      
         mQueryListeners.add(listener);
      }
      
      public synchronized void removeQueryListener(@NonNull QueryListener listener) {
          mQueryListeners.remove(listener);
      }
      
    • Activity 还获得了一个可以被带有SearchView 的片段调用的方法:

      public synchronized void changeQuery(String query) {
      
              for (QueryListener listener : mQueryListeners) {
                  listener.onQueryChange(query);
              }
      }
      
    • 现在您的带有适配器的片段需要实现 QueryListener 并自行注册/注销:

      onCreate()的某处添加这一行:

              ((YourActivity) getActivity()).addQueryListener(this);
      

      onDestroy()取消注册:

          @Override
          public void onDestroy() {
              ((YourActivity) getActivity()).removeQueryListener(this);
              super.onDestroy();
          }
      

      添加 QueryListener 方法实现:

      @Override
      public void onQueryChange(String query) {
      
          // if (isVisible()) {      if desired
          mAdapter.filter(query);
      }
      

      注意:你不必让片段实现QueryListener;您可以使用匿名类。但您必须保留对它的引用,以便稍后调用removeQueryListener()

    • 现在只需连接SearchView:

      @Override
      public boolean onQueryTextChange(String query) {
      
          ((YourActivity) getActivity()).changeQuery(query);
      }
      

    我使用的另一种模式是创建一个专用类来注册/通知侦听器。我创建了这个类的一个实例,并在 Activity 上有一个方法来访问它:

            QueryHandler handler = ((YourActivity) getActivity()).getQueryHandler();
            // QueryHandler has all the listener properties and methods shown for the Activity
    
            ...
    
            handler.changeQuery(query);
    

    或者,您也可以使用众多开源事件总线包之一,例如 Otto,在片段之间传递事件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多