我正在使用 ViewPager 创建一个 UI,用户可以在其中像单元格一样在网格页面之间滑动,每个单元格都包含一个新闻报道。第一页是一个“标题” fragment ,它有一个更大的单元格用于特色故事。其余的是“标准” fragment ,其中有 12 个统一的单元格。 ViewPager 位于我的 TabletFragment 类中(此 ui 仅适用于平板电脑,手机使用标准 ListView ),并且该 fragment 布局中的唯一元素是 ViewPager 本身。对于加载到 ViewPager 中的 fragment ,它可以是如上所述的“ header ”或“标准” fragment 。 TabletFragment 调用 Volley 使用来自 json 提要的新闻项填充 ListArray,然后将该列表发送到子 fragment (标题和标准)。 TabletFragment 在 viewPager 中保留了一个 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/