android - ViewPager 不绘制以后的 fragment

标签 android android-layout android-fragments android-viewpager android-nested-fragment

我正在使用 ViewPager 创建一个 UI,用户可以在其中像单元格一样在网格页面之间滑动,每个单元格都包含一个新闻报道。第一页是一个“标题” fragment ,它有一个更大的单元格用于特色故事。其余的是“标准” fragment ,其中有 12 个统一的单元格。 ViewPager 位于我的 TabletFragment 类中(此 ui 仅适用于平板电脑,手机使用标准 ListView ),并且该 fragment 布局中的唯一元素是 ViewPager 本身。对于加载到 ViewPager 中的 fragment ,它可以是如上所述的“ header ”或“标准” fragment 。 TabletFragment 调用 Volley 使用来自 json 提要的新闻项填充 ListArray,然后将该列表发送到子 fragment (标题和标准)。 TabletFragment 在 vi​​ewPager 中保留了一个 fragment 列表,如果在适配器上调用了 notifyDataSetChanged,它就会在所有 fragment 中调用一个名为 loadFragments 的方法,因此它们实际上会加载单元格并将它们绘制到屏幕上。当通过它进行解析时,这由 volley 响应调用。这个模型在我看来是正确的,它适用于 Header fragment 和 FIRST Standard fragment 。他们画的就像我期望的那样。然而,所有后续的标准 fragment 都只显示空白。新闻项未正确插入到 FrameLayouts。在较早的一些修补之前,似乎所有单元格实际上都被绘制在第一个标准 fragment 中的另一个单元格之上。将“添加”更改为“替换”修复了这个问题,但我仍然不明白为什么在应该注册其他创建的页面时使用这些 View ?我将在下面包含尽可能多的代码,以帮助使我所描述的内容更加清晰,如果您希望看到其他文件或方法,请指出它们,我会将它们包含在更新中。非常感谢任何关于我哪里出错的指导,似乎每个 fragment 都应该在它们自己的单独单元格中绘制,但不幸的是,目前情况并非如此。

平板电脑 fragment

public class PrestoTabletFragment extends Fragment {

private ViewPager viewPager;
private static PagerAdapter pagerAdapter;
private String feedUrl;
private ArrayList<PrestoItem> itemList;
private ArrayList<PrestoTabletContainerFragment> fragmentList;

public static PagerAdapter getAdapter() {
    return pagerAdapter;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setRetainInstance(true);

    itemList = new ArrayList<PrestoItem>();
    fragmentList = new ArrayList<PrestoTabletContainerFragment>();
    feedUrl = getArguments().getString("feedUrl");
    PrestoLoader.prestoTabletRequest(getActivity(), feedUrl, itemList);
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_presto_tablet_pager, container, false);

    viewPager = (ViewPager) rootView.findViewById(R.id.presto_tablet_pager);
    pagerAdapter = new DollyTabletPagerAdapter(getFragmentManager());
    viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int i, float v, int i2) {

        }

        @Override
        public void onPageSelected(int i) {
            fragmentList.get(i).loadFragments();
        }

        @Override
        public void onPageScrollStateChanged(int i) {

        }
    });
    viewPager.setAdapter(pagerAdapter);

    return rootView;
}

private class DollyTabletPagerAdapter extends FragmentStatePagerAdapter {
    public DollyTabletPagerAdapter(android.support.v4.app.FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int i) {
        Fragment fragment;

        Bundle data = new Bundle();
        data.putString("feedUrl", feedUrl);
        data.putParcelableArrayList("itemList", itemList);
        switch (i) {
            case 0: fragment = new PrestoTabletHeaderFragment();
                break;
            default: fragment = new PrestoTabletStandardFragment();
                data.putInt("currentPageIndex", i);
                break;
        }

        fragment.setArguments(data);
        fragmentList.add(i, (PrestoTabletContainerFragment) fragment);

        return fragment;
    }

    @Override
    public int getCount() {
        int pageCount;
        int itemCount = itemList.size();
        if (itemCount < 8) {
            pageCount = 1;
        }
        else {
            pageCount = 1 + (itemCount - 7) / 12;
            if ((itemCount - 7) % 12 != 0) {
                pageCount++;
            }
        }

        return pageCount;
    }

    @Override
    public void notifyDataSetChanged() {
        super.notifyDataSetChanged();

        viewPager.setOffscreenPageLimit(getCount());

        for (int i = 0; i < fragmentList.size(); i++) {
            PrestoTabletContainerFragment currentFragment = fragmentList.get(i);
                currentFragment.loadFragments();
        }
    }
}
}

平板请求

public static void prestoTabletRequest(Context context, String feedUrl, final ArrayList<PrestoItem> itemList) {
    itemList.clear();
    VolleySingleton volley = VolleySingleton.getInstance(context);
    JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, feedUrl, null, new Response.Listener<JSONObject>() {

        @Override
        public void onResponse(JSONObject response) {
            try {
                JSONArray content = response.getJSONObject("modules").getJSONObject("Items").getJSONArray("content");
                for (int i = 0; i < content.length(); i++) {
                    JSONObject currentObject = content.getJSONObject(i);
                    String type = currentObject.getString("type");
                    if (type.equalsIgnoreCase("text") || type.equalsIgnoreCase("promo")) {
                        PrestoItem item = new PrestoItem(currentObject);

                        itemList.add(item);


                    }
                }
            }
            catch (JSONException e) {
                e.printStackTrace();
            }
            PrestoTabletFragment.getAdapter().notifyDataSetChanged();
        }
    }, new Response.ErrorListener() {

        @Override
        public void onErrorResponse(VolleyError error) {
            error.printStackTrace();
        }
    });

    volley.addToRequestQueue(request);
}

标准 fragment

public class PrestoTabletStandardFragment extends Fragment implements PrestoTabletContainerFragment {
private ArrayList<PrestoItem> itemList;
private ArrayList<View> viewList;
private int currentPageIndex;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    currentPageIndex = getArguments().getInt("currentPageIndex");
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_presto_tablet_standard, container, false);
    itemList = getArguments().getParcelableArrayList("itemList");
    viewList = new ArrayList<View>();

    viewList.add(rootView.findViewById(R.id.cell_zero_tablet_standard));
    viewList.add(rootView.findViewById(R.id.cell_one_tablet_standard));
    viewList.add(rootView.findViewById(R.id.cell_two_tablet_standard));
    viewList.add(rootView.findViewById(R.id.cell_three_tablet_standard));
    viewList.add(rootView.findViewById(R.id.cell_four_tablet_standard));
    viewList.add(rootView.findViewById(R.id.cell_five_tablet_standard));
    viewList.add(rootView.findViewById(R.id.cell_six_tablet_standard));
    viewList.add(rootView.findViewById(R.id.cell_seven_tablet_standard));
    viewList.add(rootView.findViewById(R.id.cell_eight_tablet_standard));
    viewList.add(rootView.findViewById(R.id.cell_nine_tablet_standard));
    viewList.add(rootView.findViewById(R.id.cell_ten_tablet_standard));
    viewList.add(rootView.findViewById(R.id.cell_eleven_tablet_standard));

    return rootView;
}

public void loadFragments() {
    int index = 7;
    index += (currentPageIndex - 1) * 12;
    for (int i = index; i < itemList.size() && i < index + 12; i++) {
        int currentViewId = viewList.get(i - index).getId();
        PrestoTabletCellFragment currentFragment = new PrestoTabletCellFragment();
        Bundle data = new Bundle();
        PrestoItem item = itemList.get(i);

        String thumbnailUrl = item.getThumbnailUrl();
        String headline = item.getHeadline();
        String lastUpdated = item.getLastUpdated();
        String url = item.getUrl();

        data.putString("thumbnailUrl", thumbnailUrl);
        data.putString("headline", headline);
        data.putString("lastUpdated", lastUpdated);
        data.putString("url", url);

        currentFragment.setArguments(data);

        FragmentManager fm = MainActivity.supportManager;
        fm.beginTransaction().replace(currentViewId, currentFragment).commit();
        }
    }
}

更新 进一步调试后,我产生了以下输出,让我知道问题出在哪里:

10-07 16:43:31.875  26180-26180/com.gannett.dolly.Titans D/snw﹕ fragment PrestoTabletStandardFragment{427dd9f8 #2 id=0x7f0a0011} loading cell PrestoTabletCellFragment{427e8e38} into view 2131361810
10-07 16:43:31.875  26180-26180/com.gannett.dolly.Titans D/snw﹕ fragment PrestoTabletStandardFragment{427dd9f8 #2 id=0x7f0a0011} loading cell PrestoTabletCellFragment{4278d198} into view 2131361811
10-07 16:43:31.875  26180-26180/com.gannett.dolly.Titans D/snw﹕ fragment PrestoTabletStandardFragment{427dd9f8 #2 id=0x7f0a0011} loading cell PrestoTabletCellFragment{42743328} into view 2131361812
10-07 16:43:31.875  26180-26180/com.gannett.dolly.Titans D/snw﹕ fragment PrestoTabletStandardFragment{427dd9f8 #2 id=0x7f0a0011} loading cell PrestoTabletCellFragment{427f1e38} into view 2131361813
10-07 16:43:31.875  26180-26180/com.gannett.dolly.Titans D/snw﹕ fragment PrestoTabletStandardFragment{427dd9f8 #2 id=0x7f0a0011} loading cell PrestoTabletCellFragment{427f1ef8} into view 2131361814
10-07 16:43:31.875  26180-26180/com.gannett.dolly.Titans D/snw﹕ fragment PrestoTabletStandardFragment{427dd9f8 #2 id=0x7f0a0011} loading cell PrestoTabletCellFragment{427f1fb8} into view 2131361815
10-07 16:43:31.875  26180-26180/com.gannett.dolly.Titans D/snw﹕ fragment PrestoTabletStandardFragment{427dd9f8 #2 id=0x7f0a0011} loading cell PrestoTabletCellFragment{427f2078} into view 2131361816
10-07 16:43:31.875  26180-26180/com.gannett.dolly.Titans D/snw﹕ fragment PrestoTabletStandardFragment{427dd9f8 #2 id=0x7f0a0011} loading cell PrestoTabletCellFragment{427f2298} into view 2131361817
10-07 16:43:31.875  26180-26180/com.gannett.dolly.Titans D/snw﹕ fragment PrestoTabletStandardFragment{427dd9f8 #2 id=0x7f0a0011} loading cell PrestoTabletCellFragment{427f2430} into view 2131361818
10-07 16:43:31.875  26180-26180/com.gannett.dolly.Titans D/snw﹕ fragment PrestoTabletStandardFragment{427dd9f8 #2 id=0x7f0a0011} loading cell PrestoTabletCellFragment{427f25c8} into view 2131361819
10-07 16:43:31.875  26180-26180/com.gannett.dolly.Titans D/snw﹕ fragment PrestoTabletStandardFragment{427dd9f8 #2 id=0x7f0a0011} loading cell PrestoTabletCellFragment{4274c4b8} into view 2131361820
10-07 16:43:31.875  26180-26180/com.gannett.dolly.Titans D/snw﹕ fragment PrestoTabletStandardFragment{427dd9f8 #2 id=0x7f0a0011} loading cell PrestoTabletCellFragment{42ae95f0} into view 2131361821
10-07 16:43:31.875  26180-26180/com.gannett.dolly.Titans D/snw﹕ fragment PrestoTabletStandardFragment{427e3540 #3 id=0x7f0a0011} loading cell PrestoTabletCellFragment{427de3f0} into view 2131361810
10-07 16:43:31.875  26180-26180/com.gannett.dolly.Titans D/snw﹕ fragment PrestoTabletStandardFragment{427e3540 #3 id=0x7f0a0011} loading cell PrestoTabletCellFragment{427f2e18} into view 2131361811
10-07 16:43:31.875  26180-26180/com.gannett.dolly.Titans D/snw﹕ fragment PrestoTabletStandardFragment{427e3540 #3 id=0x7f0a0011} loading cell PrestoTabletCellFragment{427f30e8} into view 2131361812
10-07 16:43:31.875  26180-26180/com.gannett.dolly.Titans D/snw﹕ fragment PrestoTabletStandardFragment{427e3540 #3 id=0x7f0a0011} loading cell PrestoTabletCellFragment{427f33b8} into view 2131361813
10-07 16:43:31.875  26180-26180/com.gannett.dolly.Titans D/snw﹕ fragment PrestoTabletStandardFragment{427e3540 #3 id=0x7f0a0011} loading cell PrestoTabletCellFragment{427f3710} into view 2131361814
10-07 16:43:31.875  26180-26180/com.gannett.dolly.Titans D/snw﹕ fragment PrestoTabletStandardFragment{427e3540 #3 id=0x7f0a0011} loading cell PrestoTabletCellFragment{427d35c0} into view 2131361815
10-07 16:43:31.875  26180-26180/com.gannett.dolly.Titans D/snw﹕ fragment PrestoTabletStandardFragment{427e3540 #3 id=0x7f0a0011} loading cell PrestoTabletCellFragment{427f3d80} into view 2131361816
10-07 16:43:31.875  26180-26180/com.gannett.dolly.Titans D/snw﹕ fragment PrestoTabletStandardFragment{427e3540 #3 id=0x7f0a0011} loading cell PrestoTabletCellFragment{427d4aa8} into view 2131361817
10-07 16:43:31.875  26180-26180/com.gannett.dolly.Titans D/snw﹕ fragment PrestoTabletStandardFragment{427e3540 #3 id=0x7f0a0011} loading cell PrestoTabletCellFragment{427f43f0} into view 2131361818
10-07 16:43:31.875  26180-26180/com.gannett.dolly.Titans D/snw﹕ fragment PrestoTabletStandardFragment{427e3540 #3 id=0x7f0a0011} loading cell PrestoTabletCellFragment{427d6e90} into view 2131361819

如果将其滚动到右侧,就会发现每个 fragment 都使用了相同的 View ID。它是否正确?我假设 fragment 的每个唯一实例在布局中都有其自己唯一的 View 实例(那些是 FrameLayouts 的 ID),这些实例在创建页面时由 onCreateView 加载到列表中。有没有其他方法可以确保为每个唯一页面加载正确、唯一的标识符?

最佳答案

原来问题出在 StandardTablet 类的 loadFragments 方法中。我正在使用:

FragmentManager fm = MainActivity.supportManager;

当我应该使用时:

FragmentManager fm = getChildFragmentManager();

这导致 MainActivity fragment 管理器使用它找到的第一个匹配 View ID,这是第一个 StandardFragment 中的那个。更改为 childFragmentManager 可以让它为每个独特的 fragment 找到合适的 View ,之后一切都会顺利进行。

关于android - ViewPager 不绘制以后的 fragment ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26242244/

相关文章:

android - 在 Android 中使用 Facebook SDK 将带有标题的图片上传到 Facebook

java - Gradle 构建因 "Error:Execution failed for task ' :app:mergeDebugResources'. > Crunching Cruncher photo.png 失败而失败”

android - ProgressDialogue 抛出 NullPointerException

java - Android 应用程序仅占用屏幕的一部分

android - 使用动态库交叉编译 C 代码时出错

java - 如何通过 Activity 的上下文获取类中的 TextView

android - 使用警报对话框摇动动画(如果无效信息摇动编辑文本并且不要关闭)

java - LinearLayout 内的 fragment - Android

android - 如何动态设置FrameLayout的宽度和高度android?

Android YouTube Player API Fragment 不提供手动处理触摸事件的能力