【问题标题】:No Adapter Attached, Skipping Layout on Fragment没有附加适配器,在片段上跳过布局
【发布时间】:2020-02-20 18:05:22
【问题描述】:

我尝试了几种不同的方法来解决这个问题,但它似乎并不想工作。我附上了所涉及的片段。当我使用搜索功能时,recyclerview 工作;但是,当我第一次加载页面时,我收到了错误

E/RecyclerView: No adapter attached; skipping layout

我认为这可能是 onCreate 与 onCreateView 的问题,但我不确定该放在哪里。

NewsFragment.java



    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment

        v = inflater.inflate(R.layout.fragment_news, container, false);
        swipeRefreshLayout = v.findViewById(R.id.swipeRefresh);
        recyclerView = v.findViewById(R.id.news_recyclerView);


        etQuery = v.findViewById(R.id.etQuery);
        btnSearch = v.findViewById(R.id.btnSearch);

        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));

        final String country = getCountry();

        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                retrieveJson("", country, API_KEY);
            }
        });
        retrieveJson("", country, API_KEY);


        btnSearch.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!etQuery.getText().toString().equals("")) {
                    swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
                        @Override
                        public void onRefresh() {
                            retrieveJson(etQuery.getText().toString(), country, API_KEY);
                        }
                    });
                    retrieveJson(etQuery.getText().toString(), country, API_KEY);
                } else {
                    swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
                        @Override
                        public void onRefresh() {
                            retrieveJson("", country, API_KEY);
                        }
                    });
                    retrieveJson("", country, API_KEY);
                }
            }
        });
        return v;

    }

    public void retrieveJson(String query ,String country, String apiKey){

        swipeRefreshLayout.setRefreshing(true);
        Call<Headlines> call;
        if (!etQuery.getText().toString().equals("")){
            call=NewsApiClient.getInstance().getApi().getSpecificData(query,apiKey);

        }else{
            call=NewsApiClient.getInstance().getApi().getHeadlines(country,apiKey);
        }

        call.enqueue(new Callback<Headlines>() {
            @Override
            public void onResponse(Call<Headlines> call, Response<Headlines> response) {
                if (response.isSuccessful() && response.body().getArticles() != null ){
                    swipeRefreshLayout.setRefreshing(false);
                    articles.clear();
                    articles = response.body().getArticles();
                    newsAdapter = new NewsAdapter(getContext(), articles);
                    recyclerView.setAdapter(newsAdapter);
                }
            }

            @Override
            public void onFailure(Call<Headlines> call, Throwable t) {
                swipeRefreshLayout.setRefreshing(false);
                Toast.makeText(getContext(), t.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
            }
        });

    }

    public String getCountry(){
        Locale locale = Locale.getDefault();
        String country = locale.getCountry();
        return country.toLowerCase();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


    }


}

【问题讨论】:

    标签: android android-studio android-fragments oncreate fragment-oncreateview


    【解决方案1】:

    在 onCreateView 上,您实际上没有设置任何适配器。相反,当您在 call.enqueue 回调中检索 json 数据时设置它,此回调被异步调用,因此第一次调用 onCreateView 时没有将适配器设置为 RecyclerView。为避免这种情况,请在 onCreateView 函数的开头设置一个带有空数据的适配器,如下所示(使 newsAdapter 成为当前片段的变量)

    recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
    newsAdapter = new NewsAdapter(getContext(), articles);
    recyclerView.setAdapter(newsAdapter);
    

    使文章成为当前片段的变量 并在您的 retriveJson 函数的回调中设置和适配器,只需使用数据更新文章数组并像这样调用 RecycleView 的 notifydatasetchanged 函数

    public void onResponse(Call<Headlines> call, Response<Headlines> response) {
       if (response.isSuccessful() && response.body().getArticles() != null ){
          swipeRefreshLayout.setRefreshing(false);
          articles.clear();
          articles = response.body().getArticles();
          newsAdapter.setData(articles);
          newsAdapter.notifyDataSetChanged()
       }
    }
    

    setData 是您必须在 NewsAdapter 类中创建的函数。 希望它有所帮助! 看看这个brief guide 如何使用 RecycleViews

    【讨论】:

    • 感谢您的回答!我正在阅读有关 Intent 和 recyclerviews 的指南,但我真的不明白 setData 在 NewsAdapter 类中是如何/在哪里出现的?
    • 是koitlin还是java?
    • setData 是您必须在适配器类中创建的函数,或者您可以公开保存适配器内数据的变量,或者按照我的建议,您可以创建这样的函数@ 987654324@
    猜你喜欢
    • 2018-07-21
    • 2021-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-09
    • 1970-01-01
    相关资源
    最近更新 更多