【问题标题】:RecyclerView: No adapter attached; skipping layout ProblemRecyclerView:没有附加适配器;跳过布局问题
【发布时间】:2021-04-28 03:37:03
【问题描述】:

我收到了错误:

RecyclerView:没有附加适配器;跳过布局

我检查了人们针对此问题给出的其他一些答案,但没有运气。

适配器:

public class MyAdapter extends RecyclerView.Adapter<com.example.myapplication.MyAdapter.MyViewHolder> {

    private Context context;
    private List<HeadlineModel> headlineModelList;

    public MyAdapter(Context context, List<HeadlineModel> headlineModelList) {
        this.context = context;
        this.headlineModelList = headlineModelList;
    }

    @NonNull
    @Override
    public com.example.myapplication.MyAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view= LayoutInflater.from(context).inflate(R.layout.news_item_layout,parent,false);
        return new MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull final com.example.myapplication.MyAdapter.MyViewHolder holder, int position) {
        final HeadlineModel headlineModel=headlineModelList.get(position);
        holder.newTitle.setText(headlineModel.getTitle());
        holder.newsDescription.setText(headlineModel.getDescription());
        holder.newsDescription.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Uri uri= Uri.parse(headlineModel.getUrl());
                Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                context.startActivity(intent);
                //Log.v("SSSSSS",headlineModel.getUrl());
            }
        });
        holder.newsName.setText(headlineModel.getName());
        holder.newsTime.setText(headlineModel.getPublishedAt());
        Glide.with(context).load(headlineModel.getUrlToImage())
                .thumbnail(0.5f)
                .into(holder.newsImage);
    }

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

    public class MyViewHolder extends RecyclerView.ViewHolder {
        TextView newTitle;
        TextView newsDescription;
        TextView newsName;
        TextView newsTime;
        ImageView newsImage;

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            newTitle=itemView.findViewById(R.id.tv_news_title);
            newsDescription=itemView.findViewById(R.id.tv_news_desc);
            newsName=itemView.findViewById(R.id.tv_name);
            newsTime=itemView.findViewById(R.id.tv_news_date);
            newsImage=itemView.findViewById(R.id.im_news_image);
        }
    }
}

我的片段中 onCreateView 中的回收器视图是这样初始化的:

RecyclerView recyclerView;
    com.example.myapplication.MyAdapter myAdapter;
    private ProgressDialog progressDialog;

    List<com.example.myapplication.HeadlineModel> headlineModelList;

    private static final String URL="http://newsapi.org/v2/top-headlines?country=in&apiKey=cbd46bd6a4f54fe69d0cb261dbe1a878";

    public HeadlinesFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View rootview=inflater.inflate(R.layout.fragment_headlines, container, false);
        // Inflate the layout for this fragment

        recyclerView=rootview.findViewById(R.id.headRecyclerView);
        headlineModelList=new ArrayList<>();
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL,false));

        progressDialog=new ProgressDialog(getContext(),R.style.ProgressColor);
        progressDialog.setMessage("loading...");
        progressDialog.show();
        loadData();
        return rootview;
    }

调用的loadData()函数

private void loadData() {
        progressDialog.setMessage("Loading data...");
        //progressDialog.show();

        JsonObjectRequest jsonObjectRequest=new JsonObjectRequest(Request.Method.GET, URL, null, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                progressDialog.dismiss();
                try {
                    JSONArray jsonArray=response.getJSONArray("articles");
                    for (int i=0;i<jsonArray.length();i++){
                        JSONObject jsonObject=jsonArray.getJSONObject(i);
                        String title=jsonObject.getString("title");
                        String desc=jsonObject.getString("description");
                        String url=jsonObject.getString("url");
                        String urlToImage=jsonObject.getString("urlToImage");
                        String publishedAt=jsonObject.getString("publishedAt");
                        JSONObject source=jsonObject.getJSONObject("source");
                        String name=source.getString("name");

                        // for formatting time and date //

                        String year=publishedAt.substring(0,4);
                        String month=publishedAt.substring(5,7);
                        String date=publishedAt.substring(8,10);
                        String hour=publishedAt.substring(11,13);

                        //String hour="11";
                        String min=publishedAt.substring(14,16);
                        //Log.v("XXXXXX",min);
                        String updatedDate=date.concat("-").concat(month).concat("-").concat(year).concat("  ");
                        String print="";
                        int convertHour= Integer.parseInt(hour);
                        int convertMin= Integer.parseInt(min);
                        if (convertHour==12) {
                            convertHour=12;
                            print="PM";
                        }
                        else if (convertHour>11&&convertMin>0){
                            convertHour=convertHour-12;
                            print="PM";
                        }else {
                            print="AM";
                        }
                        String newHour= String.valueOf(convertHour);
                        String updatedTime=updatedDate.concat(newHour).concat(":").concat(min).concat(" ").concat(print);


                        myAdapter=new com.example.myapplication.MyAdapter(getContext(),headlineModelList);
                        com.example.myapplication.HeadlineModel headlineModel=new com.example.myapplication.HeadlineModel(name,title,desc,url,urlToImage,updatedTime);
                        headlineModelList.add(headlineModel);
                        recyclerView.setAdapter(myAdapter);
                        myAdapter.notifyDataSetChanged();
                    }

                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {

            }
        })
        {
            @Override
            protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
                try {
                    Cache.Entry cacheEntry = HttpHeaderParser.parseCacheHeaders(response);
                    if (cacheEntry == null) {
                        cacheEntry = new Cache.Entry();
                    }
                    final long cacheHitButRefreshed = 3 * 60 * 1000; // in 3 minutes cache will be hit, but also refreshed on background
                    final long cacheExpired = 24 * 60 * 60 * 1000; // in 24 hours this cache entry expires completely
                    long now = System.currentTimeMillis();
                    final long softExpire = now + cacheHitButRefreshed;
                    final long ttl = now + cacheExpired;
                    cacheEntry.data = response.data;
                    cacheEntry.softTtl = softExpire;
                    cacheEntry.ttl = ttl;
                    String headerValue;
                    headerValue = response.headers.get("Date");
                    if (headerValue != null) {
                        cacheEntry.serverDate = HttpHeaderParser.parseDateAsEpoch(headerValue);
                    }
                    headerValue = response.headers.get("Last-Modified");
                    if (headerValue != null) {
                        cacheEntry.lastModified = HttpHeaderParser.parseDateAsEpoch(headerValue);
                    }
                    cacheEntry.responseHeaders = response.headers;
                    final String jsonString = new String(response.data,
                            HttpHeaderParser.parseCharset(response.headers));
                    return Response.success(new JSONObject(jsonString), cacheEntry);
                } catch (UnsupportedEncodingException | JSONException e) {
                    return Response.error(new ParseError(e));
                }
            }

            @Override
            protected void deliverResponse(JSONObject response) {
                super.deliverResponse(response);
            }

            @Override
            public void deliverError(VolleyError error) {
                super.deliverError(error);
            }

            @Override
            protected VolleyError parseNetworkError(VolleyError volleyError) {
                return super.parseNetworkError(volleyError);
            }
        };

        RequestQueue queue= Volley.newRequestQueue(getContext());
        queue.add(jsonObjectRequest);

    }

有谁知道我做错了什么?

【问题讨论】:

标签: java android android-studio android-recyclerview


【解决方案1】:

在 API 调用成功之前设置适配器,因为您的 API 响应是异步的,直到需要时间取决于响应大小、网络速度等,直到需要创建回收器视图并且它没有适配器。 您可以在调用 loadData() 之前设置适配器,稍后当您获得响应列表时,在您的 recylerview 的适配器中设置数据并在适配器上调用 notify。

【讨论】:

    【解决方案2】:

    myAdapter=new com.example.myapplication.MyAdapter(getContext(),headlineModelList); recyclerView.setAdapter(myAdapter);

    在 onCreateView 方法和 myAdapter.notifyDataSetChanged() 上使用它; API成功时使用它

    【讨论】:

      猜你喜欢
      • 2018-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-15
      • 1970-01-01
      • 2019-04-07
      • 2021-11-04
      • 2020-01-09
      相关资源
      最近更新 更多