在 ViewPager 中使用 RecyclerView 的异步 Firebase 任务
Asynchronous Firebase Task with RecyclerView in ViewPager
- 我正在尝试从 Firebase 加载相同的 RecylerView 数据,然后更改数据中的简单内容
- 问题: 如果是2页第一页没有数据,如果是3页pages 第一页没有出现并且启动,如果我移动到第 3 页然后回到第 1 页,数据出现 +
如果我离开 phone 一段时间,使其闲置,然后在屏幕上打开(我认为它达到
onResume
),它会显示数据,但 数据重复 (现在才注意到)
- 注意:我正在使用 EventBus GreenBot Library 传递包含 RecyclerView 数据的 DataSnapshot
- 注意:RecyclerVIew 在 class 中,ViewPager 在另一个 Class
中
事件总线代码
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 以便我可以准确指出问题所在。
- 我正在尝试从 Firebase 加载相同的 RecylerView 数据,然后更改数据中的简单内容
- 问题: 如果是2页第一页没有数据,如果是3页pages 第一页没有出现并且启动,如果我移动到第 3 页然后回到第 1 页,数据出现 +
如果我离开 phone 一段时间,使其闲置,然后在屏幕上打开(我认为它达到
onResume
),它会显示数据,但 数据重复 (现在才注意到) - 注意:我正在使用 EventBus GreenBot Library 传递包含 RecyclerView 数据的 DataSnapshot
- 注意:RecyclerVIew 在 class 中,ViewPager 在另一个 Class 中
事件总线代码
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 以便我可以准确指出问题所在。