当我回到片段时防止重复项目
Prevent repeating of items when i back to fragment
在我的应用程序中,我有包含 3 个片段(主页、个人资料等)的 ViewPager
Home Fragment
包含 RecyclerView
当我从 Home Fragment
导航到 Profile Fragment
或 More Fragment
时,它按预期工作。
但是当我导航回 Home Fragment
时,RecyclerView 中的项目重复...
当我再次导航并返回时,它再次重复
这是我的MainActivity.java代码:
public class MainActivity extends AppCompatActivity {
TabLayout mainTabLayout;
ViewPager mainViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainTabLayout = findViewById(R.id.main_tablayout);
mainViewPager = findViewById(R.id.main_viewpager);
mainTabLayout.setupWithViewPager(mainViewPager);
//to put mainTabLayout Icons...
MainTabLayoutIcons();
}
//to Change MainLayout Icons...
private void MainTabLayoutIcons() {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
// add fragments to the adapter
adapter.addFragment(new Home());
adapter.addFragment(new MyActivity());
adapter.addFragment(new More());
mainViewPager.setOffscreenPageLimit(0);
mainViewPager.setAdapter(adapter);
// Select Home tab as default tab on startup
mainViewPager.setCurrentItem(0);
mainTabLayout.getTabAt(0).select();
// Set tabs Initial icons
mainTabLayout.getTabAt(0).setIcon(R.drawable.home_black);
mainTabLayout.getTabAt(1).setIcon(R.drawable.user_outline);
mainTabLayout.getTabAt(2).setIcon(R.drawable.more_outline);
/* tabSelectedListener to change the icon color once it is selected
// and change it back once another tab is selected */
mainTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
if (tab.getPosition() == 0) {
mainTabLayout.getTabAt(0).setIcon(R.drawable.home_black);
mainTabLayout.getTabAt(1).setIcon(R.drawable.user_outline);
mainTabLayout.getTabAt(2).setIcon(R.drawable.more_outline);
}
if (tab.getPosition() == 1) {
mainTabLayout.getTabAt(0).setIcon(R.drawable.home_outline);
mainTabLayout.getTabAt(1).setIcon(R.drawable.user_);
mainTabLayout.getTabAt(2).setIcon(R.drawable.more_outline);
}
if (tab.getPosition() == 2) {
mainTabLayout.getTabAt(0).setIcon(R.drawable.home_outline);
mainTabLayout.getTabAt(1).setIcon(R.drawable.user_outline);
mainTabLayout.getTabAt(2).setIcon(R.drawable.more_black);
}
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
//no need for it
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
//no need for it
}
});
}
}
这里是 ViewPagerAdapter 代码:
//Adapter for mainActivity ...
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
private final List<Fragment> fragmentList = new ArrayList<>();
public ViewPagerAdapter(@NonNull FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
@Override
public int getCount() {
return fragmentList.size();
}
public void addFragment(Fragment fragment) {
fragmentList.add(fragment);
}
}
这是第一个片段Home.java代码:
public class Home extends Fragment {
View v;
public SwipeRefreshLayout mSwipeRefreshLayout;
public RecyclerView mainRecyclerView;
private LinearLayoutManager linearLayoutManager;
public final List<MyActivityModel> mainPosts = new ArrayList<>();
private PostAdapter mAdapter;
public Home() {
/*Required Empty Constructor... */
}
@Override
public View onCreateView(LayoutInflater layoutInflater, ViewGroup container, Bundle bundle) {
v = layoutInflater.inflate(R.layout.fragment_home, container, false);
mSwipeRefreshLayout = (SwipeRefreshLayout) v.findViewById(R.id.mainSwipeRefresh);
mainRecyclerView = (RecyclerView) v.findViewById(R.id.MainRecyclerView);
linearLayoutManager = new LinearLayoutManager(getActivity());
mainRecyclerView.setLayoutFrozen(true);
mainRecyclerView.setNestedScrollingEnabled(false);
mainRecyclerView.setLayoutManager(linearLayoutManager);
mAdapter = new PostAdapter(mainPosts);
mainRecyclerView.setAdapter(mAdapter);
Swipe();
LoadPosts();
return v;
}
/**
* -----------------TODO: to load posts in Home RecyclerView...----------------
*/
public void LoadPosts() {
Query database = FirebaseDatabase.getInstance().getReference().child("Posts");
database.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {
if (snapshot.exists()) {
MyActivityModel post = snapshot.getValue(MyActivityModel.class);
mainPosts.add(0, post);
mAdapter.notifyDataSetChanged();
}
}
@Override
public void onChildChanged(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {
}
@Override
public void onChildRemoved(@NonNull DataSnapshot snapshot) {
}
@Override
public void onChildMoved(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
}
private void Swipe() {
//to refresh page after swipe
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
try {
mainPosts.clear();
LoadPosts();
mSwipeRefreshLayout.setRefreshing(false);
Toast.makeText(v.getContext(),"Refreshed", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
mSwipeRefreshLayout.setRefreshing(false);
}
}
}, 500);
}
});
}
}
这是an image showing item reeating
任何人都可以帮助我如何防止这种重复...
您可能需要使用 FragmentPagerAdapter 而不是 FragmentStatePagerAdapter。此外,将 mainRecyclerView.setLayoutFrozen(true);
设置为 false,因为它会停止 recyclerView 中的所有内容。
什么时候需要使用FragmentPagerAdapter?
FragmentStatePagerAdapter is more useful when there are a large number
of pages, working more like a list view. When pages are not visible to
the user, their entire fragment may be destroyed, only keeping the
saved state of that fragment. This allows the pager to hold on to
much less memory associated with each visited page as compared to
FragmentPagerAdapter at the cost of potentially more overhead when
switching between pages.
FragmentPagerAdapter 示例:
class viewpager_class extends FragmentPagerAdapter {
int tabcount;
public viewpager_class(@NonNull FragmentManager fm, int tab_count) {
super(fm, tab_count);
this.tabcount = tab_count;
}
@NonNull
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
Fragment1 fragment1 = new Fragment1 ();
return todayBAFragment;
case 1:
Fragment2 fragment2 = new Fragment2 ();
return todayReminderDue;
case 2:
Fragment3 fragment3 = new Fragment3 ();
return currentTransaction;
default:
return null;
}
}
@Override
public int getCount() {
return tabcount;
}
}
此外,将适配器设置到 ViewPager 中,只要你想显示 viewPager:
//set adapter into viewpager
viewpager_class viewpagerClass = new viewpager_class(getChildFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(viewpagerClass);
viewPager.setOffscreenPageLimit(2);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
在我的应用程序中,我有包含 3 个片段(主页、个人资料等)的 ViewPager
Home Fragment
包含 RecyclerView
当我从 Home Fragment
导航到 Profile Fragment
或 More Fragment
时,它按预期工作。
但是当我导航回 Home Fragment
时,RecyclerView 中的项目重复...
当我再次导航并返回时,它再次重复
这是我的MainActivity.java代码:
public class MainActivity extends AppCompatActivity {
TabLayout mainTabLayout;
ViewPager mainViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainTabLayout = findViewById(R.id.main_tablayout);
mainViewPager = findViewById(R.id.main_viewpager);
mainTabLayout.setupWithViewPager(mainViewPager);
//to put mainTabLayout Icons...
MainTabLayoutIcons();
}
//to Change MainLayout Icons...
private void MainTabLayoutIcons() {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
// add fragments to the adapter
adapter.addFragment(new Home());
adapter.addFragment(new MyActivity());
adapter.addFragment(new More());
mainViewPager.setOffscreenPageLimit(0);
mainViewPager.setAdapter(adapter);
// Select Home tab as default tab on startup
mainViewPager.setCurrentItem(0);
mainTabLayout.getTabAt(0).select();
// Set tabs Initial icons
mainTabLayout.getTabAt(0).setIcon(R.drawable.home_black);
mainTabLayout.getTabAt(1).setIcon(R.drawable.user_outline);
mainTabLayout.getTabAt(2).setIcon(R.drawable.more_outline);
/* tabSelectedListener to change the icon color once it is selected
// and change it back once another tab is selected */
mainTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
if (tab.getPosition() == 0) {
mainTabLayout.getTabAt(0).setIcon(R.drawable.home_black);
mainTabLayout.getTabAt(1).setIcon(R.drawable.user_outline);
mainTabLayout.getTabAt(2).setIcon(R.drawable.more_outline);
}
if (tab.getPosition() == 1) {
mainTabLayout.getTabAt(0).setIcon(R.drawable.home_outline);
mainTabLayout.getTabAt(1).setIcon(R.drawable.user_);
mainTabLayout.getTabAt(2).setIcon(R.drawable.more_outline);
}
if (tab.getPosition() == 2) {
mainTabLayout.getTabAt(0).setIcon(R.drawable.home_outline);
mainTabLayout.getTabAt(1).setIcon(R.drawable.user_outline);
mainTabLayout.getTabAt(2).setIcon(R.drawable.more_black);
}
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
//no need for it
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
//no need for it
}
});
}
}
这里是 ViewPagerAdapter 代码:
//Adapter for mainActivity ...
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
private final List<Fragment> fragmentList = new ArrayList<>();
public ViewPagerAdapter(@NonNull FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
@Override
public int getCount() {
return fragmentList.size();
}
public void addFragment(Fragment fragment) {
fragmentList.add(fragment);
}
}
这是第一个片段Home.java代码:
public class Home extends Fragment {
View v;
public SwipeRefreshLayout mSwipeRefreshLayout;
public RecyclerView mainRecyclerView;
private LinearLayoutManager linearLayoutManager;
public final List<MyActivityModel> mainPosts = new ArrayList<>();
private PostAdapter mAdapter;
public Home() {
/*Required Empty Constructor... */
}
@Override
public View onCreateView(LayoutInflater layoutInflater, ViewGroup container, Bundle bundle) {
v = layoutInflater.inflate(R.layout.fragment_home, container, false);
mSwipeRefreshLayout = (SwipeRefreshLayout) v.findViewById(R.id.mainSwipeRefresh);
mainRecyclerView = (RecyclerView) v.findViewById(R.id.MainRecyclerView);
linearLayoutManager = new LinearLayoutManager(getActivity());
mainRecyclerView.setLayoutFrozen(true);
mainRecyclerView.setNestedScrollingEnabled(false);
mainRecyclerView.setLayoutManager(linearLayoutManager);
mAdapter = new PostAdapter(mainPosts);
mainRecyclerView.setAdapter(mAdapter);
Swipe();
LoadPosts();
return v;
}
/**
* -----------------TODO: to load posts in Home RecyclerView...----------------
*/
public void LoadPosts() {
Query database = FirebaseDatabase.getInstance().getReference().child("Posts");
database.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {
if (snapshot.exists()) {
MyActivityModel post = snapshot.getValue(MyActivityModel.class);
mainPosts.add(0, post);
mAdapter.notifyDataSetChanged();
}
}
@Override
public void onChildChanged(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {
}
@Override
public void onChildRemoved(@NonNull DataSnapshot snapshot) {
}
@Override
public void onChildMoved(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
}
private void Swipe() {
//to refresh page after swipe
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
try {
mainPosts.clear();
LoadPosts();
mSwipeRefreshLayout.setRefreshing(false);
Toast.makeText(v.getContext(),"Refreshed", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
mSwipeRefreshLayout.setRefreshing(false);
}
}
}, 500);
}
});
}
}
这是an image showing item reeating
任何人都可以帮助我如何防止这种重复...
您可能需要使用 FragmentPagerAdapter 而不是 FragmentStatePagerAdapter。此外,将 mainRecyclerView.setLayoutFrozen(true);
设置为 false,因为它会停止 recyclerView 中的所有内容。
什么时候需要使用FragmentPagerAdapter?
FragmentStatePagerAdapter is more useful when there are a large number of pages, working more like a list view. When pages are not visible to the user, their entire fragment may be destroyed, only keeping the saved state of that fragment. This allows the pager to hold on to much less memory associated with each visited page as compared to FragmentPagerAdapter at the cost of potentially more overhead when switching between pages.
FragmentPagerAdapter 示例:
class viewpager_class extends FragmentPagerAdapter {
int tabcount;
public viewpager_class(@NonNull FragmentManager fm, int tab_count) {
super(fm, tab_count);
this.tabcount = tab_count;
}
@NonNull
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
Fragment1 fragment1 = new Fragment1 ();
return todayBAFragment;
case 1:
Fragment2 fragment2 = new Fragment2 ();
return todayReminderDue;
case 2:
Fragment3 fragment3 = new Fragment3 ();
return currentTransaction;
default:
return null;
}
}
@Override
public int getCount() {
return tabcount;
}
}
此外,将适配器设置到 ViewPager 中,只要你想显示 viewPager:
//set adapter into viewpager
viewpager_class viewpagerClass = new viewpager_class(getChildFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(viewpagerClass);
viewPager.setOffscreenPageLimit(2);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));