重新加载时刷新片段


110

在android应用程序中,我正在将数据从Db加载到的TableView内部Fragment。但是,当我重新加载Fragment它时,它将显示以前的数据。我可以Fragment用当前数据代替以前的数据来重新填充吗?


给我们看一些代码。您在哪里加载数据,在哪里开始片段,在哪里存储值?
2013年

:这应该解决您的porly那样的问题stackoverflow.com/questions/6503189/...
本杰明W.

请提供更多信息代码段
nikvs 2013年

尽量使用刷卡到刷新到您的应用看到这个stackoverflow.com/questions/41469040/fragment-refresh/...
伊姆蒂亚兹马蒙

Answers:


207

我认为您想在数据库更新时刷新片段内容

如果是这样,请拆下碎片并重新连接

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

[编辑]

此方法要求Fragment具有标签。
如果您没有它,那么@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之后无法执行此操作
Samantha Withanage 2013年

1
@Elizabeth确保您的片段具有正确设置的标签
Phantômaxx

1
@Rotwang感谢您的答复,我只是采取了捷径而不是冗长的代码,但这为铺平了道路:)
Si8

1
在新版本的support-v4-library(25.1.0)中,此解决方案不再起作用。说明这里:stackoverflow.com/questions/41270858/...
卜拉欣Bouaboud

1
警告:仅当您使用支持片段时,此技巧才适用于Oreo!
racs

146

这将刷新当前片段:

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

1
该代码放在哪里?内部活动还是片段本身?
Narendra Singh

2
您将其放在需要刷新的片段中。
Mbengue Assane

1
@SagarChavada您将代码放在哪里?您必须将其置于一次性事件中,例如刷新数据时。
Mbengue Assane

5
递归,递归,无休止的通话
zulkarnain shah

2
使用此片段在片段的onResume中创建一个循环,如何避免它?
灵魂

32

如果您没有fragment标签,以下代码对我来说效果很好。

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
片段ID是什么,我在任何地方都没有声明片段ID。如何以及在哪里声明?
Narendra Singh

似乎无法getActivity()在我的活动中使用。我应该使用Activity.this...吗?
Si8

@NarendraJi,只有FrameLayout ID才是将片段放置在容器中的位置。
Lokesh

请删除多余的支撑。这给我带来了很多麻烦。
阿比舍克

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秒才能重新加载
Omar Boshra

这似乎与viewpager适配器配合得很好
DragonFire

2
setUserVisibleHint已弃用
Sai Aditya

为我工作,感谢您的解决方案。
hetsgandhi

7

要刷新片段,可接受的答案将不适用于牛轧糖及更高版本。要使其在所有操作系统上都能正常工作,您可以执行以下操作。

    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
请为您的答案提供清晰的说明。不要编写代码,而要给出共享代码的解释,以便其他人也可以理解,这将是有帮助的。我要求您阅读FAQ部分,以便有效地使用Stack Overflow。
Sankar Ganesh

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

这仅在您FragmentManager用于初始化片段时才有效。如果您将其作为<fragment ... />XML格式,它将不会onCreateView再次调用。浪费了我30分钟的时间来解决这个问题。


1

在这里我做了什么,对我有用,我使用firebase,当用户登录时,我想先刷新当前的Fragment,您将需要从活动中重新查询上下文,因为除非您没有从Activity或context中设置它,否则片段无法获取上下文。是我在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()
        }
    }

}

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

优点是您不需要片段的标签或ID。如果你想重新加载



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

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

要写viewpagerAdapter.notifyDataSetChanged(); 在MainActivity的onResume()中。祝好运 :)


-2

最简单的方法

制作一个包含viewpager.setAdapter的公共静态方法

使适配器和viewpager静态

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

随时随地打电话,任何活动,任何片段。

MainActivity.refreshFragments();
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.