Yeniden yükleme sırasında Parçayı Yenile


110

Bir android uygulamasında bir Db'den TableViewbir Fragment. Ancak yeniden yüklediğimde Fragmentönceki verileri görüntülüyor. FragmentÖnceki veriler yerine güncel verilerle yeniden doldurabilir miyim ?


lütfen bize biraz kod gösterin. Verilerinizi nereye yüklüyorsunuz, parçanıza nereden başlıyorsunuz, değerlerinizi nerede saklıyorsunuz?
AS

Bu, gözenekli olarak tanımlanan probleminizi çözmelidir: stackoverflow.com/questions/6503189/…
Benjamin W.

lütfen daha fazla bilgi kodu pasajı
sağlayın

Uygulamanızda Yenilemek İçin Kaydırmayı deneyin, bu stackoverflow.com/questions/41469040/fragment-refresh/… 'e
Imtiaz Mamun

Yanıtlar:


207

Db güncellemesinden sonra parça içeriğini yenilemek istediğinizi düşünüyorum

Varsa, parçayı ayırın ve yeniden takın

// 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, parçanızı oluştururken verdiğiniz addır

Bu kod, destek kitaplığı içindir.

Eski cihazları destekleyen yapmıyorsan, sadece kullanmak getFragmentManager yerine getSupportFragmentManager

[DÜZENLE]

Bu yöntem, Fragment'in bir etikete sahip olmasını gerektirir.
Elinizde yoksa, @ Hammer'ın yöntemi ihtiyacınız olan şeydir.


3
Bu şu hatayı verir - java.lang.RuntimeException: ResultInfo {who = null, request = 2, result = 3, data = null} etkinliğine {xont.virtusel.v4.controller / xont.virtusel.v4.controller sonucunu teslim etme hatası .sale.InvocieBrandActivity}: java.lang.IllegalStateException: Bu eylem onSaveInstanceState
Samantha Withanage

1
@Elizabeth, Fragment'inizin doğru bir şekilde etiketlendiğinden emin olun
Phantômaxx

1
@Rotwang Cevabınız için teşekkürler Uzun kodu kullanmak yerine bir kısayol kullandım ama bu yolu
açmaya

1
Bu çözüm artık support-v4-library'nin (25.1.0) yeni sürümünde çalışmıyor. Burada açıklama: stackoverflow.com/questions/41270858/…
Brahim Bouaboud

1
Uyarı: Bu numara, Oreo'da yalnızca Destek Parçaları kullanıyorsanız işe yarar!
racs

147

Bu, mevcut parçayı yenileyecek:

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

1
bu kodu nereye koymalı? iç faaliyet mi yoksa parçanın kendisi mi?
Narendra Singh

2
Yenilenmesi gereken parçanın içine koyarsınız.
Mbengue Assane

1
@SagarChavada kodu nereye koydunuz? Verilerin yenilenmesi gibi tek seferlik bir olaya koymalısınız.
Mbengue Assane

5
Özyineleme, özyineleme, sonsuz çağrılar
zulkarnain shah

2
Parçadaki onResume içinde bunu oluşturmak bir döngü oluşturur, bundan nasıl kaçınılır?
Soul

32

Parça etiketine sahip değilseniz, aşağıdaki kod benim için iyi çalışıyor.

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
parça kimliği ne olacak, hiçbir yerde parça kimliği beyan etmedim. Nasıl ve nerede ilan edilir?
Narendra Singh

getActivity()Etkinliğimde kullanacak gibi görünmüyorum . Kullanmalı mıyım Activity.this...?
Si8

@NarendraJi Bu, yalnızca parçalarınızı konteynere yerleştirdiğiniz FrameLayout kimliğidir.
Lokesh

Lütfen bu ekstra korseyi çıkarın. Benim için çok sorun yarattı.
Abhishek

9

Parçanızı kullanıcıya görünür olduğunda yenileyebilirsiniz, sadece bu kodu Parçanıza ekleyin, bu göründüğünde parçanızı yenileyecektir.

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

çok yavaş yeniden
yüklenene

Bu, görüntüleyici adaptörüyle iyi çalışıyor gibi görünüyor
DragonFire

2
setUserVisibleHint kullanımdan kaldırıldı
Sai Aditya

Benim için çalıştı, çözüm için teşekkürler.
hetsgandhi

7

Parçayı yenilemek kabul edilen cevap Nougat ve üzeri sürümlerde çalışmayacaktır. Tüm işletim sistemlerinde çalışmasını sağlamak için aşağıdakileri yapabilirsiniz.

    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

" Fragment Already Added" İstisnası aldığınız bir Aktiviteye bağlıyken parçayı yeniden yükleyemezsiniz .

Bu yüzden fragman önce faaliyetinden ayrılmalı ve sonra eklenmelidir. Hepsi tek satırda akıcı api kullanılarak yapılabilir:

getFragmentManager().beginTransaction().detach(this).attach(this).commit();

Güncelleme: Bu, API 26 ve üzerinde yapılan değişiklikleri dahil etmek içindir:

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

Güncellemenin daha fazla açıklaması için lütfen https://stackoverflow.com/a/51327440/4514796 bakın


2
Lütfen yanıtınızı net açıklamalarla birlikte verin. Kodu yazmayın, başkalarının da anlayabilmesi ve yardımcı olması için paylaştığınız kod hakkında açıklama yapmayın. Stack Overflow'u etkili bir şekilde kullanabilmeniz için SSS Bölümünü okumanızı rica ediyorum.
Sankar Ganesh

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

bu sadece FragmentManagerparçayı başlatmak için kullanırsanız çalışacaktır . <fragment ... />XML'de bir olarak sahipseniz , onCreateViewtekrar çağırmaz . Bunu anlamak için 30 dakikamı boşa harcadım.


1

İşte yaptığım ve benim için işe yarayan şey firebase'i kullanıyorum ve kullanıcı oturum açtığında önce mevcut Parçayı yenilemek istedim, çünkü burada Etkinlik veya bağlamdan ayarlamadığınız sürece parçanın bağlam elde etmenin bir yolu yoktur. kotlin dilinde kullandığım ve çalıştığım kod, sanırım aynısını java sınıfında da kullanabilirsin

   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

A kullanın ContentProviderve bir 'CursorLoader' kullanarak verilerinizi yükleyin. Bu mimari ile verileriniz veritabanı değişikliklerinde otomatik olarak yeniden yüklenecektir. Sizin için üçüncü taraf çerçeveler kullanınContentProviderSizin - gerçekten kendi başınıza uygulamak istemezsiniz ...


0

Aynı sorunu yaşadım ama yukarıdakilerin hiçbiri benim için işe yaramadı. ya bir backstack sorunu vardı (yükledikten sonra kullanıcı geri bastığında aynı parçaya tekrar gitmek istiyordu) ya daonCreaetView

sonunda bunu yaptım:

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

iyi nokta, parçanın etiketine veya kimliğine de ihtiyacınız olmamasıdır. yeniden yüklemek istersen


0

Hem parça etkinliği hem de parçayı tutan etkinlik için onResume yöntemini kullanın.


0
getActivity().getSupportFragmentManager().beginTransaction().replace(GeneralInfo.this.getId(), new GeneralInfo()).commit();

GeneralInfo bu benim Fragment sınıfım GeneralInfo.java

Bunu fragment sınıfına bir yöntem olarak koydum:

public void Reload(){
    getActivity().getSupportFragmentManager().beginTransaction().replace(LogActivity.this.getId(), new LogActivity()).commit();
}

0

Örneğin TabLayout ile: Sadece OnTabSelectedListener uygulayın. Sayfayı yeniden yüklemek için SwipeRefreshLayout.OnRefreshListener ie'yi kullanabilirsiniz.public class YourFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {

onRefresh () yöntemi arayüzden @Override olacaktır, yani:

@Override
public void onRefresh() {
 loadData();
}

İşte düzen:

<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" />

Aktivitenizdeki kod

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 () yazın; MainActivity'de onResume (). İyi şanslar :)


-2

En kolay yol

viewpager.setAdapter içeren bir genel statik yöntem yapın

bağdaştırıcıyı ve görüntüleyiciyi statik yap

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

herhangi bir yeri, herhangi bir etkinliği, herhangi bir parçayı arayın

MainActivity.refreshFragments();
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.