В приложении для Android я загружаю данные из базы данных во TableView
внутренний файл Fragment
. Но когда я перезагружаю, Fragment
он отображает предыдущие данные. Могу ли я повторно заполнить Fragment
текущими данными вместо предыдущих?
В приложении для Android я загружаю данные из базы данных во TableView
внутренний файл Fragment
. Но когда я перезагружаю, Fragment
он отображает предыдущие данные. Могу ли я повторно заполнить Fragment
текущими данными вместо предыдущих?
Ответы:
Я думаю, вы хотите обновить содержимое фрагмента при обновлении 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.
[РЕДАКТИРОВАТЬ]
Этот метод требует, чтобы фрагмент имел тег.
Если у вас его нет, то метод @ Hammer - это то, что вам нужно.
Это обновит текущий фрагмент:
FragmentTransaction ft = getFragmentManager().beginTransaction();
if (Build.VERSION.SDK_INT >= 26) {
ft.setReorderingAllowed(false);
}
ft.detach(this).attach(this).commit();
Если у вас нет тега фрагмента, мне подходит следующий код.
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();}
}
getActivity()
в моей деятельности. Стоит ли использовать Activity.this...
?
вы можете обновить свой фрагмент, когда он виден пользователю, просто добавьте этот код в свой фрагмент, это обновит ваш фрагмент, когда он станет видимым.
@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");
}
}
Чтобы обновить фрагмент, принятый ответ не будет работать в версии 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();
}
Вы не можете перезагрузить фрагмент, пока он прикреплен к 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();
Дополнительное описание обновления см. На странице https://stackoverflow.com/a/51327440/4514796.
MyFragment fragment = (MyFragment) getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG);
getSupportFragmentManager().beginTransaction().detach(fragment).attach(fragment).commit();
это будет работать, только если вы используете FragmentManager
для инициализации фрагмента. Если у вас есть это как <fragment ... />
в XML, он не будет вызывать onCreateView
снова. Потратил свои 30 минут, чтобы понять это.
Вот что я сделал, и это сработало для меня, я использую firebase, и когда пользователь входит в систему, я хотел сначала обновить текущий фрагмент, вам нужно будет запросить контекст из активности, потому что у фрагмента нет способа получить контекст, если вы не установите его из Activity или context здесь это код, который я использовал и работал на языке котлин, я думаю, вы могли бы использовать то же самое в классе 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()
}
}
}
Используйте ContentProvider
и загрузите данные с помощью CursorLoader. С этой архитектурой ваши данные будут автоматически перезагружаться при изменении базы данных. Используйте сторонние фреймворки для себя ContentProvider
- вы действительно не хотите реализовывать это самостоятельно ...
У меня была такая же проблема, но ничего из вышеперечисленного не помогло мне. либо возникла проблема с обратным стеком (после загрузки, когда пользователь нажал обратно, он снова перешел к тому же фрагменту), либо он не вызвал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();
}
Хороший момент - вам не нужен ни тег, ни идентификатор фрагмента. если вы хотите перезагрузить
Используйте метод onResume ... как для активности фрагмента, так и для активности, содержащей фрагмент.
getActivity().getSupportFragmentManager().beginTransaction().replace(GeneralInfo.this.getId(), new GeneralInfo()).commit();
GeneralInfo
это мой класс фрагмента GeneralInfo.java
Я поместил это как метод в класс фрагмента:
public void Reload(){
getActivity().getSupportFragmentManager().beginTransaction().replace(LogActivity.this.getId(), new LogActivity()).commit();
}
Например, с TabLayout: просто реализуйте OnTabSelectedListener. Чтобы перезагрузить страницу, вы можете использовать реализацию SwipeRefreshLayout.OnRefreshListener, т.е.public class YourFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
метод onRefresh () будет @Override из интерфейса, т.е.
@Override
public void onRefresh() {
loadData();
}
Вот макет:
<com.google.android.material.tabs.TabLayout
android:id="@+id/tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimaryLighter"
app:tabGravity="fill"
app:tabIndicatorColor="@color/white"
app:tabMode="fixed"
app:tabSelectedTextColor="@color/colorTextPrimary"
app:tabTextColor="@color/colorTextDisable" />
Код в вашей деятельности
TabLayout tabLayout = (TabLayout) findViewById (R.id.tablayout); tabLayout.setupWithViewPager (viewPager);
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
if (tab.getPosition() == 0) {
yourFragment1.onRefresh();
} else if (tab.getPosition() == 1) {
yourFragment2.onRefresh();
}
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
Самый простой способ
сделать общедоступный статический метод, содержащий viewpager.setAdapter
сделать адаптер и просмотрщик статическими
public static void refreshFragments(){
viewPager.setAdapter(adapter);
}
звонить куда угодно, любую активность, любой фрагмент.
MainActivity.refreshFragments();