当我回到片段时防止重复项目

Posted

技术标签:

【中文标题】当我回到片段时防止重复项目【英文标题】:Prevent repeating of items when i back to fragment 【发布时间】:2021-10-31 08:38:59 【问题描述】:

在我的应用程序中,我的 ViewPager 包含 3 个片段(Home、Profile 等)

Home Fragment 包含 RecyclerView 当我从Home Fragment 导航到Profile FragmentMore 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

任何人都可以帮助我如何防止这种重复...

【问题讨论】:

【参考方案1】:

您可能需要使用 FragmentPagerAdapter 而不是 FragmentStatePagerAdapter。另外,将mainRecyclerView.setLayoutFrozen(true); 设置为 false,因为它会停止 recyclerView 中的所有内容。

何时需要使用 FragmentPagerAdapter?

FragmentStatePagerAdapter 在数量较多时更有用 页面,更像是一个列表视图。当页面不可见时 用户,他们的整个片段可能会被销毁,只保留 该片段的保存状态。 这允许寻呼机保持 与每个访问的页面相关联的内存要少得多 FragmentPagerAdapter 以潜在的更多开销为代价 在页面之间切换。

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));

【讨论】:

以上是关于当我回到片段时防止重复项目的主要内容,如果未能解决你的问题,请参考以下文章

导航组件防止在后按时重新创建片段

滚动回收站视图时如何防止项目重复

android键盘弹出问题

如何停止recyclerView android中的项目重复

单击recyclerview上的项目时的多个数据

带有茧栏杆的嵌套表单在编辑时会重复子项目