Cara anti-bodoh untuk menangani Fragmen pada perubahan orientasi

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
}

Saya perlu menampilkan dua tampilan daftar secara berdampingan, menu di kiri dan isinya di sisi kanan. Secara default, menu pertama dipilih dan isinya ditampilkan di sisi kanan. Fragmen yang menampilkan konten adalah sebagai berikut:

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 dan onCreateView dipanggil dua kali . Ada banyak contoh di luar sana yang menggunakan fragmen. Karena saya pemula dalam bidang ini, saya tidak dapat menghubungkan contoh dengan masalah saya. Saya membutuhkan cara yang sangat mudah untuk menangani perubahan orientasi. Saya BELUM mendeklarasikan android:configChangesdalam file manifes. Saya perlu aktivitas menghancurkan dan membuat ulang sehingga saya bisa menggunakan tata letak yang berbeda dalam mode lanskap.

pengguna1811741
sumber
Biasanya perubahan orientasi fragmen akan ditangani tanpa Anda perlu melakukan apa pun. Jadi, apa masalah yang Anda alami saat mengubah orientasi?
Alexander Kulyakhtin
Alex Saya membutuhkan fragmen DetailPart1 kelas untuk menampilkan tata letak dengan listView dalam mode potret dan tata letak dengan Tampilan Grid dalam mode lanskap. Untuk ini, saya perlu membuat ulang fragmen setiap kali tetapi saya tidak ingin memuat catatan yang sama lagi, jadi saya simpan di onSaveInstanceState. Tetapi kode di atas membuat ulang DetailPart1 dua kali, saya perlu mengetahui kode yang hilang yang membuatnya berfungsi seperti yang diinginkan
user1811741

Jawaban:

132

Anda membuat fragmen baru setiap kali Anda memutar layar dalam aktivitas onCreate();Anda. Tetapi Anda juga mempertahankan yang lama dengansuper.onCreate(savedInstanceState); . Jadi mungkin setel tag dan temukan fragmen jika ada, atau teruskan null bundle ke super.

Saya butuh beberapa saat untuk belajar dan itu benar-benar bisa menjadi bi **** ketika Anda bekerja dengan hal-hal seperti viewpager.

Saya merekomendasikan Anda untuk membaca tentang fragmen lebih lama karena topik yang tepat ini dibahas.

Berikut adalah contoh cara menangani fragmen pada perubahan orientasi reguler:

Aktivitas :

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

Fragmen :

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
sumber
terima kasih Warpzit atas usaha Anda, tetapi saya akan senang jika Anda menjelaskan dalam kode tentang point.How Anda untuk mengubah kode saya untuk menangani perubahan orientasi tanpa memuat ulang fragmen.
pengguna1811741
1
Oleh karena itu saya perlu tata letak fragmen diubah pada orientasi, tetapi saya tidak ingin memuat ulang semua catatan, yang saya lakukan adalah 1. tambahkan android: configchanges = "orientasi" dalam manifest 2. override onConfigurationChanged dalam fragmen dan deteksi orientasi dan sembunyikan / tampilkan listview atau gridview tergantung pada orientasinya. Apakah ini cara yang benar?
pengguna1811741
@ user1811741 diperbarui dengan contoh. Saya harap ini menjelaskan segalanya.
Warpzit
@Warpzit Bagaimana menangani skenario yang sama dalam kasus implementasi Fragmen ViewPager karena ViewPager menangani semua fragmen yang ditampilkan .. saran apa pun.
CoDe
1
@Shubh, saya yakin viewpager menangani ini dengan benar, jika tidak, Anda harus mengganti implementasi getItem agar sesuai dengan kebutuhan Anda. Harapan yang mengarahkan Anda ke arah yang benar, jika tidak mengajukan pertanyaan yang tepat :)
Warpzit
21

Panduan yang baik tentang cara menyimpan data antara perubahan orientasi dan rekreasi aktivitas dapat ditemukan di pedoman Android .

Ringkasan:

  1. buat fragmen Anda dapat dipertahankan:

    setRetainInstance(true);
    
  2. Buat fragmen baru hanya jika perlu (atau setidaknya ambil data darinya)

    dataFragment = (DataFragment) fm.findFragmentByTag("data");
    
    // create the fragment and data the first time
    if (dataFragment == null) {
    
Sergej Werfel
sumber
1
bagus Hemat waktu saya wah
Arjun saini