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

从URL取图片存入ArrayList并在GridView显示空白问题求助

排查GridView空白问题的关键修复点

咱们来拆解下你的GridView为啥空白——代码里有好几个关键问题在搞事情,一个个来解决:

1. Adapter里加载图片的方式完全错误

你的urlFile是网络图片的URL字符串,但你却用setImageResource(Integer.parseInt(list.get(position).urlFile))——这个方法是用来加载本地drawable/mipmap资源ID的(比如R.drawable.ic_launcher这种int值),把URL字符串转int肯定会抛NumberFormatException,而且完全不是加载网络图片的正确姿势。

正确的做法是在Adapter的getView里用Picasso把网络图片绑定到ImageView上,就像你在BottomSheetDialog里尝试做的那样,但要绑定到具体的View。

2. 回调线程可能不是UI线程,直接操作UI会失效

Communicator的回调大概率是在子线程里执行的,而Android规定所有UI操作(比如设置Adapter、更新View)必须在主线程执行。你直接在回调里设置Adapter,很可能因为线程问题导致UI不更新。

解决方法是把设置Adapter/更新数据的代码用runOnUiThread包裹,切换到主线程执行。

3. EmojiModel的对象创建逻辑混乱,数据添加错误

你在循环里的操作逻辑绕了弯路,还加错了对象:

emojiModel = new EmojiModel((String) response2.get("urlFile"));
emojiModel.init(t); // 初始化了id和price
emojieModels.add(new EmojiModel(emojiUrl)); // 却加了一个全新的、没初始化id/price的对象

你应该直接把那个已经init过的emojiModel添加到列表里,而不是重新创建一个新对象。

4. Adapter中布局文件不匹配

你在Adapter构造函数里给父类传的布局是R.layout.smiles_items_layout,但getView里inflate的却是R.layout.gifts_layout_2。如果gifts_layout_2里没有R.id.smile_image_view这个ImageView,findViewById会返回null,自然显示不了任何内容。必须保证inflate的布局和你要找的控件对应。

5. 无用的Picasso调用

你在BottomSheetDialog的循环里调用Picasso.with(getApplicationContext()).load(emojiUrl);——这行代码只是发起了一个图片请求,但没有绑定到任何ImageView,完全是多余的,应该删掉,图片加载放在Adapter里做才是正确的。


修正后的代码示例

1. 修正EmojiAdapter.java

public class EmojiAdapter extends ArrayAdapter<EmojiModel> {
    Context context;
    ArrayList<EmojiModel> list;

    public EmojiAdapter(Context context, ArrayList<EmojiModel> list) {
        super(context, R.layout.smiles_items_layout, list);
        this.context = context;
        this.list = list;
    }

    @NonNull
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // 用ViewHolder模式优化性能,避免重复findViewById
        ViewHolder holder;
        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            // 确保inflate的是正确的布局,里面包含smile_image_view
            convertView = inflater.inflate(R.layout.smiles_items_layout, parent, false);
            holder = new ViewHolder();
            holder.imageView = convertView.findViewById(R.id.smile_image_view);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        EmojiModel model = list.get(position);
        // 用Picasso加载网络图片,可添加占位图和错误图优化体验
        Picasso.with(context)
                .load(model.urlFile)
                .placeholder(R.drawable.default_emoji) // 可选:加载中的占位图
                .error(R.drawable.error_emoji) // 可选:加载失败的占位图
                .into(holder.imageView);

        return convertView;
    }

    // ViewHolder内部类,缓存控件提升性能
    private static class ViewHolder {
        ImageView imageView;
    }
}

2. 修正BottomSheetDialog_Smiles.java里的回调代码

Communicator.getInstance().on("subscribe start", new Emitter.Listener() {
    @Override
    public void call(Object... args) {
        try{
            JSONDictionary response = (JSONDictionary) args[0];
            String str = response.get("emojiPack").toString();
            JSONArray emojies = new JSONArray(str);
            
            // 先清空列表,避免重复加载时数据叠加
            emojieModels.clear();
            
            for(int i=0;i<emojies.length();i++){
                JSONObject response2 = emojies.getJSONObject(i);
                EmojiModel emojiModel = new EmojiModel(response2.getString("urlFile"));
                // 如果需要id和price,执行init初始化
                JSONDictionary t = JSONDictionary.fromString(response2.toString());
                emojiModel.init(t);
                // 添加初始化完成的对象到列表
                emojieModels.add(emojiModel);
            }
            
            // 切换到主线程更新UI,这一步非常关键
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // 优化:如果已有Adapter,直接通知数据变化,不用重新创建
                    if(gridView2.getAdapter() != null){
                        ((EmojiAdapter) gridView2.getAdapter()).notifyDataSetChanged();
                    } else {
                        EmojiAdapter emojiAdapter = new EmojiAdapter(getApplicationContext(), emojieModels);
                        gridView2.setAdapter(emojiAdapter);
                    }
                }
            });
            
        } catch (JSONException e) {
            e.printStackTrace();
            // 主线程提示加载失败
            runOnUiThread(() -> Toast.makeText(getApplicationContext(), "表情加载失败", Toast.LENGTH_SHORT).show());
        }
    }
});

// 注释掉这部分,因为回调里会初始化Adapter,初始时GridView可以是空的
// EmojiAdapter emojiAdapter = new EmojiAdapter(getApplicationContext(), emojieModels);
// gridView2.setAdapter(emojiAdapter);

额外检查点

  1. 网络权限:确保AndroidManifest.xml里已经添加了网络权限:
    <uses-permission android:name="android.permission.INTERNET"/>
    
  2. URL有效性:检查urlFile的地址是否能在浏览器正常打开,确保是有效的图片链接。
  3. GridView布局:检查GridView的layout_width和layout_height是否设置为match_parent或合适的值,有没有被其他View遮挡。

内容的提问来源于stack exchange,提问作者O.D

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:39:20