重新加载时刷新碎片

在一个 android 应用程序中,我将数据从数据库加载到 Fragment中的 TableView中。但是,当我重新加载的 Fragment它显示以前的数据。我可以用当前数据而不是以前的数据重新填充 Fragment吗?

363617 次浏览

我觉得你想要 在数据库更新时刷新片段内容

如果是这样,分离碎片并重新连接

// 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 的方法就是你所需要的。

如果您没有片段标记,下面的代码对我很有用。

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

这将刷新当前的碎片:

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

使用 ContentProvider并使用“ CursorLoader”加载数据。使用此体系结构,数据将在数据库更改时自动重新加载。使用 第三方框架为您的 ContentProvider-你并不真的想要实现它自己..。

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

这将只有在您使用 FragmentManager初始化片段时才能工作。如果在 XML 中将它作为 <fragment ... />,它就不会再次调用 onCreateView。我浪费了30分钟才想明白。

我也有同样的问题,但是以上的都不适合我。要么是出现了一个回栈问题(当用户向后按下加载键时,它将再次进入相同的片段) ,要么是它没有调用 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。 如果你想重新装弹的话

当片段附加到 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

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

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

你可以在片段对用户可见时刷新它, 只要将这段代码添加到您的片段中,这将在可见时刷新您的片段。

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

最简单的方法

创建一个包含 viewpager.setAdapter 的公共静态方法

使适配器和浏览器静态

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

呼叫任何地方,任何活动,任何碎片。

MainActivity.refreshFragments();

要刷新片段接受的答案将不会在牛轧糖和以上版本的工作。让它工作在所有操作系统上,你可以做以下。

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

在这里我所做的和它为我工作我使用 firebase,当用户是 logIn 我想刷新当前片段首先你将需要请求活动的上下文,因为片段没有一个方法获得上下文,除非你设置它从活动或上下文这里是我使用的代码和工作在 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()
}
}


}

利用 onResume 方法... 在片段活动和持有片段的活动上。

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

这是我的片段类 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) ; 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) {


}
});
// Reload current fragment
Fragment frag = new Order();
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.fragment_home, frag).commit();

以防您正在使用导航组件
您可以使用 navigate(this_fragment_id)导航到这个片段,但是是在一个新的实例中。此外,您还必须在删除实际的片段之前弹出回栈。

科特林

val navController: NavController =
requireActivity().findNavController(R.id.navHostFragment)
navController.run {
popBackStack()
navigate(R.id.this_fragment_id)
}

爪哇咖啡

NavController navController =
requireActivity().findNavController(R.id.navHostFragment);
navController.popBackStack();
navController.navigate(R.id.this_fragment_id);

如果你正在使用 NavController,试试这个(kotlin) :

val navController = findNavController()
navController.run {
popBackStack()
navigate(R.id.yourFragment)
}

这些答案对我都不起作用,所以如果还有人对此有问题的话,我也可以发布我的解决方案。此解决方案仅在使用导航组件时有效。

转到导航图并找到要刷新的片段。从那个片段创建一个动作到它自己。现在你可以像这样在片段中调用这个动作。

private void refreshFragment(){
// This method refreshes the fragment
NavHostFragment.findNavController(FirstFragment.this)
.navigate(R.id.action_FirstFragment_self);
}
Below code reloads the current fragment onClick of button from Parent Activity.


layoutNews.setOnClickListener(v -> {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment_container, fragNews);
ft.detach(fragNews);
ft.attach(fragNews);
ft.commit();
});