【发布时间】:2020-07-14 04:52:36
【问题描述】:
我有一个带有 TabLayout 的活动和两个代表选项卡内容的片段。 我在我的活动的 OnCreate 方法中手动管理打开的选项卡的当前状态:
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import com.google.android.material.tabs.TabLayout;
public class LoginActivity extends AppCompatActivity {
private TabLayout tabLayout;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
tabLayout = findViewById(R.id.tabLayout);
//initialize or restore opened tab, after activity first started or recreated
int tabIndex = savedInstanceState == null ? 0 : savedInstanceState.getInt("tabIndex");
Fragment f;
switch (tabIndex) {
case 0:
f = new SignInFragment();
break;
case 1:
f = new SignUpFragment();
break;
default:
throw new UnsupportedOperationException();
}
//sync tab indicator
tabLayout.selectTab(tabLayout.getTabAt(tabIndex));
//set opened fragment
getSupportFragmentManager().beginTransaction()
.replace(R.id.tabContent, f)
.commit();
//add listener to handle tab switching
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
Fragment tabFragment;
switch (tab.getPosition()) {
case 0:
tabFragment = new SignInFragment();
break;
case 1:
tabFragment = new SignUpFragment();
break;
default:
throw new UnsupportedOperationException();
}
getSupportFragmentManager().beginTransaction()
.setCustomAnimations(com.google.android.material.R.anim.abc_grow_fade_in_from_bottom, com.google.android.material.R.anim.abc_shrink_fade_out_from_bottom)
.replace(R.id.tabContent, tabFragment)
.commit();
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("tabIndex", tabLayout.getTabAt(tabLayout.getSelectedTabPosition()).getPosition());
}
}
这只是简单的示例。我的真实代码是用 C# 编写的,还有一些其他逻辑来存储和管理活动重启之间的状态。
配置改变时的问题(例如开关方向):
- 打开的片段被破坏
- 活动被破坏
- 活动已重新启动
- 在 onCreate 方法中,当调用 super.onCreate(savedInstanceState) 片段管理器时,使用默认(无参数)构造函数重新创建片段(在步骤 1 中销毁)。
- 我在 onCreate 方法中的代码恢复被破坏的片段。因此,片段管理器重新创建的片段被销毁并替换为我在此步骤中创建的片段。
如何避免这种行为?我不需要片段管理器恢复的片段。我也不需要片段的默认构造函数(我有一些自定义 ViewModel 通过托管活动的构造函数注入片段)
把 null 放到 super.onCreate() 中?我认为这不是很好的解决方案...
附:我知道 ViewPager 和 ViewPager2 来管理 TabLayout 的选项卡。 ViewPager 已弃用。使用 ViewPager2 我有一个奇怪的错误:第一个选项卡(在 0 索引处)工作正常,但在第二个选项卡中我无法专注于任何输入(单击输入并立即失去焦点,不知道为什么)。
【问题讨论】:
标签: android android-fragments android-lifecycle