Android ViewPager 在加载第一个片段时显示空白屏幕,但在向后滑动跨过其他片段时显示正确的内容

Android ViewPager showing empty screen for first fragment onload but right content when swiping back across other fragments

我想用 3 个 fragments A、B、C 填充 viewpager。它们每个都有一个 recycler view 和线性布局管理器。在使用 AsyncTask.

获取一些数据后,viewpager 在 activity 中是 set-up

在 activity 查看加载时,第一个 fragment (A) 显示空白屏幕(无内容)。但是,当我从 A 到 B、B 到 C、C 到 B、B 到 A 的片段滑动时,我可以在 fragment A.

中看到预期的内容

片段 A(音频)- 正在加载,然后是 B(视频)和 C(文本)

Frag A-1 Frag B Frag-C

反方向:C -> B -> A(此时内容出现在A)

Frag-C Frag B Frag-A-2

fragment_audio_items.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/audio_feed_item_list_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </android.support.v7.widget.RecyclerView>

</LinearLayout>

AudioFeedItemsFragment.java

package com.abc.app.fragments;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.abc.app.R;
import com.abc.app.adapters.FeedItemListRVAdapter;
import com.abc.app.models.feed.FeedItem;


import java.util.ArrayList;
import java.util.List;

/**
 * Created by amit on 10/12/16.
 */

public class AudioFeedItemsFragment extends Fragment {

    public static final String AUDIO_FEED_ITEM_LIST = "AUDIO_FEED_ITEM_LIST";

    RecyclerView mRecyclerView;
    LinearLayoutManager mLinearLayoutManager;
    FeedItemListRVAdapter mFeedItemListRVAdapter;
    List<FeedItem> mAudioFeedItemList = new ArrayList<>();
    Bundle mBundle;

    public static AudioFeedItemsFragment newInstance(ArrayList<FeedItem> feedItems) {
        AudioFeedItemsFragment audioFeedItemsFragment = new AudioFeedItemsFragment();
        Bundle audioArgs = new Bundle();
        audioArgs.putParcelableArrayList(AUDIO_FEED_ITEM_LIST, feedItems);
        audioFeedItemsFragment.setArguments(audioArgs);
        return audioFeedItemsFragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBundle = getArguments();
        if (null != mBundle) {
            mAudioFeedItemList = mBundle.getParcelableArrayList(AUDIO_FEED_ITEM_LIST);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_audio_items, container, false);
        mRecyclerView = (RecyclerView) rootView.findViewById(R.id.audio_feed_item_list_recycler_view);
        mLinearLayoutManager = new LinearLayoutManager(getContext());
        mRecyclerView.setLayoutManager(mLinearLayoutManager);

        mFeedItemListRVAdapter = new FeedItemListRVAdapter(mAudioFeedItemList);
        mRecyclerView.setAdapter(mFeedItemListRVAdapter);


        return rootView;
        // / return super.onCreateView(inflater, container, savedInstanceState);
    }

}

片段 B 和 C 的相似代码。

FeedMediaTabCollectionAdapter.java

package com.abc.app.adapters;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;

import android.support.v4.app.FragmentStatePagerAdapter;
import android.util.Log;


import com.abc.app.fragments.AudioFeedItemsFragment;
import com.abc.app.fragments.FeedItemDetailsFragment;
import com.abc.app.fragments.TextFeedItemsFragment;
import com.abc.app.fragments.VideoFeedItemsFragment;
import com.abc.app.models.feed.FeedItem;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;


/**
 * Created by amit on 7/12/16.
 */

public class FeedMediaTabCollectionAdapter extends FragmentStatePagerAdapter {
    public static final String TAG = "FMTC";
    private List<String> mFragmentTitleList = new ArrayList<>();
    Map<String, ArrayList<FeedItem>> mFeedItemsListMap;


    public FeedMediaTabCollectionAdapter(FragmentManager fm, Map<String, ArrayList<FeedItem>> feedItemsListMap, List<String> titles) {
        super(fm);
        mFeedItemsListMap = feedItemsListMap;
        mFragmentTitleList = titles;
    }

    @Override
    public Fragment getItem(int position) {
        Log.d(TAG, "position: " + position);
        switch (position) {
            case 0 :
                return AudioFeedItemsFragment.newInstance(mFeedItemsListMap.get(AudioFeedItemsFragment.AUDIO_FEED_ITEM_LIST));
            case 1 :
                return VideoFeedItemsFragment.newInstance(mFeedItemsListMap.get(VideoFeedItemsFragment.VIDEO_FEED_ITEM_LIST));
            case 2:
                return TextFeedItemsFragment.newInstance(mFeedItemsListMap.get(TextFeedItemsFragment.TEXT_FEED_ITEM_LIST));
            default:
                return null;

        }
    }

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


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


}

activity_new_feed_items.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/feed_media_layout"
    android:layout_width="match_parent" android:layout_height="match_parent">

    <android.support.v4.view.ViewPager
        android:id="@+id/feed_media_pager"
        android:layout_width="match_parent" android:layout_height="match_parent">

        <android.support.design.widget.TabLayout
            android:id="@+id/feed_media_tab_layout"
            app:tabMode="scrollable"
            app:tabGravity="fill"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

        </android.support.design.widget.TabLayout>

    </android.support.v4.view.ViewPager>-


</android.support.design.widget.CoordinatorLayout>

NewFeedItemsActivity.java

package com.abc.app.activities;

import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;

import com.abc.app.R;
import com.abc.app.adapters.FeedMediaTabCollectionAdapter;
import com.abc.app.fragments.AudioFeedItemsFragment;
import com.abc.app.fragments.TextFeedItemsFragment;
import com.abc.app.fragments.VideoFeedItemsFragment;
import com.abc.app.models.feed.FeedItem;
import com.abc.app.models.feed.FeedLink;
import com.abc.app.utilities.FeedUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by amit on 13/12/16.
 */

public class NewFeedItemsActivity extends DrawerActivity {

    public static final String AUDIO = "Audio";
    public static final String VIDEO = "Video";
    public static final String TEXT = "Text/Misc";
    private ArrayList<FeedItem> mAudioFeedItemList = null;
    private  ArrayList<FeedItem> mVideoFeedItemList = null;
    private  ArrayList<FeedItem> mTextFeedItemList = null;
    private Map<String, ArrayList<FeedItem>> feedItemsListMap = null;
    static ArrayList<FeedLink> mfeedLinks;
    ProgressDialog mProgressDialog;


    FeedMediaTabCollectionAdapter mFeedMediaTabCollectionAdapter;
    ViewPager mViewPager;
    TabLayout mTabLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentLayout(R.layout.activity_new_feed_items);

        mViewPager = (ViewPager) findViewById(R.id.feed_media_pager);
        mTabLayout = (TabLayout) findViewById(R.id.feed_media_tab_layout);

        new LoadFeedItemList().execute();

    }

    public void setupViewPager() {
        List<String> titles = Arrays.asList(AUDIO, VIDEO, TEXT);
        mFeedMediaTabCollectionAdapter = new FeedMediaTabCollectionAdapter(getSupportFragmentManager(), feedItemsListMap, titles);
        mViewPager.setAdapter(mFeedMediaTabCollectionAdapter);
        mTabLayout.setupWithViewPager(mViewPager);
    }

    class LoadFeedItemList extends AsyncTask<String, String, String> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            mProgressDialog = new ProgressDialog(NewFeedItemsActivity.this);
            mProgressDialog.setMessage("Loading feed items...");
            mProgressDialog.setIndeterminate(false);
            mProgressDialog.setCancelable(false);
            mProgressDialog.show();
            mAudioFeedItemList = new ArrayList<>();
            mVideoFeedItemList = new ArrayList<>();
            mTextFeedItemList = new ArrayList<>();
            feedItemsListMap = new HashMap<>();

            populateFeedLinks();
        }

        @Override
        protected String doInBackground(String... params) {
            List<FeedItem> feedItemList = new ArrayList<>();
            for (FeedLink feedLink : mfeedLinks) {
                List<FeedItem> localFeedItems = FeedUtils.getFeedItemList(feedLink.getUrl(), feedLink.getType());
                for (FeedItem feedItem : localFeedItems) {
                    String mimeType = FeedUtils.getFeedItemMediaType(feedItem);
                    if (mimeType.equalsIgnoreCase(FeedUtils.AUDIO)) {
                        mAudioFeedItemList.add(feedItem);
                    } else if (mimeType.equalsIgnoreCase(FeedUtils.VIDEO)) {
                        mVideoFeedItemList.add(feedItem);
                    } else {
                        mTextFeedItemList.add(feedItem);
                    }
                }
            }


            return null;
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            feedItemsListMap.put(AudioFeedItemsFragment.AUDIO_FEED_ITEM_LIST, mAudioFeedItemList);
            feedItemsListMap.put(VideoFeedItemsFragment.VIDEO_FEED_ITEM_LIST, mVideoFeedItemList);
            feedItemsListMap.put(TextFeedItemsFragment.TEXT_FEED_ITEM_LIST, mTextFeedItemList);
            setupViewPager();
            mProgressDialog.dismiss();

        }
    }

    void populateFeedLinks() {

        mfeedLinks = new ArrayList<>();
        FeedLink feedLink1 = new FeedLink();
        feedLink1.setUrl("http://www.bbc.co.uk/programmes/p002vsnk/episodes/downloads.rss");
        feedLink1.setType(FeedUtils.RSS);
        mfeedLinks.add(feedLink1);

        /*FeedLink feedLink2 = new FeedLink();
        feedLink2.setUrl("http://www.npr.org/rss/podcast.php?id=344098539");
        feedLink2.setType(FeedUtils.RSS);
        mfeedLinks.add(feedLink2);*/

        FeedLink feedLink3 = new FeedLink();
        feedLink3.setUrl("http://www.theregister.co.uk/headlines.atom");
        feedLink3.setType(FeedUtils.ATOM);
        mfeedLinks.add(feedLink3);

        /*
        FeedLink feedLink4 = new FeedLink();
        feedLink4.setUrl("http://www.lse.ac.uk/assets/richmedia/webFeeds/publicLecturesAndEvents_AtomAllMediaTypes2016.xml");
        feedLink4.setType(FeedUtils.ATOM);
        mfeedLinks.add(feedLink4);*/
    }
}

更新: 我想,我发现了代码的问题。问题出在文件 FeedItemListRVAdapter.java

FeedItemListRVAdapter.java

public class FeedItemListRVAdapter extends RecyclerView.Adapter<FeedItemListRVAdapter.FeedItemViewHolder> {

    private static String TAG = "FeedItemListRVAdapter";

    public static List<FeedItem> feedItemList; // <------- static?? This was the issue!

    @Override
    public FeedItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Log.d(TAG, "-----------onCreateViewHolder--------------");
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.feed_item_list, parent, false);
        FeedItemViewHolder feedItemViewHolder = new FeedItemViewHolder(view);
        return feedItemViewHolder;
    }

    @Override
    public void onBindViewHolder(FeedItemViewHolder holder, int position) {
        Log.d(TAG, "-----------onBindViewHolder--------------");
        holder.feedItemTitle.setText(feedItemList.get(position).getTitle());
        holder.feedItemDescription.setText(feedItemList.get(position).getDescription());
        holder.feedItemPubDate.setText(FeedUtils.getLocalTimeString(feedItemList.get(position).getPubDate()));
        String downloadSize = FeedUtils.round2DecimalPlace(FeedUtils.bytesToMB(feedItemList.get(position).getMediaFileSize()));
        holder.feedItemDownloadSize.setText(downloadSize + " MB");
        holder.feedItemDuration.setText(FeedUtils.getMinSec(feedItemList.get(position).getMediaDuration()) + " min");
    }

    @Override
    public int getItemCount() {
        return feedItemList.size();
    }

    public static class FeedItemViewHolder extends RecyclerView.ViewHolder {

        CardView cardView;
        TextView feedItemTitle;
        TextView feedItemPubDate;
        TextView feedItemDuration;
        TextView feedItemDownloadSize;
        TextView feedItemDescription;


        FeedItemViewHolder(View itemView) {
            super(itemView);
            Log.d("FeedItemViewHolder", "-----------FeedItemViewHolder--------------");
            cardView = (CardView) itemView.findViewById(R.id.feed_item_card_view);
            feedItemTitle = (TextView) itemView.findViewById(R.id.feed_item_title);
            feedItemPubDate = (TextView) itemView.findViewById(R.id.feed_item_pub_date);
            feedItemDuration = (TextView) itemView.findViewById(R.id.feed_item_duration);
            feedItemDownloadSize = (TextView) itemView.findViewById(R.id.feed_item_download_size);
            feedItemDescription = (TextView) itemView.findViewById(R.id.feed_item_description);
        }
    }

    public FeedItemListRVAdapter(List<FeedItem> feedItemList) {

        this.feedItemList = feedItemList;
    }
}

在FeedItemListRVAdapter.java中,静态成员feedItemList是在为第二个片段调用FeedItemListRVAdapter构造函数时被空数据覆盖的问题.将其更改为非静态并且有效。