未填充 ListView。 ViewPager 和片段的问题

Posted

技术标签:

【中文标题】未填充 ListView。 ViewPager 和片段的问题【英文标题】:ListView not populated. Problem with ViewPager and fragments 【发布时间】:2019-05-31 14:55:12 【问题描述】:

我使用 ViewPager 切换了三个片段,第三个包含 ListView。

我的问题是 ListView 在我第一次切换到该片段时没有填充。我必须切换回第一个,然后再次切换回第三个,并且只会填充 ListView。这里似乎有什么问题?

ViewPager 是如何工作的?

这是我的 TabAdapter

public class TabAdapter extends FragmentStatePagerAdapter 
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();

TabAdapter(FragmentManager fm) 
    super(fm);


@Override
public Fragment getItem(int position) 
    return mFragmentList.get(position);


public void addFragment(Fragment fragment, String title) 
    mFragmentList.add(fragment);
    mFragmentTitleList.add(title);


@Nullable
@Override
public CharSequence getPageTitle(int position) 
    return mFragmentTitleList.get(position);


@Override
public int getCount() 
    return mFragmentList.size();

这是列表视图的 ListAdapter

   public class ListAdapter extends BaseAdapter 
    private ArrayList data = new ArrayList();

    public ListAdapter(LinkedHashMap<String, ArrayList<String>> lhm) 
        try 
            data.addAll(lhm.entrySet());
         catch (Exception e) 
            e.printStackTrace();
        
    

    @Override
    public int getCount() 
        return data.size();
    

    @Override
    public LinkedHashMap.Entry<String, ArrayList<String>> getItem(int position) 
        return (LinkedHashMap.Entry) data.get(position);
    

    @Override
    public long getItemId(int position) 
        return 0;
    
    @NonNull
    @Override
    public View getView(final int position, @Nullable View convertView, @NonNull ViewGroup parent) 
        final LinkedHashMap.Entry<String, ArrayList<String>> item = getItem(position);
        final ArrayList quotesList = item.getValue();
        if (convertView == null) 
            convertView = LayoutInflater.from(getContext()).inflate(R.layout.archive_list, parent, false);
        
        TableRow tableRow = convertView.findViewById(R.id.container);
        TextView title = convertView.findViewById(R.id.title);
        ImageView copy = convertView.findViewById(R.id.copy);
        copy.setVisibility(View.INVISIBLE);
        title.setText(item.getKey() + " Quotes");

        tableRow.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                Intent intent = new Intent(getContext(), ViewActivity.class);
                intent.putExtra("title", item.getKey());
                intent.putStringArrayListExtra("quotes", quotesList);
                if (interstitialAd.isLoaded()) 
                    interstitialAd.show();
                    startActivity(intent);
                 else 
                    startActivity(intent);
                
            
        );
        return convertView;
    

更新

问题似乎来自 Linkedhashmap。我尝试手动将值放入 Hashmap 并且它有效。现在的问题是我当前的代码。我通过从 firebase 检索数据来填充我的 hashmap,这似乎是问题所在?也许它的填充速度没有那么快?

    private void initArchives() 
    DatabaseReference dBase = FirebaseDatabase.getInstance().getReference().child("archive");
    dBase.addListenerForSingleValueEvent(new ValueEventListener() 
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) 
            for(DataSnapshot snapshot : dataSnapshot.getChildren()) 
                DataPojo dp = snapshot.getValue(DataPojo.class);
                hm.put(dp.getName(), dp.getMessages());
            
        
        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) 

        
    );


  public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) 
    View view = inflater.inflate(R.layout.fragment_archive, container, false);
    listView = view.findViewById(R.id.listView);
    searchView = view.findViewById(R.id.searchView);


    initArchives();
    listAdapter = new ListAdapter(hm);
    listView.setAdapter(listAdapter);
    listView.invalidateViews();

    loadAds();

    return view;

【问题讨论】:

【参考方案1】:

首先FragmentStatePagerAdapter 真的很蛋疼。但我们必须解决这个问题。我建议您 Ctrl + 单击FragmentStatePagerAdapter 并阅读源代码。

另一件事是使用addFragment() 方法将片段添加到您的ArrayList 可能不是最好的主意,因为FragmentStatePagerAdapter 正在保存片段的状态并从它自己的FragmentManager 加载它们。

所以你添加的片段可能不是你得到的片段。 一个可能的解决方案是使用标签。

有一些关于herehere和here主题的必读文章。

还有另一件事。 ViewPager 在使用 FragmentStatePagerAdapter 时一次创建三个片段。首先,它创建要显示的片段,然后是右侧的片段,最后是左侧的片段。由于您有三个片段,因此不会立即创建最后一个(第三个)片段(第一个片段的左侧没有片段)。也许您正在加载一些需要时间在第三个片段上下载的数据?下次显示第三个片段时,它会从FragmentStatePagerAdapter 的保存状态加载。这些只是一些需要考虑的可能性。不一定是正确的解决方案。祝你好运。

【讨论】:

以上是关于未填充 ListView。 ViewPager 和片段的问题的主要内容,如果未能解决你的问题,请参考以下文章

填充 ListView 很慢,Fragment 加载不顺畅

listView 颤动中未定义子项和填充

带有导航抽屉的片段中的 ListView 和 ViewPager

从 Parent 为 Fragment 的 ListView 设置适配器

Listview嵌套Viewpager实现仿淘宝搜狐广告主页,并实现listview的下拉刷新

LinearLayout 中的 ViewPager ListView。滑动 ViewPager 应该滑动整个页面吗?