一直报错 No adapter attached; skipping layout,我不知道哪里出问题了,求指点,谢谢你们
package com.example.myapplication;
import android.os.Bundle;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.ObservableEmitter;
import io.reactivex.rxjava3.core.ObservableOnSubscribe;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.schedulers.Schedulers;
public class WanbanActivity extends AppCompatActivity {
private List<price> priceList;
private PriceAdapter adapter;
private RecyclerView recyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_wanban);
initView();
connCs();
}
private void initView() {
recyclerView = findViewById(R.id.recyler);
LinearLayoutManager manager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(manager);
}
private void showPrice(List<price> pri){
adapter=new PriceAdapter(this,priceList);
recyclerView.setAdapter(adapter);
}
public void connectwanban(){
new Thread(new Runnable() {
@Override
public void run() {
try {
Document document = Jsoup.connect("http://www.xinfadi.com.cn/getPriceData.html")
.data("query", "Java")
.userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 SLBrowser/8.0.1.5162 SLBChan/11")
.cookie("auth", "token")
.timeout(8000)
.ignoreContentType(true)
.post();
System.out.println(document);
Elements el = document.getElementsByTag("body");
String string = el.text();
System.out.println(string);
JSONObject jsonObject= null;
jsonObject = new JSONObject(string);
StringBuilder cs=new StringBuilder();
int current=jsonObject.getInt("current");
int limit=jsonObject.getInt("limit");
int count=jsonObject.getInt("count");
JSONArray jsonArray=jsonObject.getJSONArray("list");
for(int i=0;i<jsonArray.length();i++){
JSONObject object=jsonArray.getJSONObject(i);
String prodName=object.getString("prodName");
String prodCatid=object.getString("prodCatid");
String prodCat=object.getString("prodCat");
String lowPrice=object.getString("lowPrice");
String highPrice=object.getString("highPrice");
String place=object.getString("place");
String unitInfo=object.getString("unitInfo");
String pubDate=object.getString("pubDate");
String avgPrice=object.getString("avgPrice");
int id= object.getInt("id");
Log.d("ting","Json======"+id+"\t"+prodName+"\t"+unitInfo+"\t"+prodCatid+"\t"+
prodCat+"\t"+lowPrice+"\t"+highPrice+"\t"+avgPrice+"\t"+pubDate);
priceList=new ArrayList<>();
price pri=new price();
pri.setid(id);
pri.setplace(place);
pri.setavgPrice(avgPrice);
pri.sethighPrice(highPrice);
pri.setlowPrice(lowPrice);
pri.setprodCatid(prodCatid);
pri.setunitInfo(unitInfo);
pri.setpubDate(pubDate);
// pri.setprodpcatid(pri.prodpcatid);
pri.setprodPcat(prodCat);
pri.setprodName(prodName);
priceList.add(pri);
}
} catch (IOException e) {
throw new RuntimeException(e);
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
}).start();
}
private void connCs(){
priceList=new ArrayList<>();
Observable.create(new ObservableOnSubscribe<List<price>>() {
@Override
public void subscribe(@NonNull ObservableEmitter<List<price>> emitter) throws Throwable {
Document document = Jsoup.connect("http://www.xinfadi.com.cn/getPriceData.html")
.data("query", "Java")
.userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 SLBrowser/8.0.1.5162 SLBChan/11")
.cookie("auth", "token")
.timeout(8000)
.ignoreContentType(true)
.post();
System.out.println(document);
Elements el = document.getElementsByTag("body");
String string = el.text();
System.out.println(string);
JSONObject jsonObject= null;
jsonObject = new JSONObject(string);
StringBuilder cs=new StringBuilder();
int current=jsonObject.getInt("current");
int limit=jsonObject.getInt("limit");
int count=jsonObject.getInt("count");
JSONArray jsonArray=jsonObject.getJSONArray("list");
for(int i=0;i<jsonArray.length();i++){
price pri=new price();
JSONObject object=jsonArray.getJSONObject(i);
String prodName=object.getString("prodName");
String prodCatid=object.getString("prodCatid");
String prodCat=object.getString("prodCat");
String lowPrice=object.getString("lowPrice");
String highPrice=object.getString("highPrice");
String place=object.getString("place");
String unitInfo=object.getString("unitInfo");
String pubDate=object.getString("pubDate");
String avgPrice=object.getString("avgPrice");
int id= object.getInt("id");
Log.d("ting","Json======"+id+"\t"+prodName+"\t"+unitInfo+"\t"+prodCatid+"\t"+
prodCat+"\t"+lowPrice+"\t"+highPrice+"\t"+avgPrice+"\t"+pubDate);
pri.setid(id);
pri.setplace(place);
pri.setavgPrice(avgPrice);
pri.sethighPrice(highPrice);
pri.setlowPrice(lowPrice);
pri.setprodCatid(prodCatid);
pri.setunitInfo(unitInfo);
pri.setpubDate(pubDate);
// pri.setprodpcatid(pri.prodpcatid);
pri.setprodPcat(prodCat);
pri.setprodName(prodName);
priceList.add(pri);
emitter.onNext(priceList);
}
}
}) .observeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<List<price>>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(@NonNull List<price> priceList) {
showPrice(priceList);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
;
}
}
下面是adapter
package com.example.myapplication;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import java.util.List;
public class PriceAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
private List<price> priceList;
private Context context;
public PriceAdapter(Context context,List<price> obj){
this.context=context;
this.priceList=obj;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view= LayoutInflater.from(context).inflate(R.layout.item,parent,false);
return new PriceHolder(view);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewholder, int i) {
PriceHolder holder= (PriceHolder) viewholder;
final price pri=priceList.get(i);
holder.id.setText(pri.getid());
holder.hignPrice.setText(pri.gethignPrice());
holder.unitInfo.setText(pri.getunitInfo());
holder.pubDate.setText(pri.getpubDate());
holder.prodpcatid.setText(pri.getprodpcatid());
holder.prodPcat.setText(pri.getprodCat());
holder.prodName.setText(pri.getprodName());
holder.place.setText(pri.getplace());
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public int getItemCount() {
return priceList.size();
}
}
holder
package com.example.myapplication;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
public class PriceHolder extends RecyclerView.ViewHolder{
TextView id;
TextView prodName;
TextView proCatid;
TextView prodCat;
TextView prodpcatid;
TextView prodPcat;
TextView lowPrice;
TextView hignPrice;
TextView avgPrice;
TextView place;
TextView unitInfo;
TextView pubDate;
public PriceHolder(@NonNull View itemView) {
super(itemView);
id = itemView.findViewById(R.id.id);
prodName = itemView.findViewById(R.id.prodName);
prodCat = itemView.findViewById(R.id.prodCat);
pubDate = itemView.findViewById(R.id.pubDate);
unitInfo= itemView.findViewById(R.id.unitInfo);
place = itemView.findViewById(R.id.place);
avgPrice= itemView.findViewById(R.id.avgPrice);
hignPrice = itemView.findViewById(R.id.hignPrice);
lowPrice = itemView.findViewById(R.id.lowPrice);
hignPrice = itemView.findViewById(R.id.hignPrice);
}
}
提供参考实例方法:https://blog.csdn.net/yechaoa/article/details/78864631
参考这几篇文章看有没有帮助:
https://blog.csdn.net/yechaoa/article/details/78864631
https://www.jianshu.com/p/75cebed90b2f
https://blog.csdn.net/geniushorse/article/details/114128291
No adapter attached; skipping layout 原因、解决办法
当Adapter和LayoutManager 都没有的时候,就会抛出No … attached; skipping layout 异常
众所周知,RecyclerView的出现不光可以代替ListView,也可以代替GridView,所以啊大胸弟,你在用的时候要告诉RecyclerView你要代替的是哪个啊,就是所谓的初始化配置,不配置就会警告报错、不显示数据
分割线可以不设置,动画也可以不设置,但是LayoutManager必须设置。
随意示范一下
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(linearLayoutManager);
上面用的是LinearLayoutManager的第二个构造方法,必要的参数都有了,当然也可以用第一个构造,贴一下这个构造的代码:
/**
* @param context Current context, will be used to access resources.
* @param orientation Layout orientation. Should be {@link #HORIZONTAL} or {@link
* #VERTICAL}.
* @param reverseLayout When set to true, layouts from end to start.
*/
public LinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
setOrientation(orientation);
setReverseLayout(reverseLayout);
setAutoMeasureEnabled(true);
}
或者 简单版,默认 VERTICAL
mRecyclerView.setLayoutManager(new LinearLayoutManager(mContext));
/**
* Creates a vertical LinearLayoutManager
*
* @param context Current context, will be used to access resources.
*/
public LinearLayoutManager(Context context) {
this(context, VERTICAL, false);
}
当然,不要忘了 mRecyclerView.setAdapter(mAdapter);
参考一下这篇文章,用RecyclerView做布局,然后在启动界面的时候因为是从数据库或网络等地方获取数据有延迟,在没有获取到数据时候就开始加载RcyclerView就会出现RecyclerView: No adapter attached; skipping layout致使APP无缘无故崩溃。
https://blog.csdn.net/shendaoyu/article/details/121679574
在编写Android应用程序时,我们通常需要将UI界面元素放置在页面上,并确保它们之间具有正确的布局和位置。这是通过使用布局管理器来实现的,其中包括LinearLayout、RelativeLayout、ConstraintLayout等。但是,当我们在应用程序中出现“无法附加适配器; 跳过布局”错误时,就无法正确地布局UI元素。
该错误通常发生在使用RecyclerView或ListView等带有适配器的布局管理器时。适配器是用于将数据与UI元素(例如,RecyclerView中的ViewHolder)绑定在一起的组件。因此,如果我们在尝试设置RecyclerView或ListView的适配器时遇到此错误,则意味着该适配器无法附加到布局管理器上。
有几种可能导致这个错误的原因。其中一种可能是由于时间顺序问题导致的。在某些情况下,我们可能会在RecyclerView或ListView尚未完全构建的情况下尝试设置其适配器。这可能会导致问题,因为RecyclerView或ListView需要先构建其基本结构,然后才能让适配器与其附加。因此,如果我们要设置适配器,请确保RecyclerView或ListView已经完全构建。
另一个可能的原因是我们在使用RecyclerView或ListView时忘记了设置其布局管理器。这会导致适配器无法正确附加到布局管理器上。因此,在使用RecyclerView或ListView时,请确保设置其布局管理器。
还有一种可能的原因是我们在尝试设置适配器之前,尚未初始化要使用的数据源。这会导致适配器无法正确绑定数据源到UI元素上。
最后,我们还可以尝试清除应用程序缓存或重置设备来解决此错误。这是因为有时设备可能会在缓存问题或其他问题的情况下出现错误,从而导致无法正确附加适配器。
在解决此错误时,应该考虑到以上可能的原因,并采取适当的措施来解决问题。无论是确保RecyclerView或ListView已经完全构建,设置布局管理器,还是初始化数据源,都应该采取适当的措施来确保适配器能够成功附加到布局管理器上。
在计算机科学和软件开发中,适配器是一种常见的设计模式,它被用于将不同类之间的接口或数据格式转换为其他类所需的接口或数据格式。适配器模式是一种结构性模式,它关注的是对象之间的组合和复合。
在软件开发过程中,我们经常会遇到需要将不同类之间的接口或数据格式进行转换的情况。这种情况下,使用适配器模式可以避免代码的重复和修改,同时提高代码的可重用性和灵活性。
适配器模式通常涉及到以下三个角色:
目标接口:即需要被转换的目标接口或数据格式。在适配器模式中,我们通常定义一个目标接口,代表需要被转换成的接口或数据格式。
适配器:适配器是实现目标接口并封装适配者对象的类。适配器实现目标接口中定义的方法,并将这些方法转换为适配者对象的方法调用。
适配者:适配者是需要被转换的原始对象。适配器使用适配者对象来实现目标接口。
有两种类型的适配器:类适配器和对象适配器。类适配器使用多重继承来适配两个不兼容的接口,而对象适配器使用组合来适配两个不兼容的接口。对象适配器更加灵活,因为它可以通过组合来适配任意类。
在适配器模式中,适配器起到了桥梁的作用,使得不同的类能够协同工作。适配器模式通常用于以下场景:
要使用一个已经存在的类,但它的接口不符合需求。
要创建一个可复用的类,该类可以与多个不兼容的类协同工作。
要适配一个第三方库或框架,以便在自己的应用程序中使用。
适配器模式的优点如下:
复用性好:适配器模式可以使得不同的类相互合作,从而实现代码的复用。
灵活性好:适配器模式可以在不改变原始类的情况下实现不同类之间的兼容。
扩展性好:适配器模式可以很容易地添加新的适配器类,从而扩展系统的功能。
适配器模式的缺点如下:
过多的适配器会使得系统变得复杂,难以维护。
适配器模式可能会降低系统的性能,因为需要进行额外的数据转换。
在开发过程中,适配器模式是一种非常实用的设计模式,在需要将不同类之间的接口或数据格式进行转换的情况下,适配器模式可以使得代码更加简单、易于维护和扩展。
当Adapter和LayoutManager 都没有的时候,就会抛出No … attached; skipping layout 异常。不要忘了 mRecyclerView.setAdapter(mAdapter);
可以参考:
No adapter attached; skipping layout 原因、解决办法:https://blog.csdn.net/yechaoa/article/details/78864631
参考newbing
"No adapter attached; skipping layout" 错误通常在使用 RecyclerView 或 ListView 时出现,表示适配器未正确附加到布局中。这可能是由于以下几个原因导致的:
适配器未正确初始化或设置:请确保在布局文件中正确定义了 RecyclerView 或 ListView,并且在代码中正确初始化了适配器对象,并将其附加到布局中。例如,在使用 RecyclerView 时,您需要创建一个 RecyclerView.Adapter 的子类,并在代码中将其设置给 RecyclerView。
数据源为空或未更新:如果您的数据源为空,或者在数据源更新后未调用适配器的 notifyDataSetChanged() 方法,就会出现此错误。请确保在设置适配器之前,您的数据源已经被正确填充,并且在数据源更新后调用了 notifyDataSetChanged() 方法。
布局参数设置不正确:如果您在布局文件中使用了 RecyclerView 或 ListView,确保它们的布局参数设置正确。例如,RecyclerView 应该使用 layout_width 和 layout_height 设置为 match_parent 或具体的数值。
布局管理器未设置:对于 RecyclerView,您需要设置一个布局管理器来管理列表项的排列方式。请确保在代码中为 RecyclerView 设置了正确的布局管理器,例如 LinearLayoutManager、GridLayoutManager 等。
recyclerview 布局没有设置