当前位置: 首页 > 知识库问答 >
问题:

如何处理旋转屏幕和保存碎片中的数据?

堵雅健
2023-03-14

我有3个片段(片段Home、片段A、片段B和片段C)。应用程序首次运行时将显示片段主页(在Mainactivity中设置)。从导航绘图项可以选择每个片段。每个选定项目都将显示详细信息片段。

我在处理数据和保留片段时遇到问题:

(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);
}

片段A:

public class FragmentA extends Fragment {
public FragmentA() {
    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_a, container, false);
    return rootView;
}

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    getActivity().setTitle("Fragment A");
}
}

片段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);
}

共有3个答案

孔鹤龄
2023-03-14

因为每次旋转屏幕时都会调用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
        }
  }

并将实例状态保存在所有片段中的onPaul()之前

@Override 
protected void onSaveInstanceState(Bundle bundle1)
{ 
super.onSaveInstanceState(bundle1); Log.i(tag,"inside onSaveInstanceState");      
bundle1.putInt("tag",n); 

}
公良泰宁
2023-03-14

您需要重写片段A和B中的onConfigurationChanged(Configuration newConfig)方法,以便在应用程序配置更改时告诉它们留在那里。例如:

      @Override
        public void onConfigurationChanged(Configuration newConfig) {
                super.onConfigurationChanged(newConfig);
                // get current fragment
                Fragment fragment = mAdapter.getItem(currentItem);
                if(fragment!=null){
                     fragment.onResume();
                }
        }
柳深
2023-03-14

解决了这个问题。在主活动中添加以下内容:

@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。

谢谢大家

 类似资料:
  • 我有这个活动,它包含一个片段。这个片段布局由一个包含多个片段(实际上是两个)的视图寻呼机组成。 当创建视图分页器时,它的适配器被创建,被调用,我的子片段被创建。太棒了。 现在,当我旋转屏幕时,框架处理片段的重新创建,适配器从主片段在我的中再次创建,但是从未被调用,因此我的适配器持有错误的引用(实际上为空),而不是两个片段。 我发现片段管理器(即子片段管理器)包含一个名为的片段数组,这当然是代码无法

  • 在屏幕旋转后,虽然我在super.onCreate(null);,中传递null,但我得到了object返回的nullPointerException异常。我知道在传递savedInstanceState=null的同时必须销毁并重新创建活动,这意味着活动应该在旋转后开始,因为它是第一次开始,为什么在旋转后会出现此异常? onCreate()代码段,其中名为historyText的对象 Logca

  • 实现在竖屏的NavigationController中push一个横屏的UIViewController,模拟器测试兼容5.0、6.0系统。实现程序中手动旋转屏幕的效果。 [Code4App.com]

  • 使用ASL的25.0我遇到了一些问题,比如以编程方式保存选定项(或其索引)和选定项。

  • 您好,我创建了一个带有默认“导航抽屉活动”的项目。所以我有一个MainActivity,其中有一个片段,用于替换菜单上的每个项目。 菜单之一是“客户”,显示客户列表。 从客户片段中我可以看到这个客户的利益,其中是一个调用利益的片段。 还有更多的层次,但要简短,这就足够了。 这是MainActivity上的代码,我使用它从片段中调用片段并在之间传递数据 我用的是: 问题是,当我旋转手机时,无论我的活

  • 我使用和来显示片段。最初增加了2个片段,Fragment1和Fragment2,在接收到服务器的响应后,在第二个位置增加了第三个片段Fragment3。因此,在添加所有页面之后,这应该是ViewPager中的片段序列-->Fragment1,Fragment3,fragment2。 下面是解决方案代码 代码: