В приложении для Android я загружаю данные из базы данных в TableView
внутри Fragment
. Но когда я перезагружаю Fragment
он отображает предыдущие данные. Могу ли я заново заполнить Fragment
текущими данными вместо предыдущих?
Обновить фрагмент при перезагрузке
Ответ 1
Я думаю, что вы хотите обновить содержимое фрагмента при обновлении db
Если это так, отсоедините фрагмент и снова подключите его
// Reload current fragment
Fragment frg = null;
frg = getSupportFragmentManager().findFragmentByTag("Your_Fragment_TAG");
final FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.detach(frg);
ft.attach(frg);
ft.commit();
Your_Fragment_TAG - это имя, которое вы дали своему фрагменту при его создании.
Этот код предназначен для библиотеки поддержки.
Если вы не поддерживаете старые устройства, просто используйте getFragmentManager вместо getSupportFragmentManager
[EDIT]
Этот метод требует, чтобы Фрагмент имел тег.
Если у вас его нет, то метод @Hammer - это то, что вам нужно.
Ответ 2
Это обновит текущий фрагмент:
FragmentTransaction ft = getFragmentManager().beginTransaction();
if (Build.VERSION.SDK_INT >= 26) {
ft.setReorderingAllowed(false);
}
ft.detach(this).attach(this).commit();
Ответ 3
Если у вас нет метки фрагмента, следующий код работает хорошо для меня.
Fragment currentFragment = getActivity().getFragmentManager().findFragmentById(R.id.fragment_container);
if (currentFragment instanceof "NAME OF YOUR FRAGMENT CLASS") {
FragmentTransaction fragTransaction = (getActivity()).getFragmentManager().beginTransaction();
fragTransaction.detach(currentFragment);
fragTransaction.attach(currentFragment);
fragTransaction.commit();}
}
Ответ 4
Для обновления фрагмента принятый ответ не будет работать на Nougat и выше версии. Чтобы заставить его работать на всех ОС вы можете сделать следующее.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
fragmentManager.beginTransaction().detach(this).commitNow();
fragmentManager.beginTransaction().attach(this).commitNow();
} else {
fragmentManager.beginTransaction().detach(this).attach(this).commit();
}
Ответ 5
вы можете обновить фрагмент, когда он виден для пользователя, просто добавьте этот код в свой фрагмент, это обновит ваш фрагмент, когда он будет виден.
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
// Refresh your fragment here
getFragmentManager().beginTransaction().detach(this).attach(this).commit();
Log.i("IsRefresh", "Yes");
}
}
Ответ 6
MyFragment fragment = (MyFragment) getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG);
getSupportFragmentManager().beginTransaction().detach(fragment).attach(fragment).commit();
это будет работать, только если u использует FragmentManager
для инициализации фрагмента. Если u имеет это как <fragment ... />
в XML, он не будет вызывать onCreateView
снова. Потратил мои 30 минут, чтобы понять это.
Ответ 7
Вы не можете перезагрузить фрагмент, когда он привязан к Activity, где вы получаете исключение " Fragment Already Added
".
Таким образом, фрагмент должен быть сначала отделен от его активности, а затем прикреплен. Все можно сделать, используя беглый api в одной строке:
getFragmentManager().beginTransaction().detach(this).attach(this).commit();
Обновление. Это должно включать изменения, внесенные в API 26 и выше:
FragmentTransaction transaction = mActivity.getFragmentManager()
.beginTransaction();
if (Build.VERSION.SDK_INT >= 26) {
transaction.setReorderingAllowed(false);
}
transaction.detach(this).attach
(this).commit();
Дополнительную информацию об обновлении см. на странице /questions/122243/refresh-fragment-not-working-any-more/12121183#12121183
Ответ 8
Используйте ContentProvider
и загрузите данные с помощью "CursorLoader". С этой архитектурой ваши данные будут автоматически перезагружены при изменении базы данных. Используйте сторонние фреймворки для своего ContentProvider
- вы действительно не хотите реализовать его самостоятельно...
Ответ 9
У меня была такая же проблема, но ни одна из вышеперечисленных не работала на мою. либо была проблема с backstack (после загрузки, когда пользователь нажал назад, он снова перейдет к тому же фрагменту), или он не вызвал onCreaetView
наконец я сделал это:
public void transactFragment(Fragment fragment, boolean reload) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
if (reload) {
getSupportFragmentManager().popBackStack();
}
transaction.replace(R.id.main_activity_frame_layout, fragment);
transaction.addToBackStack(null);
transaction.commit();
}
Хорошая точка - вам не нужен тег или идентификатор фрагмента. если вы хотите перезагрузить
Ответ 10
Вот что я сделал, и это сработало для меня. Я использую Firebase, и когда пользователь входит в систему, я хотел сначала обновить текущий фрагмент, вам нужно будет запросить контекст из действия, потому что у фрагмента нет способа получить контекст, если вы не установите его из действия или контекста здесь. это код, который я использовал и работал на языке котлин, я думаю, вы могли бы использовать то же самое в классе Java
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
super.setUserVisibleHint(isVisibleToUser)
val context = requireActivity()
if (auth.currentUser != null) {
if (isVisibleToUser){
context.supportFragmentManager.beginTransaction().detach(this).attach(this).commit()
}
}
}
Ответ 11
Используйте метод onResume... как для активности фрагмента, так и для активности, содержащей фрагмент.
Ответ 12
Самый простой способ
сделать публичный статический метод, содержащий viewpager.setAdapter
сделать адаптер и viewpager статичными
public static void refreshFragments(){
viewPager.setAdapter(adapter);
}
Звоните куда угодно, любая деятельность, любой фрагмент.
MainActivity.refreshFragments();
Ответ 13
protected void onResume() {
super.onResume();
viewPagerAdapter.notifyDataSetChanged();
}
Делайте запись viewpagerAdapter.notifyDataSetChanged(); в onResume() в MainActivity. Удачи :)