У додатку для Android я завантажую дані з Db TableView
всередину a Fragment
. Але коли я перезавантажую, Fragment
він відображає попередні дані. Чи можу я переповнити Fragment
поточні дані замість попередніх даних?
У додатку для Android я завантажую дані з Db TableView
всередину a 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
[EDIT]
Цей метод вимагає, щоб фрагмент мав тег.
Якщо у вас цього немає, тоді вам потрібен метод @ 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();
}
Ви не можете перезавантажити фрагмент, поки він додається до діяльності, де ви отримуєте " 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, і коли користувач входить у систему, я спершу хотів оновити поточний фрагмент, вам потрібно буде вимагати контекст від діяльності, оскільки фрагмент не має способу отримати контекст, якщо ви не встановите його з "Діяльність" або "Контекст тут" це код, який я використовував і працював на мові kotlin, я думаю, ви могли б використовувати те саме в класі 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
- ви насправді не хочете їх реалізувати самостійно ...
У мене був той самий випуск, але жодне з перерахованого вище не працювало на моєму. або виникла проблема з 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();
}
хороший момент - вам теж не потрібен тег або ідентифікатор фрагмента. якщо ви хочете перезавантажити
Скористайтеся методом onResume ... як щодо активності фрагмента, так і активності, що містить фрагмент.
getActivity().getSupportFragmentManager().beginTransaction().replace(GeneralInfo.this.getId(), new GeneralInfo()).commit();
GeneralInfo
це мій клас Fragment 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();