Android 如何处理旋转屏幕并将数据保存在片段中?
我有3个片段(片段Home、片段A、片段B和片段C)。应用程序首次运行时将显示片段主页(在Mainactivity中设置)。从导航绘图项可以选择每个片段。每个选定项目都将显示详细信息片段 我在处理数据和保留片段时遇到问题:Android 如何处理旋转屏幕并将数据保存在片段中?,android,android-fragments,fragment,android-fragmentactivity,screen-orientation,Android,Android Fragments,Fragment,Android Fragmentactivity,Screen Orientation,我有3个片段(片段Home、片段A、片段B和片段C)。应用程序首次运行时将显示片段主页(在Mainactivity中设置)。从导航绘图项可以选择每个片段。每个选定项目都将显示详细信息片段 我在处理数据和保留片段时遇到问题: (1). 当我选择一个片段(例如片段a)时,将显示片段a的页面。但是当我旋转设备时,为什么我的片段返回到片段主页而不是停留在当前片段?如何处理它? (2). 在片段B中,我在GridView中显示图像。但是,当我旋转设备时,为什么我的片段返回到片段主页而不是停留在当前片段?
(1). 当我选择一个片段(例如片段a)时,将显示片段a的页面。但是当我旋转设备时,为什么我的片段返回到片段主页而不是停留在当前片段?如何处理它?
(2). 在片段B中,我在GridView中显示图像。但是,当我旋转设备时,为什么我的片段返回到片段主页而不是停留在当前片段?如何处理它并仍然使用现有数据显示此片段?
这是我的代码:
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
private static final String LOG_TAG = MainActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
displaySelectedItem(R.id.nav_home);
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
displaySelectedItem(item.getItemId());
return true;
}
private void displaySelectedItem (int itemId) {
Fragment fragment = null;
switch (itemId){
case R.id.nav_home:
fragment = new FragmentHome();
break;
case R.id.nav_a:
fragment = new FragmentA();
break;
case R.id.nav_b:
fragment = new FragmentB();
break;
case R.id.nav_c:
fragment = new FragmentC();
break;
case R.id.nav_d:
fragment = new FragmentD();
break;
}
FragmentManager fragmentManager = MainActivity.this.getSupportFragmentManager();
List<Fragment> fragments = fragmentManager.getFragments();
if (fragments != null) {
for(Fragment f : fragments){
fragmentManager.popBackStack();
}
}
//replace the fragment
if (fragment != null) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, fragment, "TAG_FRAGMENT");
fragmentTransaction.commit();
}
DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
drawerLayout.closeDrawer(GravityCompat.START);
}
片段B:
public class FragmentB extends Fragment {
private static final String LOG_TAG = FragmentB.class.getSimpleName();
private ImageAdapter imageAdapter;
private ArrayList<Movie> movieList;
public FragmentNowPlaying() {
super();
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_b, container, false);
GridView gridView = (GridView) rootView.findViewById(R.id.gridviewNowPlaying);
imageAdapter = new ImageAdapter(getContext(), R.layout.fragment_b, movieList);
if (savedInstanceState == null) {
movieList = new ArrayList<Movie>();
}else{
movieList = (ArrayList<Movie>) savedInstanceState.get("MovieList");
}
gridView.setAdapter(imageAdapter);
return rootView;
}
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putParcelableArrayList("MovieList",movieList);
super.onSaveInstanceState(outState);
}
公共类FragmentB扩展了Fragment{
私有静态最终字符串LOG_TAG=FragmentB.class.getSimpleName();
专用图像适配器;
私人电影导演;
公共碎片{
超级();
}
@凌驾
创建时的公共void(@Nullable Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setRetainInstance(真);
}
@可空
@凌驾
创建视图时的公共视图(LayoutFlater充气机、@Nullable ViewGroup容器、@Nullable Bundle savedInstanceState){
视图根视图=充气机。充气(R.layout.fragment_b,容器,false);
GridView GridView=(GridView)rootView.findViewById(R.id.gridviewNowPlaying);
imageAdapter=新的imageAdapter(getContext(),R.layout.fragment_b,movieList);
如果(savedInstanceState==null){
movieList=newarraylist();
}否则{
movieList=(ArrayList)savedInstanceState.get(“movieList”);
}
setAdapter(imageAdapter);
返回rootView;
}
@凌驾
SaveInstanceState上的公共无效(束超出状态){
杰出的电影艺术家(MovieList,MovieList);
super.onSaveInstanceState(超出状态);
}
您需要覆盖片段A和B中的OnConfiguration Changed(Configuration newConfig)
方法,以便在应用程序配置更改时告诉它们留在那里。例如:
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// get current fragment
Fragment fragment = mAdapter.getItem(currentItem);
if(fragment!=null){
fragment.onResume();
}
}
因为每次旋转屏幕时都会调用onCreate()方法 解决问题 在onCreate()方法中,检查savedInstanceState()是否为null
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(null == savedInstanceState){
//set you initial fragment object
}
else
{
//Load the fragment by tag
}
}
并在所有片段中保存onPause()之前的实例状态
@Override
protected void onSaveInstanceState(Bundle bundle1)
{
super.onSaveInstanceState(bundle1); Log.i(tag,"inside onSaveInstanceState");
bundle1.putInt("tag",n);
}
已解决此问题。在MainActivity中添加以下内容:
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(STATE_SELECTED_POSITION, mCurrentSelectedPosition);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION, 0);
Menu menu = navigationView.getMenu();
menu.getItem(mCurrentSelectedPosition).setChecked(true);
}
在每个片段中添加条件以检查savedInstanceState是否为null
谢谢大家尝试在片段中设置
setRetainInstance(true)
@emdadhosain已经尝试了,但仍然无法。您能举一些例子吗?
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(STATE_SELECTED_POSITION, mCurrentSelectedPosition);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION, 0);
Menu menu = navigationView.getMenu();
menu.getItem(mCurrentSelectedPosition).setChecked(true);
}