Элементы во Фрагменте не работают после повторного добавления одного и того же фрагмента
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");
}
}