Элементы во Фрагменте не работают после повторного добавления одного и того же фрагмента

UPDATE. Я нашел, что заголовок - это не единственное, что затронуто, но listeners и другие элементы в фрагменте не инициализируются. (Например, FAB). Единственное, что работает правильно, - это что-то построенное внутри adapter (т.е. Строки ListView)

Проблема. Откройте "Открытый ящик", щелкните элемент списка, который открывает новый Fragment в том же Activity. Откройте снова "Ящик навигации", щелкните тот же элемент, который должен просто заменить существующий Fragment, а при открытии Fragment все элементы, которые программно программируются в Java (текст, цвета, слушатели), не изменяются/не добавляются к Fragment. Представление - это просто макет по умолчанию xml. Я подтвердил с помощью Log.d, что код, который устанавливает эти вещи, запускается. (Если вы открываете другой Fragment, а затем возвращаетесь к исходному, все работает нормально)

Подтвержденная причина: При изменении этого параметра:

    compile "com.android.support:appcompat-v7:25.0.1"
    compile 'com.android.support:design:25.0.1'

к

    compile "com.android.support:appcompat-v7:25.1.0"
    compile 'com.android.support:design:25.1.0'

(если только одна из этих библиотек изменена, неважно, какая из них проблема)

Я подтвердил, что изменение этих двух библиотек является проблемой (также подтвердило эту проблему во втором приложении и изменило только этот код, имеет тот же результат)

Мои вопросы, почему это происходит и как это можно исправить?

Код и более подробное описание из оригинального вопроса:

                FragmentTransaction tItems = fm.beginTransaction();
                ListFragment mFrag = new PlannerFragment();
                tItems.replace(R.id.main_frag, mFrag, TAG_CALC_FRAGMENT);
                tItems.commit();

В моем ящике имеется около 4 параметров, которые открывают этот фрагмент, но перед каждым я устанавливаю глобальную переменную следующим образом:

MyApp.PlanType = "highbal";
MyApp.PlanType = "lowbal";
etc.

На основе значения PlanType (выше), что Fragment загружается с различными данными (но в тех же самых макетах xml). Это просто ListView с заголовком.

Этот Fragment, (PlannerFragment) загружается в первый раз.

Когда я нажимаю на другой элемент (другой PlanType), который переходит к тому же Fragment (тот же самый код выше выполнен): ListView загружает штраф в фактический список. Но в header в списке, ни один из значений setText() не устанавливает новые данные правильно. Он использует значения по умолчанию из моего макета xml.

Теперь, если я загружаю другой Fragment между ними, все отлично работает. Это только когда я либо добавляю, либо заменяю (я пробовал оба) тот же самый Fragment поверх старого делает это.

Вот код заголовка вверху PlannerFragment

@Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        // Setup listview
        lv = getListView();

        LayoutInflater inflaterHeader = getActivity().getLayoutInflater();
        ViewGroup header = (ViewGroup) inflaterHeader.inflate(R.layout.planner_listview_header, lv, false);
        lv.addHeaderView(header, null, false);

        // Load Data then Set Textviews, e.g.:
        TextView title = (TextView) getActivity().findViewById(R.id.tvPlannerTitle);
    dateOutput = (TextView) getActivity().findViewById(R.id.tvDebtOutDate);

Если я добавлю к этому коду, dateOutput.setText("test"); этого не произойдет. Я могу сделать Log.d и мои регистры данных, поэтому этот код читается, но пользовательский интерфейс не установлен.

Я даже попытался удалить Fragment сначала, как это, с помощью проверки:

                Fragment fragment = fm.findFragmentByTag(TAG_CALC_FRAGMENT);
                if(fragment != null)
                    fm.beginTransaction().remove(fragment).commit();

Это не влияет.

Опять же, это ТОЛЬКО случалось, когда я менял библиотеки выше. Это ошибка с библиотекой или она теперь реагирует по-другому?

Ответ 1

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


FragmentTransaction заменит поведение

Заменить не работает должным образом в appCompat 25.1.0
Текущее состояние (4 января 2017 г.): ошибка назначена
Ссылка на проблему


Изменение жизненного цикла фрагмента на 25.1.0

onStart на новом фрагменте вызывается перед onStop на предыдущем
Текущий статус: работает как ожидалось. Для меня это может быть потрясающее изменение от app compat 25.0.x Ссылка на проблему

Также существует проблема с событием resume, называемым два раза в фрагменте, см. здесь.

TL;DR. Возможно, лучшим временным решением является не использование 25.1.0 до выхода новой версии.

Ответ 2

вы можете добавить list_view_header.xml в метод navigationDrawer() и изменить позицию выбранного элемента, например selectItem(position - 1).

  private void navigationDrawer() {

        mTitle = mDrawerTitle = getTitle();
        // mNavigationDrawerItemTitles = getResources().getStringArray(R.array.navigation_drawer_items_array);

        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerList = (ListView) findViewById(R.id.left_drawer);

        LayoutInflater inflater = getLayoutInflater();
        View listHeaderView = inflater.inflate(R.layout.list_view_header, null, false);
        mDrawerList.addHeaderView(listHeaderView, null, false);

        setupToolbar();

        DataModel[] drawerItem = new DataModel[6];

        drawerItem[0] = new DataModel(R.drawable.dashboard_icon, "Dashboard");
        drawerItem[1] = new DataModel(R.drawable.cal_icon, "Calender");
        drawerItem[2] = new DataModel(R.drawable.classes, "Classes");
        drawerItem[3] = new DataModel(R.drawable.message_icon_hdpi, "Message Center");
        drawerItem[4] = new DataModel(R.drawable.profile, "Profile & Setting");
        drawerItem[5] = new DataModel(R.drawable.bulletin_icon, "Bulletin Board");

        getSupportActionBar().setDisplayHomeAsUpEnabled(false);
        getSupportActionBar().setHomeButtonEnabled(true);

        DrawerItemCustomAdapter adapter = new DrawerItemCustomAdapter(this, R.layout.list_view_item_row, drawerItem);
        mDrawerList.setAdapter(adapter);
        mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerLayout.setDrawerListener(mDrawerToggle);
        setupDrawerToggle();


    }

    private class DrawerItemClickListener implements ListView.OnItemClickListener {

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            selectItem(position - 1);
        }


    }

    private void selectItem(int i) {
        Fragment fragment = null;

        switch (i) {
            case 0:
                fragment = new Fragment_DashBoard();
                // toolbar.setTitle("Dashboard");
                Titletv.setText("Dashboard");
                break;
            case 1:
                fragment = new Fragment_Calender();
                // toolbar.setTitle("Calender");
                Titletv.setText("Calender");

                break;
            case 2:
                fragment = new Fragment_Classes();
                // toolbar.setTitle("Classes");
                Titletv.setText("Classes");
                break;
            case 3:
                fragment = new Fragment_MessageCenter();
                // toolbar.setTitle("Message");
                Titletv.setText("Messages");
                break;
            case 4:
                fragment = new Fragment_ProfileSetting();
                // toolbar.setTitle("Profile");
                Titletv.setText("Profile");

                break;

            case 5:
                fragment = new Fragment_BulletinBoard();
                //toolbar.setTitle("Bulletin Board");
                Titletv.setText("Bulletin Board");

                break;

            default:
                break;
        }


        if (fragment != null) {

            FragmentManager fragmentManager = getSupportFragmentManager();
            FragmentTransaction trans = fragmentManager.beginTransaction();
            fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).addToBackStack(null).commit();

            mDrawerList.setItemChecked(i, true);
            mDrawerList.getItemAtPosition(i);
            // setTitle(mNavigationDrawerItemTitles[position]);
            mDrawerLayout.closeDrawer(mDrawerList);


        } else {
            Log.e("MainActivity", "Error in creating fragment");
        }


    }