Oryantasyon değişikliğinde Fragment ile başa çıkmanın kusursuz yolu


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
}

Yan yana iki liste görünümü, solda menü ve içeriği sağ tarafta görüntüleme ihtiyacım var. Varsayılan olarak, ilk menü seçilir ve içeriği sağ tarafta görüntülenir. İçeriği gösteren Fragman aşağıdaki gibidir:

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 ve onCreateView iki kez çağrılır . Parçaların kullanıldığı birçok örnek var. Bu konuya başlangıç ​​yaptığım için sorunu örnekle ilişkilendiremiyorum. Oryantasyon değişikliğini halletmek için aptalca bir yola ihtiyacım var. android:configChangesManifest dosyasında beyan etmedim . Manzara modunda farklı bir düzen kullanabilmek için etkinliğin yok etmesine ve yeniden yaratmasına ihtiyacım var.


Genellikle parçaların yönelim değişiklikleri hiçbir şey yapmanıza gerek kalmadan halledilir. Peki, yönelimi değiştirdiğinizde yaşadığınız problem nedir?
Alexander Kulyakhtin

Alex, dikey modda listView ile düzeni görüntülemek için DetailPart1 sınıfına ve yatay modda Izgara Görünümü ile mizanpaja ihtiyacım var. Bunun için parçayı her seferinde yeniden oluşturmam gerekiyor ancak aynı kayıtları yeniden yüklemek istemiyorum, bu yüzden OnSaveInstanceState'de depolayın.Ama yukarıdaki kod DetailPart1'i iki kez yeniden oluşturuyor, istediğim gibi çalışmasını sağlayan eksik kodu bilmem gerekiyor
user1811741

Yanıtlar:


132

Etkinliğinizde ekranı her çevirdiğinizde yeni bir fragman oluşturuyorsunuz onCreate();Ama aynı zamanda eskilerini de koruyorsunuz super.onCreate(savedInstanceState);. Bu yüzden, belki etiketi ayarlayın ve varsa parçayı bulun veya boş paketi süper'e geçirin.

Bunu öğrenmem biraz zaman aldı ve görüntüleyici gibi şeylerle çalışırken gerçekten bi **** olabilir.

Bu konu tam olarak işlendiğinden parçalar hakkında fazladan bir kez okumanızı tavsiye ederim .

Düzenli bir yön değişikliğinde parçaların nasıl işleneceğine dair bir örnek:

Aktivite :

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

Parça :

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

Çabanız için teşekkürler Warpzit, ancak amacınızı kodla açıklarsanız sevinirim. Kodumu, parçayı yeniden yüklemeden yön değişikliğini idare edecek şekilde nasıl değiştirebilirim.
user1811741

1
Bu nedenle, yönlendirmede değiştirilecek parçanın düzenine ihtiyacım var, ancak tüm kayıtları yeniden yüklemek istemiyorum, 1. manifest'e android: configchanges = "orientation" ekle 2. parçada onConfigurationChanged değerini geçersiz kılın ve yönlendirmeyi tespit edin ve yönlendirmeye bağlı olarak liste görünümünü veya ızgara görünümünü gizleyin / gösterin. Bu doğru yol mu?
user1811741

@ user1811741 örnekle güncellendi. Umarım her şeyi açıklığa kavuşturur.
Warpzit

@Warpzit ViewPager Fragment uygulaması durumunda aynı senaryoyu nasıl ele alabilirim çünkü ViewPager görüntülenen tüm fragmanlarla ilgilenir ... herhangi bir öneri.
CoDe

1
@Shubh Viewpager'ın bunu doğru bir şekilde ele aldığına inanıyorum, aksi takdirde ihtiyaçlarınıza uyması için getItem uygulamasını geçersiz kılmanız gerekecek. Umarım doğru bir soru
sormazsanız

21

Oryantasyon değişiklikleri ve aktivite rekreasyonu arasında verilerin nasıl tutulacağına ilişkin iyi bir kılavuz android kılavuzlarında bulunabilir .

Özet:

  1. parçanızı muhafaza edilebilir hale getirin:

    setRetainInstance(true);
    
  2. Yalnızca gerekirse yeni bir parça oluşturun (veya en azından ondan veri alın)

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

1
nice Zamanımı kurtar wah
Arjun saini
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.