You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Volley+Picasso解析JSON后RecyclerView无显示,报“No adapter attached”错误

问题排查与解决方案

嘿,我帮你梳理了下问题,你遇到的No adapter attached : skipping layout警告以及界面无内容显示,其实是由几个代码逻辑错误和初始化顺序问题导致的,我会一步步给你修复:

核心问题点梳理

  1. RecyclerView初始化时未绑定适配器:你在Volley异步请求回调里才设置适配器,而布局绘制时RecyclerView还没拿到适配器,就会抛出那个警告
  2. UserInfo类的getter/setter完全混乱:这会导致你传递的名称和图片路径完全错位,数据根本没法正确显示
  3. Adapter中控件ID查找错误:布局里的ImageButton是imagebtn,但你在Adapter里找的是image,导致图片加载失败
  4. MainActivity错误查找子项控件:你直接在Activity里找CardView里的控件,这些控件属于RecyclerView的子项,应该由Adapter的ViewHolder来管理
  5. JSON解析时图片路径拼接错误:你把字段名和图片名拼在一起了,导致取到错误的字段值
  6. Toast未调用show():异常提示根本弹不出来,你没法及时发现解析错误

具体修复步骤

1. 彻底修复UserInfo类的逻辑

你的UserInfo类的getName()返回的是image_link,setName()设置的也是image_link,完全搞反了,这是最致命的错误,修改后如下:

public class UserInfo {
    private String name;
    private String imageLink;

    // 构造方法要和属性对应,你之前的构造参数也错了
    public UserInfo(String name, String imageLink) {
        this.name = name;
        this.imageLink = imageLink;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getImageLink() {
        return imageLink;
    }

    public void setImageLink(String imageLink) {
        this.imageLink = imageLink;
    }
}

2. 修正MainActivity的初始化逻辑

(1)删除错误的控件查找代码

你在Activity里找imagebtn和description是完全错误的,这些属于RecyclerView的子项布局,删除这两行:

// 删掉这两行!
imageButton = findViewById(R.id.imagebtn);
textView = findViewById(R.id.description);

(2)提前设置空适配器解决警告

在RecyclerView初始化时就绑定一个空适配器,避免布局绘制时无适配器的警告:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    progressbar = findViewById(R.id.progressBar);
    progressbar.setVisibility(View.VISIBLE);
    
    mRecyclerview = findViewById(R.id.recycler_view);
    mRecyclerview.setHasFixedSize(true);
    mRecyclerview.setLayoutManager(new LinearLayoutManager(this));
    
    mExampleList = new ArrayList<>();
    // 提前初始化适配器并绑定,解决No adapter警告
    mExampleAdapter = new ExampleAdapter(MainActivity.this, mExampleList);
    mRecyclerview.setAdapter(mExampleAdapter);
    mExampleAdapter.setOnItemClickListener(MainActivity.this);
    
    mRequestQueue = Volley.newRequestQueue(this);
    jsonParse();
}

(3)修正JSON解析的图片路径

你之前的代码把字段名和图片名拼在一起了,导致取的字段是logo_pathcivil.png,这肯定不对,修改成正确的路径拼接:

// 原错误代码:
// String image = obj.getString("logo_path" + "civil.png");
// 修改为(假设接口返回的logo_path是路径前缀,比如"http://xelwel.com.np/hamrosewaapp/uploads/images/logo/"):
String logoPath = obj.getString("logo_path");
// 拼接完整图片路径
String image = logoPath + "civil.png";
// 如果接口返回的logo_path已经是完整图片地址,直接取就行:
// String image = obj.getString("logo_path");

(4)更新数据后通知Adapter

在JSON解析完成后,不需要重新创建Adapter,直接更新数据并通知Adapter刷新:

try {
    JSONObject jsonObject = new JSONObject(response);
    JSONArray jsonArray = jsonObject.getJSONArray("org_list");
    
    // 先清空列表,避免重复加载数据
    mExampleList.clear();
    for (int i = 0; i < jsonArray.length(); i++) {
        JSONObject obj = jsonArray.getJSONObject(i);
        String hsname = obj.getString("orga_organame");
        String logoPath = obj.getString("logo_path");
        String image = logoPath + "civil.png";
        mExampleList.add(new UserInfo(hsname, image));
    }
    // 通知Adapter数据更新
    mExampleAdapter.notifyDataSetChanged();
    progressbar.setVisibility(View.GONE);
} catch (JSONException e) {
    // 修复Toast,加上show()
    Toast.makeText(getApplicationContext(),"Error Parsing Data", Toast.LENGTH_LONG).show();
    e.printStackTrace();
}catch (Exception e) {
    Toast.makeText(getApplicationContext(),"Something went wrong", Toast.LENGTH_LONG).show();
    e.printStackTrace();
}

3. 修复ExampleAdapter的控件查找错误

你的Adapter里ViewHolder找的ImageView ID是image,但布局里的ImageButton ID是imagebtn,导致控件为null,修改如下:

public class ViewHolder extends RecyclerView.ViewHolder {
    public TextView textView;
    public ImageButton imageView; // 注意这里是ImageButton,和布局一致

    public ViewHolder(View itemView) {
        super(itemView);
        textView = itemView.findViewById(R.id.description);
        // 修正ID为imagebtn
        imageView = itemView.findViewById(R.id.imagebtn);
        
        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(mListener!= null){
                    int position = getAdapterPosition();
                    if (position!= RecyclerView.NO_POSITION){
                        mListener.onItemClick(position);
                    }
                }
            }
        });
    }
}

同时,onBindViewHolder里的图片加载也要对应:

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    UserInfo info = mExampleList.get(position);
    String imageUrl = info.getImageLink();
    String hsname = info.getName();
    holder.textView.setText(hsname);
    Picasso.with(mcontext).load(imageUrl).fit().centerInside().into(holder.imageView);
}

4. 确保添加网络权限

检查你的AndroidManifest.xml里有没有添加网络权限,没有的话加上:

<uses-permission android:name="android.permission.INTERNET" />

完成以上所有修改后,你的RecyclerView应该能正常加载并显示数据,No adapter attached的警告也会消失,图片和文字都能正确显示啦!

内容的提问来源于stack exchange,提问作者Ayush Katuwal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:58:27