Безглуздий спосіб обробки фрагмента при зміні орієнтації


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у файлі маніфесту. Мені потрібно активність знищити та відтворити, щоб я міг використовувати інший макет у альбомному режимі.


Зазвичай орієнтація на фрагменти подбає про те, щоб вам нічого не потрібно робити. Отже, яка проблема виникає при зміні орієнтації?
Олександр Куляхтін

Алекс Мені потрібен фрагмент класу DetailPart1 для відображення макета з listView у портретному режимі та макета з поданням сітки в альбомному режимі. Для цього мені потрібно кожен раз відтворювати фрагмент, але я не хочу завантажувати ті самі записи знову, тому я зберігайте їх у onSaveInstanceState. Але наведений вище код відтворює DetailPart1 двічі, мені потрібно знати відсутній код, який змушує його працювати за бажанням
user1811741

Відповіді:


132

Ви створюєте новий фрагмент кожного разу, коли ви перетворюєте екран у своїй діяльності, onCreate();але ви також підтримуєте старі за допомогою super.onCreate(savedInstanceState);. Тож, можливо, встановіть тег і знайдіть фрагмент, якщо він існує, або передайте нульовий пакет супер.

Це зайняло у мене деякий час, щоб навчитися, і це справді може бути бі ****, коли ви працюєте з такими речами, як 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 за ваші зусилля, але я буду радий, якщо ви поясніть у коді про свою точку зору. Як змінити мій код для обробки зміни орієнтації без перезавантаження фрагмента.
користувач1811741

1
Отже, мені потрібно змінити макет фрагмента за орієнтацією, але я не хочу перезавантажувати всі записи, те, що я зробив, було 1. додати android: configchanges = "рієнтація "в маніфест 2. перевизначити onConfigurationChanged у фрагменті та виявити орієнтацію і приховати / показати перегляд списку або сітку в залежності від орієнтації. Це правильний шлях?
user1811741

@ user1811741 оновлено з прикладом. Сподіваюся, це все прояснить.
Warpzit

@Warpzit Як ​​можна обробити той самий сценарій у випадку реалізації фрагмента ViewPager, оскільки ViewPager піклується про всі відображені фрагменти ... будь-яка пропозиція.
CoDe

1
@Shubh добре, я вважаю, що viewpager справляється з цим належним чином, якщо ні, то вам доведеться перевизначити реалізацію getItem відповідно до ваших потреб. Сподіваюся, що це спрямувало вас у правильному напрямку, якщо не поставити належного питання :)
Warpzit

21

Хороший настанова про те, як зберігати дані між змінами орієнтації та відпочинком, можна знайти в інструкціях для Android .

Короткий зміст:

  1. зробіть ваш фрагмент доступним для зберігання:

    setRetainInstance(true);
    
  2. Створюйте новий фрагмент лише за необхідності (або, принаймні, беруть з нього дані)

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

приємно Збережи мій час вау
Арджун Сайні
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.