RecyclerView внутри фрагмента, содержащегося в ViewPager, пуст - PullRequest
0 голосов
/ 11 июня 2018

Бороться с этим так плохо!

Я создал вьювер-пейджер с 2 страницами, одна из которых представляет собой аудиоплеер, который работает отлично, а вторая страница - список новостей.Это фрагмент с видом переработчика в детстве.

Gradle

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, верны, когда я отображал заголовок новости в тосте.

1 Ответ

0 голосов
/ 11 июня 2018

newsAdapter.notifyDataSetChanged(); должен вызываться после того, как вы изменили список новостей (jsonArrayRequest запускается в фоновом режиме, функция, вызывающая его, продолжается напрямую, не ожидая ответа), а не после того, как вы начали получать новости.Более того, не рекомендуется изменять массив адаптера из другого потока, и совершенно неправильно создавать адаптер в фоновом потоке.

...