gpt4 book ai didi

android - 在 ViewPager 中重新加载 fragment 时出现问题

转载 作者:太空狗 更新时间:2023-10-29 14:38:18 25 4
gpt4 key购买 nike

我对 ViewPager 中的 fragment 有疑问。在我的应用程序中,我使用 FragmentStatePagerAdapter 实现了 4 个选项卡。这是我的 SectionsPageAdapter.java

public class SectionsPageAdapter extends FragmentStatePagerAdapter {

private String fragment0 = "";
private Fragment fragAt0;
private FragmentManager manager;
private String[] tabNames;
Context context;


public SectionsPageAdapter(FragmentManager fm, Context ctx, String lastFrag) {
super(fm);
context = ctx;
tabNames = ctx.getResources().getStringArray(R.array.tabs_name);
this.manager = fm;
this.listener = new fragmentChangeListener();
fragment0 = lastFrag;
}


@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return ActivityTypeFragment.newInstance(0);
case 1:
return EventsFragment.newInstance();
case 2:
return CalendarFragment.newInstance();
case 3:
if(fragAt0 == null){

switch(fragment0){
case "Chart":
fragAt0 = ChartFragment.newInstance(listener);
break;
case "Hour":
fragAt0 = HourChartFragment.newInstance(listener);
break;
case "Daily":
fragAt0 = DailyChartFragment.newInstance(listener);
break;
default:
fragAt0 = ChartFragment.newInstance(listener);
}
}
return fragAt0;
default:
return ActivityTypeFragment.newInstance(0);
}
}

@Override
public int getCount() {
return 4;
}

@Nullable
@Override
public CharSequence getPageTitle(int position) {
return tabNames[position];
}

@Override
public int getItemPosition(@NonNull Object object) {
if (object instanceof ChartFragment && fragAt0 instanceof DailyChartFragment
|| object instanceof HourChartFragment && fragAt0 instanceof DailyChartFragment)
{
return POSITION_NONE;
}
else if (object instanceof DailyChartFragment && fragAt0 instanceof ChartFragment
|| object instanceof HourChartFragment && fragAt0 instanceof ChartFragment){
return POSITION_NONE;
}
else if (object instanceof HourChartFragment && fragAt0 instanceof ChartFragment)
{
return POSITION_NONE;
}
else if (object instanceof ChartFragment && fragAt0 instanceof HourChartFragment
|| object instanceof DailyChartFragment && fragAt0 instanceof HourChartFragment)
{
return POSITION_NONE;
}

return POSITION_NONE;
}

public interface nextFragmentListener {
void fragment0Changed(String newFragmentIdentification, FragmentManager fragmentManager);
}
private nextFragmentListener listener;

private final class fragmentChangeListener implements nextFragmentListener {


@Override
public void fragment0Changed(String fragment, FragmentManager fm) {
fragment0 = fragment;

manager.beginTransaction().remove(fragAt0).commitNow();
switch (fragment) {
case "Chart":
fragAt0 = ChartFragment.newInstance(listener);

break;
case "Daily":
fragAt0 = DailyChartFragment.newInstance(listener);
break;
case "Hour":
fragAt0 = HourChartFragment.newInstance(listener);
break;
}
SectionsPageAdapter.this.notifyDataSetChanged();
}
}

public String getFragmentName()
{
return fragment0;
}

所以在最后一个选项卡中,我有一个 fragment - ChartFragment,其中我有 Spinner 以及选择另一个图表的选项。当用户选择另一个图表时,另一个图表会通过调用我的 SectionsPageAdapter 中的方法 fragment0Changed 在此选项卡中重新加载类(class)。我在 https://stackoverflow.com/a/27304530/1573414 中找到了这个解决方案.

这是我的 onItemSelected 函数,我希望它出现在“图表”选项卡中的每个 fragment 中

@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (view != null) {
String selectedMenu = ((TextView) view).getText().toString();
if (selectedMenu == getString(R.string.best_appealing_chart)) {
LoadBestAppealingChart();
} else if (selectedMenu == getString(R.string.hour_chart)) {
chartListener.fragment0Changed("Hour", getActivity().getSupportFragmentManager());
}
else
{
chartListener.fragment0Changed("Daily", getActivity().getSupportFragmentManager());
}
}
else {
LoadBestAppealingChart();
}
}

所以,在我旋转设备之前一切正常,之后选择另一个图表就不起作用了。应用抛出异常:

java.lang.IllegalStateException: Fragment host has been destroyed 
at android.support.v4.app.FragmentManagerImpl.ensureExecReady(FragmentManager.java:2183)
at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:2211)
at android.support.v4.app.BackStackRecord.commitNow(BackStackRecord.java:643).

我读过文章https://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html,but在我的例子中,我既没有用于替换 fragment 的异步方法,也没有在 Activity 生命周期方法中调用它。我在微调器的 onSelectionChanged 方法中进行 fragment 交易。我尝试了什么:使用 commitNowAllowingStateLoss() 并没有让事情变得更好,它只是没有抛出异常, fragment 仍然没有重新加载;将 getSupportFragmentManager() 参数传递给 fragment0Changed 方法也无济于事,但即使我使用简单的 commitNow() 方法,这样做也不会抛出任何异常。但是有帮助的是,在旋转后我选择我的应用程序的第一个或第二个选项卡然后转到我的第四个选项卡(图表选项卡),然后我可以毫无问题地切换(重新加载)我的 fragment 。有趣的是,切换到第三个选项卡(日历选项卡)也无济于事。切换到第三个选项卡并返回到第四个选项卡后,切换 fragment 仍然没有重新加载。

最佳答案

我认为在 Android 上与 Fragment 传递监听器通信是一个常见的错误。 Fragment 上的监听器必须由 the Activity or a child Fragment 实现.所以你必须让你的 Activity 或 Fragment 实现 NextFragmentListener ...其次,永远不要在 ViewPager 上引用 Fragment,你正在泄漏旧的 fragment0

关于android - 在 ViewPager 中重新加载 fragment 时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52440475/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com