重新加载时刷新片段

时间:2013-12-20 11:11:07

标签: android android-fragments

在Android应用程序中,我将数据从Db加载到TableView内的Fragment。但是当我重新加载Fragment时,它会显示以前的数据。我可以使用当前数据而不是以前的数据重新填充Fragment吗?

17 个答案:

答案 0 :(得分:182)

我认为您希望在db update

时刷新片段内容

如果是,请分离片段并重新连接

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

答案 1 :(得分:127)

这将刷新当前片段:

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

答案 2 :(得分:27)

如果您没有片段标记,以下代码对我来说效果很好。

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

答案 3 :(得分:4)

您可以在用户看到片段时刷新片段, 只需将这段代码添加到片段中,即可在可见时刷新您的片段。

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

答案 4 :(得分:3)

您无法在片段附加到活动时重新加载片段,您可以在其中获得&#34; Fragment Already Added&#34;异常。

因此片段必须首先与其活动分离,然后附加。所有这些都可以使用流畅的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

答案 5 :(得分:3)

要刷新片段,以上所有答案均不适用于Oreo及更高版本。要使其适用于所有操作系统,您可以执行以下操作。

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

答案 6 :(得分:2)

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

这只有在您使用FragmentManager初始化片段时才有效。如果您将其作为XML中的<fragment ... />,则不会再次调用onCreateView。我花了30分钟才弄清楚这一点。

答案 7 :(得分:1)

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

答案 8 :(得分:1)

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

答案 9 :(得分: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。 如果你想重新加载

答案 10 :(得分:0)

使用ContentProvider并使用&#39; CursorLoader&#39;加载数据。使用此架构,您的数据将在数据库更改时自动重新加载。对ContentProvider使用third-party frameworks - 您真的不想自己实施它......

答案 11 :(得分:0)

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

}

答案 12 :(得分:0)

在片段活动和保存片段的活动上都使用onResume方法。

答案 13 :(得分: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) {

        }
    });

答案 14 :(得分:0)

如果您使用导航组件
您可以使用 navigate(this_fragment_id) 导航到此片段,但在一个新实例中。此外,您还必须在删除实际片段之前弹出 backstack。

科特林

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

Java

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

答案 15 :(得分:-1)

最简单的方法

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

将适配器和viewpager设为静态

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

在任何地方,任何活动,任何片段上通话。

MainActivity.refreshFragments();

答案 16 :(得分:-2)

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

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