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


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.