在 2 个片段之间切换而不是每次都重新创建它们解决方案不起作用? - 安卓工作室(Java)

问题描述 投票:0回答:1

我一直在努力让我的 Android 应用程序能够做到这一点,当您在片段之间切换时,它会保留您在片段中完成的操作。我希望能够在片段之间切换而无需重新创建或替换它们,只需显示和隐藏它们。例如,如果您在片段 1 中选中了一个框,但切换到片段 2,然后又回到片段 1,则仍应选中该框。我尝试实施@Tester101 这篇文章中概述的解决方案如何在两个片段之间切换,而无需每次都重新创建片段?

但我不确定我是否让它正常工作。当我从 HomeFragment 切换到 WidgetFragment 时,WidgetFragment 被放置在 HomeFragment 的顶部。

HomeFragment 看起来像这样:Text 但是当我切换到 WidgetFragment 时,它看起来像这样:Text 将 WidgetFragment 中的文本视图和复选框放置在 HomeFragment 的顶部。

package loon.si.weather_app;

import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.FragmentManager;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.view.MenuItem;

import com.google.android.material.navigation.NavigationView;

import java.util.Objects;

public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
    
    private DrawerLayout drawerLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        
        drawerLayout = findViewById(R.id.drawer_layout);
        NavigationView navigationView = findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);

        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.open_nav, R.string.close_nav);

        drawerLayout.addDrawerListener(toggle);
        toggle.syncState();

        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .replace(R.id.fragment_container, new HomeFragment()).commit();
            navigationView.setCheckedItem(R.id.nav_home);
        }

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        FragmentManager fragmentManager = getSupportFragmentManager();
        if(fragmentManager.findFragmentById(R.id.nav_home) != null){
            fragmentManager.beginTransaction().remove(Objects.requireNonNull(fragmentManager.findFragmentById(R.id.nav_home))).commit();
        }
        if(fragmentManager.findFragmentById(R.id.nav_widget) != null){
            fragmentManager.beginTransaction().remove(Objects.requireNonNull(fragmentManager.findFragmentById(R.id.nav_widget))).commit();
        }
    }

    @SuppressLint("NonConstantResourceId")
    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        switch (item.getItemId()){
            case R.id.nav_home:
                if(fragmentManager.findFragmentById(R.id.nav_home) != null) {
                    //if the fragment exists, show it.
                    fragmentManager.beginTransaction().show(Objects.requireNonNull(fragmentManager.findFragmentById(R.id.nav_home))).commit();
                } else {
                    //if the fragment does not exist, add it to fragment manager.
                    fragmentManager.beginTransaction().add(R.id.fragment_container, new HomeFragment(), "home").commit();
                }
                if(fragmentManager.findFragmentById(R.id.nav_widget) != null){
                    //if the other fragment is visible, hide it.
                    fragmentManager.beginTransaction().hide(Objects.requireNonNull(fragmentManager.findFragmentById(R.id.nav_widget))).commit();
                }
                break;

            case R.id.nav_widget:
                if(fragmentManager.findFragmentById(R.id.nav_widget) != null) {
                    //if the fragment exists, show it.
                    fragmentManager.beginTransaction().show(Objects.requireNonNull(fragmentManager.findFragmentById(R.id.nav_widget))).commit();
                } else {
                    //if the fragment does not exist, add it to fragment manager.
                    fragmentManager.beginTransaction().add(R.id.fragment_container, new WidgetFragment(), "widget").commit();
                }
                if(fragmentManager.findFragmentById(R.id.nav_home) != null){
                    //if the other fragment is visible, hide it.
                    fragmentManager.beginTransaction().hide(Objects.requireNonNull(fragmentManager.findFragmentById(R.id.nav_home))).commit();
                }
                break;
        }
        drawerLayout.closeDrawer(GravityCompat.START);
        return true;
    }

    @Override
    public void onBackPressed() {
        if (drawerLayout.isDrawerOpen(GravityCompat.START)){
            drawerLayout.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }
}
java android android-studio android-fragments android-fragment-manager
1个回答
0
投票
  1. 要在片段之间切换时保留片段的状态,需要使用 FragmentTransaction 类的 addToBackStack 方法。此方法将当前片段添加到返回堆栈,这允许用户通过按后退按钮导航回上一个片段。

transaction.addToBackStack(null).commit(); drawerLayout.closeDrawer(GravityCompat.START);

  1. 使用 findFragmentByTag 方法通过标签名称而不是 ID 查找片段,因为标签名称是唯一的,并且在片段隐藏或显示时不会改变。

if(fragmentManager.findFragmentByTag("home") != null) { transaction.show(Objects.requireNonNull(fragmentManager.findFragmentByTag("home"))); } 别的 { transaction.add(R.id.fragment_container, new HomeFragment(), "home"); } 如果(fragmentManager.findFragmentByTag(“小部件”)!= null) { transaction.hide(Objects.requireNonNull(fragmentManager.findFragmentByTag("widget"))); } 休息;

© www.soinside.com 2019 - 2024. All rights reserved.