Обновить фрагмент при перезагрузке


111

В приложении для Android я загружаю данные из базы данных во TableViewвнутренний файл Fragment. Но когда я перезагружаю, Fragmentон отображает предыдущие данные. Могу ли я повторно заполнить Fragmentтекущими данными вместо предыдущих?


покажите нам код, пожалуйста. Где вы загружаете свои данные, где вы начинаете свой фрагмент, где вы храните свои значения?
— AS

Это должно решить вашу подробно описанную проблему: stackoverflow.com/questions/6503189/…
— Benjamin W.

пожалуйста, предоставьте больше фрагмента информационного кода
— nikvs

Попробуйте использовать Swipe-to-Refresh To Your App, см. Этот stackoverflow.com/questions/41469040/fragment-refresh/…
— Имтиаз Мамун

Ответы:


207

Я думаю, вы хотите обновить содержимое фрагмента при обновлении 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 - это то, что вам нужно.


3
Это дает следующую ошибку - java.lang.RuntimeException: Не удалось доставить результат ResultInfo {who = null, request = 2, result = 3, data = null} в действие {xont.virtusel.v4.controller / xont.virtusel.v4.controller .sale.InvocieBrandActivity}: java.lang.IllegalStateException: Невозможно выполнить это действие после onSaveInstanceState
— Саманта Уитханейдж

1
@Elizabeth, убедитесь, что у вашего фрагмента правильно установлен тег
— Phantômaxx

1
@Rotwang Спасибо за ваш ответ. Я просто использовал ярлык, а не длинный код, но это помогло проложить путь :)
— Si8,

1
Это решение больше не работает в новой версии support-v4-library (25.1.0). Объяснение здесь: stackoverflow.com/questions/41270858/…
— Брахим Буабуд

1
Предупреждение: этот трюк работает в Oreo, только если вы используете Support Fragments!
— racs

147

Это обновит текущий фрагмент:

FragmentTransaction ft = getFragmentManager().beginTransaction();
if (Build.VERSION.SDK_INT >= 26) {
   ft.setReorderingAllowed(false);
}
ft.detach(this).attach(this).commit();

1
куда поставить этот код? внутри активности или самого фрагмента?
— Нарендра Сингх

2
Вы помещаете его внутрь фрагмента, который нужно обновить.
— Mbengue Assane

1
@SagarChavada где ты поместил код? Вы должны поместить его в одноразовое событие, например, когда данные обновляются.
— Mbengue Assane

5
Рекурсия, рекурсия, бесконечные вызовы
— zulkarnain shah

2
Использование этого создает внутри onResume во фрагменте создается цикл, как этого избежать?
— Soul

32

Если у вас нет тега фрагмента, мне подходит следующий код.

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();}
}

1
какой будет идентификатор фрагмента, я нигде не объявлял идентификатор фрагмента. Как и где это заявить?
— Нарендра Сингх

Не могу использовать getActivity()в моей деятельности. Стоит ли использовать Activity.this...?
— Si8

@NarendraJi - это только идентификатор FrameLayout, в который вы помещаете свои фрагменты в контейнер.
— Локеш

Удалите лишнюю скобу. Это доставило мне много хлопот.
— Абхишек

9

вы можете обновить свой фрагмент, когда он виден пользователю, просто добавьте этот код в свой фрагмент, это обновит ваш фрагмент, когда он станет видимым.

@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");
    }
}

так медленно, что перезагрузка занимает 3 секунды
— Омар Бошра

Это , кажется, работает хорошо с ViewPager адаптером
— DragonFire

2
setUserVisibleHint устарел
— Сай Адитья

У меня сработало, спасибо за решение.
— hetsgandhi

7

Чтобы обновить фрагмент, принятый ответ не будет работать в версии 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

Вы не можете перезагрузить фрагмент, пока он прикреплен к 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.


2
Пожалуйста, дайте свой ответ с четкими описаниями. Не пишите код, дайте объяснение кода, которым вы поделились, чтобы другие также могли понять, и это будет полезно. Я прошу вас прочитать раздел часто задаваемых вопросов, чтобы эффективно использовать Stack Overflow.
— Санкар Ганеш

3
   MyFragment fragment = (MyFragment) getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG);
        getSupportFragmentManager().beginTransaction().detach(fragment).attach(fragment).commit();

это будет работать, только если вы используете FragmentManagerдля инициализации фрагмента. Если у вас есть это как <fragment ... />в XML, он не будет вызывать onCreateViewснова. Потратил свои 30 минут, чтобы понять это.


1

Вот что я сделал, и это сработало для меня, я использую 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()
        }
    }

}

0

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


0

У меня была такая же проблема, но ничего из вышеперечисленного не помогло мне. либо возникла проблема с обратным стеком (после загрузки, когда пользователь нажал обратно, он снова перешел к тому же фрагменту), либо он не вызвал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();
}

Хороший момент - вам не нужен ни тег, ни идентификатор фрагмента. если вы хотите перезагрузить


0

Используйте метод onResume ... как для активности фрагмента, так и для активности, содержащей фрагмент.


0
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();
}

0

Например, с 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) {

        }
    });

-2
protected void onResume() {
        super.onResume();
        viewPagerAdapter.notifyDataSetChanged();
    }

Напишите viewpagerAdapter.notifyDataSetChanged (); в onResume () в MainActivity. Удачи :)


-2

Самый простой способ

сделать общедоступный статический метод, содержащий viewpager.setAdapter

сделать адаптер и просмотрщик статическими

public static void refreshFragments(){
        viewPager.setAdapter(adapter);
    }

звонить куда угодно, любую активность, любой фрагмент.

MainActivity.refreshFragments();
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.