方向变化时处理片段的简便方法


87
public class MainActivity extends Activity implements MainMenuFragment.OnMainMenuItemSelectedListener {

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

    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager
            .beginTransaction();

    // add menu fragment
    MainMenuFragment myFragment = new MainMenuFragment();
    fragmentTransaction.add(R.id.menu_fragment, myFragment);

    //add content
    DetailPart1 content1= new DetailPart1 ();
    fragmentTransaction.add(R.id.content_fragment, content1);
    fragmentTransaction.commit();

}
public void onMainMenuSelected(String tag) {
  //next menu is selected replace existing fragment
}

我需要并排显示两个列表视图,菜单在左侧,其内容在右侧。默认情况下,第一个菜单处于选中状态,其内容显示在右侧。显示内容的片段如下:

public class DetailPart1 extends Fragment {
  ArrayList<HashMap<String, String>> myList = new ArrayList<HashMap<String, String>>();
  ListAdapter adap;
  ListView listview;

  @Override
  public void onActivityCreated(Bundle savedInstanceState) {
      super.onActivityCreated(savedInstanceState);

       if(savedInstanceState!=null){
        myList = (ArrayList)savedInstanceState.getSerializable("MYLIST_obj");
        adap = new LoadImageFromArrayListAdapter(getActivity(),myList );
        listview.setAdapter(adap);
       }else{
        //get list and load in list view
        getlistTask = new GetALLListTasks().execute();
    }


     @Override
   public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.skyview_fragment, container,false);
           return v;
        }


     @Override
      public void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
          outState.putSerializable("MYLIST_obj", myList );
        }
    }

onActivityCreated和onCreateView被调用两次。有很多使用片段的示例。由于我是该主题的初学者,因此无法将示例与问题联系起来。我需要一种万无一失的方法来处理方向更改。我尚未android:configChanges在清单文件中声明。我需要销毁并重新创建活动,以便可以在横向模式下使用不同的布局。


通常,片段方向更改无需任何操作即可完成。那么,当您改变方向时会遇到什么问题?
亚历山大·库里亚赫汀

Alex我需要类DetailPart1片段以纵向显示listView的布局,以横向模式显示Grid View的布局。为此,我每次都需要重新创建该片段,但是我不想再次加载相同的记录,所以我将它们存储在onSaveInstanceState上。但是上面的代码两次重新创建了DetailPart1,我需要知道使它
按需

Answers:


132

您每次打开屏幕在活动时间内创建一个新片段onCreate();,但你也维持旧有super.onCreate(savedInstanceState);。因此,也许设置标签并找到该片段是否存在,或者将空束传递给super。

这花了我一些时间来学习,当您使用诸如viewpager之类的东西时,它确实可以说是一个烂摊子。

我建议您多花点时间阅读有关片段的内容,因为它涵盖了这个确切的主题。

这是一个如何在规则的方向变化中处理碎片的示例:

活动内容

public class MainActivity extends FragmentActivity {

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

        if (savedInstanceState == null) {
            TestFragment test = new TestFragment();
            test.setArguments(getIntent().getExtras());
            getSupportFragmentManager().beginTransaction().replace(android.R.id.content, test, "your_fragment_tag").commit();
        } else {
            TestFragment test = (TestFragment) getSupportFragmentManager().findFragmentByTag("your_fragment_tag");
        }
    }
}

片段

public class TestFragment extends Fragment {

    public static final String KEY_ITEM = "unique_key";
    public static final String KEY_INDEX = "index_key";
    private String mTime;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_layout, container, false);

        if (savedInstanceState != null) {
            // Restore last state
            mTime = savedInstanceState.getString("time_key");
        } else {
            mTime = "" + Calendar.getInstance().getTimeInMillis();
        }

        TextView title = (TextView) view.findViewById(R.id.fragment_test);
        title.setText(mTime);

        return view;
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("time_key", mTime);
    }
}

感谢Warpzit的努力,但是如果您在代码中解释您的观点,我将非常高兴。如何更改我的代码以处理方向更改而无需重新加载片段。
user1811741

1
因此,我需要在方向上更改片段的布局,但我不想重新加载所有记录,我所做的是1.在清单2中添加android:configchanges =“ orientation” 2.在片段中覆盖onConfigurationChanged并检测方向并根据方向隐藏/显示listview或gridview。这是正确的方法吗?
user1811741

@ user1811741已更新示例。我希望它可以澄清一切。
Warpzit 2012年

@Warpzit在ViewPager Fragment实现的情况下,如何处理相同的场景,因为ViewPager会处理所有显示的fragment..any建议。
CoDe 2014年

1
@Shubh好吧,我相信viewpager可以正确处理此问题,否则,您将不得不重写getItem实现以适应您的需求。希望这能为您指明正确的方向,如果没有提出正确的问题:)
Warpzit 2015年

21

可以在android准则中找到有关如何在方向变化和活动娱乐之间保留数据的良好准则

概要:

  1. 使您的片段可保留:

    setRetainInstance(true);
    
  2. 仅在必要时创建新片段(或至少从中获取数据)

    dataFragment = (DataFragment) fm.findFragmentByTag("data");
    
    // create the fragment and data the first time
    if (dataFragment == null) {
    

节省我的时间,哇
Arjun saini
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.