【问题标题】:android fragment destroyed after home or overview buttons are pressed按下主页或概览按钮后,android片段被破坏
【发布时间】:2017-06-28 15:56:21
【问题描述】:

我对 android 编程相当陌生,所以请多多包涵。我已经尝试过搜索 SO、tutorialspoint、big nerd 牧场等,但我没有找到/理解这一点:如何在用户按下主页或概览按钮后使片段持续存在?例如:

我在一个活动中有两个片段 A 和 B,带有一个用于在两个片段之间切换的切换按钮。默认情况下,在创建活动时,片段 A 会加载到屏幕上。如果我切换到片段 B 并按主页或概览,然后返回应用程序,则会显示片段 A。我明白它为什么显示,但我不明白如何保持片段 B 显示。

我已经阅读了有关 backstack、savedInstanceState 和 setRetainInstance(以及其他几个)的信息,但无法弄清楚。

我将在两个片段中覆盖onAttach(Context context)onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState)onViewCreated(View view, Bundle savedInstanceState),并在我的活动中覆盖onStart()onCreate(Bundle savedInstanceState)

片段:

@Override
public void onAttach(Context context) {
    this.context = context;
    faContext = (FragmentActivity) context;

    super.onAttach(context);
}// end onAttach(Activity activity)


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
    Bundle bundle = this.getArguments();

    if(bundle != null) {
        String bundleAdminId = getString(R.string.bundle_admin_name);
        adminName = bundle.getString(bundleAdminId);
    }
    else {
        Log.d("BUNDLE_Profile", "bundle is null");
    }

    // Defines the xml file for the fragment
    return inflater.inflate(R.layout.fragment_profile, parent, false);
}// end onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState)

onViewCreated 只有按钮事件处理程序

活动:

@Override
public void onStart() {
    super.onStart();

    // start the home fragment
    createFragment(new HomeFragment(), R.id.frag_container);

    // update the local storage
}// end onStart()


private void createFragment(Fragment fragment, int fragContainerId) {
    // make sure the passed fragment isn't null
    if(fragment != null) {
        FragmentTransaction ft = faContext.getSupportFragmentManager().beginTransaction();
        ft.replace(fragContainerId, fragment);
        ft.commit();
    }
}// end createFragment(Fragment fragment)`

onCreate 也有按钮处理程序

【问题讨论】:

  • 为什么不在 OnCreate 方法中创建片段?

标签: android android-fragments


【解决方案1】:

使用标签打开片段。试试这个功能

public void openNewFragment(Fragment f, String tag) {

    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    Fragment fragment = getSupportFragmentManager().findFragmentByTag(tag);
    {
        if (fragment != null) {
            if (currentFragment != null) {
                if (fragment.getClass().equals(currentFragment.getClass())) {
                    drawerLayout.closeDrawers();
                    return;
                }
            }
            ft.show(fragment);
            ft.hide(currentFragment);
            currentFragment = fragment;
        } else {
            if (currentFragment != null)
                ft.hide(currentFragment);
            ft.add(R.id.container, f, tag);
            currentFragment = f;
        }
        ft.commit();


    }
}

在此函数中,您必须提供片段名称及其标签。

【讨论】:

    【解决方案2】:

    重新启动应用程序时,您不能保留片段位置,除非它被存储。因此,一种方法是在片段之间切换时,将片段的当前位置存储在 Shared Preference 中。重新启动应用程序时读取先前存储的片段位置并在切换时更新 SharedPreferences 值。

            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
    
    
                sharedPreferences = getSharedPreferences("fragmentPosition",MODE_PRIVATE);
    
                if(sharedPreferences.getInt("position",0)==1) loadFragmentOne();
                else loadFragmentTwo();
           }
    
           public void onToggleMethod(){
    
               if(currentToggle ==1){
                  LoadFragmentTwo();
                  UpdateSharedPreference();
               }
               else{
                  loadFragmentOne();
                  UpdateSharedPreference();
               }
          }
    

    【讨论】:

    • 即使应用程序还没有完全退出?
    • 是的...它会持续到您清除共享首选项数据或清除应用程序数据
    【解决方案3】:

    很明显,当您在一段时间后从家返回活动时,活动会进入停止模式并开始。可能是因为资源被从内存中释放出来了。

    要更好地了解这一点,只需尝试在片段 b 上并立即按下主页并再次通过最近的应用部分返回应用并查看行为。

    如果问题是我上面所说的那么..尝试关注

    1. 尝试创建一个静态变量并尝试记住上次加载的片段,并在活动的恢复中加载上次加载的片段。
    2. 否则在 onstart 加载片段时,使用带有标签的片段管理器并在加载之前放置一个条件以检查片段是否已经在内存中,如果是,则不要加载任何内容。

    这样的.. onStart(){ if(fragmentManager.getFragmentByTag("String tag")== null){ createFragment(); } }

    试试看这是否有用。

    【讨论】:

    • 正确格式化代码使用{}按钮或缩进4个空格
    • 非常有用的信息!不幸的是,这不是问题。
    【解决方案4】:

    尝试像这样更改 onStart 方法,

    @Override
        public void onStart() {
            super.onStart();
            // start the home fragment
    
            if(faContext.getSupportFragmentManager().findFragmentById(R.id.frag_container) == null) {
                createFragment(new HomeFragment(), R.id.frag_container);
            }
    
            // update the local storage
        }// end onStart()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-03
      • 2014-04-25
      • 1970-01-01
      • 2018-08-12
      • 1970-01-01
      • 1970-01-01
      • 2012-05-16
      相关资源
      最近更新 更多