从URL取图片存入ArrayList并在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);
额外检查点
- 网络权限:确保AndroidManifest.xml里已经添加了网络权限:
<uses-permission android:name="android.permission.INTERNET"/> - URL有效性:检查
urlFile的地址是否能在浏览器正常打开,确保是有效的图片链接。 - GridView布局:检查GridView的
layout_width和layout_height是否设置为match_parent或合适的值,有没有被其他View遮挡。
内容的提问来源于stack exchange,提问作者O.D

