Замена фрагментов в AppCompatActivity

У меня есть приложение для Android со SlideMenu.

Это большая часть MainActivity, где у меня есть sideMenu:

public class MainActivity extends ActionBarActivity
{
    private ActionBarDrawerToggle sideMenuToggle;
    private DrawerLayout sideMenuLayout;
    private SideMenuAdapter mAdapter;

    ...

    private class DrawerItemClickListener implements ListView.OnItemClickListener 
    {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) 
        {
            Bundle data = new Bundle();
            data.putString("title", options.get(posit).getString("visual_name"));
            if (posit == Constants.INDEX_USERNAME)
                goToView(ViewManager.EDITPROFILE, data);
            else if ((posit >= Constants.INDEX_SECTION_1) && (posit <= Constants.INDEX_SECTION_5)) 
            {
                Bundle category = options.get(posit);
                data.putString("title", category.getString("visual_name"));
                data.putString("visual_name", category.getString("visual_name"));
                data.putString("name", category.getString("name"));
                data.putInt("photo", category.getInt("photo"));
                data.putInt("ico", category.getInt("cat_ico"));
                data.putBoolean("is_root", true);
                goToView(ViewManager.CATEGORYFRAGMENT, data);
            }
        }
    }

    public Fragment goToView(ViewInfo _viewInfo, Bundle bundle)
    {
        try 
        {
            if ((this != null) && !this.isFinishing())
            {
                ViewManager myVMgr = viewMgr;
                return myVMgr.show(_viewInfo, bundle, false);
            }

        } catch (IllegalStateException e) {
        }
        return null;
    }
}

И это большая часть кода ViewManager, где я переключаюсь между разделами (это фрагменты):

public class ViewManager 
{

    private Activity context = null;

    ...

    public Fragment show(ViewInfo _newFragInfo, Bundle _data,  boolean back)
    {
        Fragment currentFragment = null;
        Fragment newFragment = null;

        final FragmentManager fm = context.getFragmentManager();
        ViewInfo _lastFragInfo = lastViewData != null ? lastViewData.getViewInfo() : null;

        // In this app we must support changing between same fragment class
        //if ((_lastFragInfo != null) && _newFragInfo.getIdView().equalsIgnoreCase(_lastFragInfo.getIdView())) {
        //    return null;
        //}

        FragmentTransaction ft = fm.beginTransaction();
        if (_newFragInfo.getIsRoot())
        {
            Iterator<ViewData> iter = viewStack.iterator();
            ViewData viewData;
            while (iter.hasNext())
            {
                viewData = iter.next();
                if (!viewData.getViewInfo().getIsRoot())
                {
                    currentFragment = fm.findFragmentByTag(viewData.getViewInfo().getIdView());
                    if (currentFragment != null)
                    {
                        ft.remove(currentFragment);
                    }
                }
                iter.remove();
            }
        }

        // Hide current fragment
        if (_lastFragInfo != null)
        {
            currentFragment = fm.findFragmentByTag(_lastFragInfo.getIdView());
            if (currentFragment != null)
            {
                if (!back)
                    ft.detach(currentFragment);
                else
                    ft.remove(currentFragment);
            }
        }

        // Show new fragment
        if (_newFragInfo != null)
        {
            if (_newFragInfo.getIsRoot() || back) // only tabs are reusable fragment
                newFragment = fm.findFragmentByTag(_newFragInfo.getIdView());
            if (newFragment == null)
            {
                newFragment = Fragment.instantiate(context, _newFragInfo.getClaseView().getName());
                ft.add(R.id.frame_content, newFragment, _newFragInfo.getIdView());
            }
            else
            {
                ft.attach(newFragment);
            }

            if (_data == null)
                _data = new Bundle(1);

            if (!_data.containsKey("title"))
                _data.putString("title", context.getResources().getString(_newFragInfo.getTitle()));

            if (!_newFragInfo.getIsRoot() && !back)
            {
                viewStack.add(lastViewData);
            }

            ((BaseFragment)newFragment).setData(_data);
        }

        lastViewData = new ViewData(_newFragInfo, _data);
        ft.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out);
        ft.commitAllowingStateLoss();
        fm.executePendingTransactions();
        return newFragment;
    }
}

В боковом меню параметр «Редактировать профиль» имеет собственный фрагмент, а в разделах с 1 по 5 используется тот же фрагмент, но я загружаю другое содержимое.

Пока это работает хорошо, и когда пользователь открывает боковое меню и переключается между разделами, они загружаются правильно.

Но теперь я загрузил свой код для использования target sdk 26, и он не компилируется, потому что ActionBarActivity больше не доступен, поэтому я внес следующие изменения:

public class MainActivity extends ActionBarActivity

к этому

public class MainActivity extends AppCompatActivity

и внутри ViewManager

private Activity context = null;

к этому

private AppCompatActivity context = null;

Теперь это компилируется, но когда я переключаюсь между разделами, данные нового раздела не загружаются, и я продолжаю смотреть содержимое предыдущего раздела.

Некоторые примеры:

1)

1.1) Выбираю Section1 (я вижу содержание Section1)

1.2) Я выбираю Edit Profile (я вижу содержимое Edit profile)

1.3) Выбираю Section3 (вижу содержимое Section3)

2)

2.1) Выбираю Section1 (я вижу содержание Section1)

2.2) Я выбираю Section3 (я вижу не содержимое Section3, а содержимое Section1).

Проверяя это, я увидел, что проблема в том, что с AppCompatActivity, onCreate, onCreateView и onResume методы моего CategoryFragment вызываются на шагах 1.1, 1.3 и 2.1, но не на шаге 2.2.

Я что-то упускаю? Следует ли мне внести новое изменение, чтобы транзакции фрагментов выполнялись правильно с помощью AppCompatActivity?

-- РЕДАКТИРОВАТЬ --

Метод setData фрагмента таков:

public void setData(Bundle _newdata)
{
    data = _newdata;
}

Я подумал изменить его на это:

public void setData(Bundle _newdata)
{
    data = _newdata;
    // Some code to force the refresh/reloading of the Fragment
}

Но я не уверен, что это сложный способ исправить это, и, кстати, я не знаю, как заставить фрагмент перезагружаться.

Моя идея состоит в том, чтобы установить флаг для каждого Fragment, затем обработать текущий Fragment и накачать необходимый Fragment. Это то, что вам нужно?

ʍѳђઽ૯ท 09.09.2018 15:32

Извините, я вас не очень хорошо понимаю. Отлаживая мой код. Я видел, что в обоих примерах вызывается строка «Fragment.instantiate (...)», поэтому я предполагаю, что это раздувает фрагмент. Но во втором примере не вызываются методы oncreate или onresume.

Wonton 09.09.2018 15:37
0
2
216
0

Другие вопросы по теме