在自己的BaseAdapter里面开启异步任务获取Bitmap,如何setImageBitmap()

在自己的BaseAdapter里面开启异步任务获取Bitmap,如何setImageBitmap()

public class FoodAdapter extends BaseAdapter {

    private Context mContext;
    private List<Food> mData;

    public FoodAdapter(Context context, List<Food> data) {
        mContext = context;
        mData = data;
    }

    @Override
    public int getCount() {
        return mData.size();
    }

    @Override
    public Food getItem(int position) {
        return mData.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder = null;

        if (convertView == null) {
            convertView = LayoutInflater.from(mContext).inflate(R.layout.fragment_index_goodlist_item,parent,false);
            viewHolder = new ViewHolder(convertView);
            viewHolder.findViews();
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        Food food = mData.get(position);
        
        //获取Bitmap并加载ImageView
        MyAsynTask.BitmapAsyncTask bitmapAsyncTask = new MyAsynTask.BitmapAsyncTask(food.getImg());
        bitmapAsyncTask.execute();
        bitmapAsyncTask.setOnDataFinishedListener(new MyAsynTask.OnDataFinishedListener() {
            @Override
            public void onDataSuccess(Object result) {
//                (Bitmap) result;
                FoodAdapter.super.notifyDataSetChanged();
            }

            @Override
            public void onDataFailure() {
                Toast.makeText(mContext, "加载图片失败",Toast.LENGTH_SHORT).show();
            }
        });

        //加载其他控件
        viewHolder.mTvName.setText(food.getName());
        viewHolder.mTvDescription.setText(food.getDescription());
        viewHolder.mTvPrice.setText("¥"+food.getPrice());
        viewHolder.mTvAction.setText(food.getAction());
        viewHolder.mTvCount.setText("已售:"+food.getCount());

        return convertView;
    }

    private class ViewHolder {
        ImageView mIvImg;
        TextView mTvName, mTvDescription, mTvPrice, mTvAction, mTvCount;
        View mView;
        public ViewHolder (View view){
            this.mView = view;
        }

        private void findViews() {
            mIvImg = mView.findViewById(R.id.id_iv_img);
            mTvName = mView.findViewById(R.id.id_tv_name);
            mTvDescription = mView.findViewById(R.id.id_tv_description);
            mTvPrice = mView.findViewById(R.id.id_tv_price);
            mTvAction = mView.findViewById(R.id.id_tv_action);
            mTvCount = mView.findViewById(R.id.id_tv_count);
        }
    }
}

在上面内部方法onDataSuccess(Object result)中,如何调用viewHolder去设置已经获得的(Bitmap)result呢?或许只能用Handler来处理?

public class MyAsynTask {
    //获取JSON中的照片
    public static class BitmapAsyncTask extends AsyncTask<String, Void, Bitmap> {
        private String mUrl;
        private OnDataFinishedListener onDataFinishedListener;

        public BitmapAsyncTask(String url) {
            this.mUrl = url;
        }

        public void setOnDataFinishedListener(OnDataFinishedListener onDataFinishedListener) {
            this.onDataFinishedListener = onDataFinishedListener;
        }

        @Override
        protected Bitmap doInBackground(String... strings) {
            InputStream in = null;
            try {
                URL url = new URL(strings[0]);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setRequestMethod("GET");
                connection.setConnectTimeout(5000);

                if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                    in = connection.getInputStream();
                    Bitmap bitmap = BitmapFactory.decodeStream(in);
                    in.close();
                    return bitmap;
                }
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (in != null)
                        in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return null;
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            super.onPostExecute(bitmap);
            if (bitmap != null) {
                onDataFinishedListener.onDataSuccess(bitmap);
            } else {
                onDataFinishedListener.onDataFailure();
            }
        }
    }

    public interface OnDataFinishedListener {
        public void onDataSuccess(Object result);

        public void onDataFailure();
    }
}


正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

1回答
好帮手慕雪 2020-09-24 10:32:46

http://img1.sycdn.imooc.com//climg/5f6c04d80936c22008840446.jpg

同学就在这里给对应的ImageView设置bitmap就可以了。另外,为什么要 FoodAdapter.super.notifyDataSetChanged();父类通知呢? FoodAdapter.this.notifyDataSetChanged();就可以了。祝:学习愉快

  • 提问者 AgonyX #1
    是把viewHolder传进去然后设置图片是吗
    2020-09-24 11:06:42
  • 提问者 AgonyX #2
    //获取Bitmap并加载ImageView MyAsynTask.BitmapAsyncTask bitmapAsyncTask = new MyAsynTask.BitmapAsyncTask(food.getImg(), viewHolder); bitmapAsyncTask.execute(); bitmapAsyncTask.setOnDataFinishedListener(new MyAsynTask.OnDataFinishedListener() { @Override public void onDataSuccess(Object result, ViewHolder viewHolder) { viewHolder.mIvImg.setImageBitmap((Bitmap) result); FoodAdapter.this.notifyDataSetChanged(); } @Override public void onDataFailure() { Toast.makeText(mContext, "加载图片失败",Toast.LENGTH_SHORT).show(); } }); 我把viewHolder传进去来设置bitmap,但是发生了 https://class.imooc.com/course/qadetail/194645 这里面的事情。主要现象是一加载listview的时候文本什么都加载好了,但是bitmap只在第一个item处轮流加载,然后再慢慢分配到其他item的位置上,而且到最后还会有item没加载成功bitmap
    2020-09-24 11:23:23
  • 好帮手慕雪 回复 提问者 AgonyX #3
    你的data里哪个字段是用来放bitmap的?就在onDataSuccess()里更新一下这个值,然后notifyDataSetChanged就可以了。如果还是不行,则直接提交作业,写一个简单的说明文档 ,说明一下你代码的情况,老师这样能看到你所有的代码,进行测试,给出建议方案
    2020-09-24 16:46:59
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
2.Android 网络操作与流行框架
  • 参与学习           人
  • 提交作业       220    份
  • 解答问题       1800    个

本阶段是联网及数据处理的必备技能。课程从网络基础知识到线程间协同工作、异步下载处理;从文件存储、到轻量级数据库SQLite的使用;最后利用最流程的第三方框架助你快速开发企业级APP。

了解课程
请稍等 ...
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师