ViewPager中隐藏的片段内的RecyclerView为空

时间:2018-06-11 15:49:45

标签: android android-fragments android-recyclerview android-viewpager

苦苦挣扎!

我创建了一个包含2个页面的viewpager,一个是完美运行的音频播放器,第二个页面是新闻列表。它是一个带有回收者视图的片段。

摇篮

dependencies {
    implementation 'com.android.support.constraint:constraint-layout:1.1.1'
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation project(':library')
    implementation 'com.android.support:support-v4:27.1.1'
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support:recyclerview-v7:27.1.1'
    implementation 'com.squareup.picasso:picasso:2.71828'
    implementation 'com.android.volley:volley:1.1.0'
}

ViewPager适配器

private class mPagerAdapter extends FragmentStatePagerAdapter {

        public mPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int pos) {
            switch(pos) {

                case 0: return PlayerPage.newInstance();
                case 1: return News.newInstance();
                default: return PlayerPage.newInstance();
            }
        }

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

新闻片段

public class News extends Fragment {
    private List<NewsBlueprint> newsList = new ArrayList<>();
    private RecyclerView recyclerView;
    private NewsAdapter newsAdapter;
    private ProgressBar progressBar;

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

        progressBar = (ProgressBar) v.findViewById(R.id.progress_bar);

        recyclerView = (RecyclerView) v.findViewById(R.id.news_recyclerview);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity().getBaseContext()));
        recyclerView.setHasFixedSize(true);
        recyclerView.setItemViewCacheSize(View.DRAWING_CACHE_QUALITY_HIGH);

        // Fill with test
        newsList.add(new NewsBlueprint("hi", "hi", "hi", "hi"));

        try {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    newsAdapter = new NewsAdapter(newsList);
                    getActivity().runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            recyclerView.setAdapter(newsAdapter);
                        }
                    });
                }
            }).start();
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        getNews();

        return v;
    }

    public static News newInstance() {
        return new News();
    }

    public void getNews() {
        newsList.clear();
        progressBar.setVisibility(View.VISIBLE);
        String url = "I removed link for privacy on StackOverflow";

        RequestQueue mRequestQueue;
        Cache cache = new DiskBasedCache(getActivity().getCacheDir(), 1024 * 1024); // 1MB cap
        Network network = new BasicNetwork(new HurlStack());
        mRequestQueue = new RequestQueue(cache, network);
        mRequestQueue.start();

        JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, url, null, new Response.Listener<JSONArray>() {
            @Override
            public void onResponse(JSONArray response) {
                try {

                    JSONObject current = null;

                    for (int i = 0; i < response.length(); i++) {

                        current = response.getJSONObject(i);

                        // Get the topStory's title from the volume information
                        String topStoryTitle =  current.getJSONObject("title").getString("rendered");
                        // Get the current topStory's section information
                        // The appropriate section that the story belongs to is contained in the subsection
                        String topStorySection = current.getJSONObject("content").getString("rendered");

                        // Get the date on which the news was published
                        // Extract date information from the JSON response
                        String topStoryDateTime = current.getString("date");

                        // Get the story url
                        String storyUrl = current.getString("link");

                        JSONObject res = current.getJSONObject("_links");
                        JSONArray multimedia = res.getJSONArray("wp:featuredmedia");
                        String href = multimedia.getJSONObject(0).getString("href");

                        newsList.add(new NewsBlueprint(topStoryTitle, topStorySection, topStoryDateTime, href));


                        Toast.makeText(getContext(), "Looping " + topStoryTitle, Toast.LENGTH_SHORT).show();

                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                }


            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(getContext(), "Make sure you are connected to the internet", Toast.LENGTH_SHORT).show();
            }
        });

        mRequestQueue.add(jsonArrayRequest);
        newsAdapter.notifyDataSetChanged();


        progressBar.setVisibility(View.INVISIBLE);
    }
}

新闻适配器

public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.MyViewHolder>{

    private List<NewsBlueprint> news;

    public class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView title;
        public ImageView thumbnail;

        public MyViewHolder(View view) {
            super(view);

            title = view.findViewById(R.id.title);
            thumbnail = view.findViewById(R.id.thumbnail);
        }
    }

    public NewsAdapter(List<NewsBlueprint> newsList) {
        this.news = newsList;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.news_row, parent, false);

        return new MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        NewsBlueprint newsBlueprint = news.get(position);
        holder.title.setText(newsBlueprint.getTitle());
        // Set thumbnail
        //Picasso.get().load(newsBlueprint.getImageURL()).into(holder.thumbnail);
    }

    public int getItemCount() {
        return news.size();
    }

    }

新闻蓝图

只是一个代表新闻项目的类

结果是一个空的RecyclerView

我确保从JSON返回的数据是正确的,因为我在Toast中显示了新闻的标题。

1 个答案:

答案 0 :(得分:3)

在你修改了newsList之后必须调用

newsAdapter.notifyDataSetChanged();(jsonArrayRequest在后台运行,调用它的函数直接继续而不等待响应),而不是在你开始获得新闻。此外,从另一个线程修改适配器数组并不是一个好主意,在后台线程上创建适配器是完全错误的。