在 ViewPager 中使用 RecyclerView 的异步 Firebase 任务

Asynchronous Firebase Task with RecyclerView in ViewPager


事件总线代码

EventBus.getDefault().postSticky
           (new ViewPagerAndDataSnapshotSender(dataSnapshot.child("Examples"), viewPager));

其中 ViewPagerAndDataSnapshotSender 是一个数据对象 class 我创建它是为了发送 DataSnapshot 来使用它,并发送 viewPager 来通知它有变化

@Override
public void onStart() {
    super.onStart();
    EventBus.getDefault().register(this);
    adapter.notifyDataSetChanged();
}

@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
public void onEvent(ViewPagerAndDataSnapshotSender ss) {
    fetchExamples(ss.getDataSnapshot(), ss.getViewPager());
}

@Override
public void onStop() {
    EventBus.getDefault().unregister(this);
    super.onStop();
}

ViewPagerAdapter

class ViewPagerAdapter extends FragmentPagerAdapter {
    private final List<Fragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitleList = new ArrayList<>();

    ViewPagerAdapter(FragmentManager manager) {
        super(manager);
    }

    @Override
    public Fragment getItem(int position) {
        return new ExampleRecyclerViewFragment(); // the same recycler view I want to return every pagee
    }

    @Override
    public int getCount() {
        return mFragmentTitleList.size();
    }

    void addFragment(String title) {
        //mFragmentList.add(fragment);
        mFragmentTitleList.add(title);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return mFragmentTitleList.get(position);
    }
}

ViewPager的调用(在onCreate中)

viewPager = (ViewPager) rootView.findViewById(R.id.viewpager);
TabLayout tabLayout = (TabLayout) rootView.findViewById(R.id.tabs);
setupViewPager(viewPager);
tabLayout.setupWithViewPager(viewPager);
fetchData();  // a method in which the EventBus data are set in asynchronous Firebase method

setupViewPager 方法

private void setupViewPager(ViewPager viewPager) {
        ViewPagerAdapter adapter = new ViewPagerAdapter(getFragmentManager());
        adapter.addFragment("Fragment");
        adapter.addFragment("Activity");
        //adapter.addFragment("SASDF");
        viewPager.setAdapter(adapter);
    }

ExampleRecyclerViewFragment (The RecyclerView) 我觉得错误就在这里 在 onCreate

RecyclerView exampleRecyclerView = (RecyclerView)                
rootView.findViewById(R.id.ExampleRecyclerView);
exampleList = new ArrayList<>();
adapter = new ExampleAdapter(exampleList);
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
llm.setSmoothScrollbarEnabled(true);
exampleRecyclerView.setScrollbarFadingEnabled(true);
exampleRecyclerView.setLayoutManager(llm);
exampleRecyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();

调用数据的异步

public void fetchExamples(final DataSnapshot Examples, final ViewPager viewPager2) {
    //noinspection StatementWithEmptyBody
    if (Examples.hasChild("Method 2")) {  // If has multi example

    } else {  // If has only one example

        Examples.getRef().child("Method 1").addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                example.setStepName(String.valueOf(dataSnapshot.getKey()));

                for (DataSnapshot childSnapshot : dataSnapshot.child("Code").getChildren()) {
                    example.addCode(String.valueOf(childSnapshot.getValue()));
                    //Log.i("CodeValue", String.valueOf(childSnapshot.getValue()));
                }

                for (DataSnapshot childSnapshot : dataSnapshot.child("Explaination").getChildren()) {
                    example.addExplanation(String.valueOf(childSnapshot.getValue()));
                    //Log.i("ExplanationValue", String.valueOf(childSnapshot.getValue()));
                }
                example.addExample();
                exampleList.add(example.getExampleObject());
                viewPager2.getAdapter().notifyDataSetChanged(); // viewPager by EventBus
                viewPager.getAdapter().notifyDataSetChanged(); // viewPager by static
                adapter.notifyDataSetChanged();
            }

            @Override
            public void onChildChanged(DataSnapshot dataSnapshot, String s) {

            }

            @Override
            public void onChildRemoved(DataSnapshot dataSnapshot) {

            }

            @Override
            public void onChildMoved(DataSnapshot dataSnapshot, String s) {

            }

            @Override
            public void onCancelled(FirebaseError firebaseError) {

            }
        });
    }
}

关于我在代码中遗漏的内容有什么想法吗?

提前致谢,任何其他需要Class的代码请告诉我

尝试扩展 FragmentStatePagerAdapter 而不是 FragmentPagerAdapter

并且在设置 viewpager 时 viewpager.setOfscreenPagelimit(totalPagesinViewpager);

根据您分享的代码片段,我猜您遗漏了这两件事

无数据问题:- 在从 firebase 获取示例之前,您应该显示加载动画。
只有从服务器获取数据后,您才应该在 ViewPager 中添加片段。您正在添加具有空 ArrayList 的片段。滑动到第 3 页并返回到第 1 页或将 phone 置于空闲状态,为网络调用完成和 RecyclerView 呈现数据提供足够的时间。

或者,您可以在单个片段中调用提取示例。显示加载动画直到请求完成,然后才将适配器分配给 RecyclerView。

数据重复问题:-您应该在成功完成网络调用后清除旧列表数据,然后用新数据重新填充它。您正在同一列表中添加新数据,导致数据重复。如果请求失败,显示一些错误消息但保留旧数据。

请分享整个 class 以便我可以准确指出问题所在。