【问题标题】:Fragments overlapping in AndroidAndroid中的片段重叠
【发布时间】:2020-03-15 09:41:55
【问题描述】:

我正在尝试在片段之间切换而不丢失以前的内容,所以我决定实现这种方式来做到这一点:

private void loadFragment(Fragment fragment) {
    FragmentManager fragmentManager = getSupportFragmentManager();
    fragmentManager.beginTransaction().hide(fragment);
    if (!alreadyOpened[currentIndex]) {
        alreadyOpened[currentIndex] = true;
        fragmentManager.beginTransaction().add(R.id.fragment_container,fragment).commit();
    } else {
        fragmentManager.beginTransaction().show(fragment).commit();
    }
}

使用这个方法,我检查一个片段是否已经打开:如果是,我显示它,如果不是,我添加它。然后我将其声明为“已经打开”。问题是当我在片段之间切换时,我看到所有三个片段都重叠。我该如何解决? 这是我调用 loadFragment 方法时的菜单栏:

private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
        = new BottomNavigationView.OnNavigationItemSelectedListener() {

    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.bbn_item1:
                currentIndex = 0;
                loadFragment(new HomeFragment());
                return true;
            case R.id.bbn_item2:
                currentIndex = 1;
                loadFragment(new PopularFragment());
                return true;
            case R.id.bbn_item3:
                 currentIndex = 2;
                loadFragment(new PlayingFragment());
                return true;
        }
        return false;
    }
};

编辑:新代码

List<Fragment> fragments = new ArrayList<>();

private void loadFragment(Fragment fragment) {
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    if (alreadyOpened[currentIndex]) {
        ft.replace(R.id.fragment_container, fragments.get(currentIndex));
    } else {
        fragments.add(currentIndex, fragment);
        alreadyOpened[currentIndex] = true;
        ft.replace(R.id.fragment_container, fragment);
    }
    ft.addToBackStack(null);
    ft.commit();
}

【问题讨论】:

    标签: java android android-fragments fragment overlapping


    【解决方案1】:

    您不应该在每次导航点击时都创建新的片段。在某处创建一次并将它们保存在List&lt;Fragment&gt; fragments 数组中。然后使用fragmentManager.beginTransaction().replace(R.id.fragment_layout, fragment); 这是一个小例子:

        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_left); //optional 
        ft.replace(R.id.fragment_layout, fragments.get(selectedFragment));
        ft.addToBackStack(null);
        ft.commit();
    

    从您的onNavigationItemSelected 发送selectedFragment 变量,并匹配fragments 列表中的位置。

    编辑: 这个怎么样:

    public HomeFragment homeFragment;
    public PopularFragment popularFragment;
    public PlayingFragment playingFragment;
    
    private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
        = new BottomNavigationView.OnNavigationItemSelectedListener() {
    
    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.bbn_item1:
               if(homeFragment == null){ homeFragment  =new HomeFragment();}
               loadFragment(homeFragment )
                return true;
            case R.id.bbn_item2:
                if(homeFragment == null){ popularFragment  =new PopularFragment();}
                loadFragment(popularFragment)
                return true;
            case R.id.bbn_item3:
                 if(homeFragment == null){ playingFragment  =new PlayingFragment();}
                loadFragment(playingFragment);
                return true;
        }
        return false;
    }
    

    };

    public void loadFragment(Fragment fragment){
      FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_left); //optional 
        ft.replace(R.id.fragment_layout, fragment);
        ft.addToBackStack(null);
        ft.commit();
    
    }
    

    【讨论】:

    • 使用这种方法,我不会在切换之前恢复我在片段中所做的事情,对吧?例如:我有一个片段,用户可以在其中搜索项目。如果我切换片段,我会丢失找到的项目列表并返回搜索栏。这是我想要避免的
    • 我相信是的。调用片段的 OnCreate 函数,然后您正在创建新片段,例如: new MyFragment() 不是当您使用 FragmentTransaction 绑定布局时。所以你不应该失去你的进步。试试看,如果你松了,我们也可以解决它。
    • 我用新代码更新了问题,不幸的是没有任何改变
    • 它不断刷新片段的内容。
    • 我不知道我有相同的工作版本,它甚至不会刷新 recyclerview 内容。你想要什么样的内容?
    猜你喜欢
    • 2014-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-18
    • 1970-01-01
    • 2020-03-23
    • 1970-01-01
    相关资源
    最近更新 更多