在android中使用位图下载后图像顺序出错

时间:2016-01-13 07:52:57

标签: android bitmapimage

我希望显示从URL下载的数据和图像,但是在从URL下载图像后,图像的顺序出错了。我使用卡片视图和回收视图显示我的数据和图像,但第一张卡片中的第一张图片转到第二张,而第三张卡片上的第二张图片和第三张图片将丢失,第一张图片将清空。有人可以帮我这个吗?

以下是我的代码。 TQ

SimpleCardViewAdapter.java

public class SimpleCardViewAdapter extends RecyclerView.Adapter<SimpleCardViewAdapter.ViewHolder> {

private List<CardViewData> mDataset;
Bitmap downloadedBitmap;
ImageView row_image;

public SimpleCardViewAdapter(List<CardViewData> dataset) {
    mDataset = dataset;
}

@Override
public ViewHolder onCreateViewHolder(final ViewGroup viewGroup, int i) {
    View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.row_layout, viewGroup, false);
    return new ViewHolder(v);
}

@Override
public void onBindViewHolder(final ViewHolder viewHolder, int i) {
    final CardViewData cardViewData = mDataset.get(i);

    viewHolder.mTitle.setText(cardViewData.getTitle());
    viewHolder.mDescription.setText(cardViewData.getDescription());
    String var = cardViewData.getImage();

    new Thread(new getImageTask(var)).start();
    viewHolder.mImage.setImageBitmap(downloadedBitmap);

    viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Toast.makeText(v.getContext(), "Title: " + cardViewData.getTitle(), Toast.LENGTH_SHORT).show();
        }
    });
}

class getImageTask implements Runnable {

    String imageUrl;

    getImageTask(String imgUrl){
        imageUrl = imgUrl;
    }

    @Override
    public void run() {
        try {
            URL url = new URL(imageUrl);
            downloadedBitmap = BitmapFactory.decodeStream(url.openConnection().getInputStream());
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        Message msg = new Message();
        Bundle b = new Bundle();
        b.putString("mfeApi", "1");
        msg.setData(b);
        handlerGroupedProductsImage.sendMessage(msg);
    }

}

Handler handlerGroupedProductsImage = new Handler() {
    public void handleMessage(Message msg) {
        Bundle b = msg.getData();
        String done = b.getString("mfeApi");
    };
};



@Override
public int getItemCount() {
    return mDataset == null ? 0 : mDataset.size();
}

public static class ViewHolder extends RecyclerView.ViewHolder {

    public TextView mTitle;
    public TextView mDescription;
    public ImageView mImage;

    public ViewHolder(View itemView) {
        super(itemView);

        mTitle = (TextView) itemView.findViewById(R.id.row_title);
        mDescription = (TextView) itemView.findViewById(R.id.row_description);
        mImage = (ImageView) itemView.findViewById(R.id.row_image);
    }
}

Activity.java

private void getData() {

    try {

        final String toSend = "http://www.test.com.my/test/api/kipcard_helpAPI.php";

        new Thread(new Runnable() {
            @Override
            public void run() {
                URL url = null;
                HttpURLConnection conn = null;
                String receivedString = null;
                try {
                    url = new URL(toSend);
                    conn = (HttpURLConnection) url.openConnection();
                    conn.setRequestMethod("POST");
                    InputStream in = new BufferedInputStream(conn.getInputStream());
                    receivedString = IOUtils.toString(in, "UTF-8");
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                Message msg = new Message();
                Bundle b = new Bundle();
                b.putString("mfeApi", receivedString);
                msg.setData(b);
                hGet.sendMessage(msg);
            }
        }).start();

    } catch (Exception e) {
        e.printStackTrace();
    }

}



Handler hGet = new Handler() {
    public void handleMessage(Message msg) {
        Bundle b = msg.getData();
        String s = b.getString("mfeApi");

        items =  s.split("\\|\\|");
        size = items.length;

        List <CardViewData> list =  new ArrayList<CardViewData>();
        for(int i = 0 ; i <= size-3 ; i+=3){
            Log.d("here",items[i] +"" );
            //new Thread(new getImageTask(imahr)).start();
            list.add(new CardViewData(items[i+2], items[i+3], items[i+1]));
        }
        mAdapter = new SimpleCardViewAdapter(list);

        mRecyclerView.setAdapter(mAdapter);
    };
};

3 个答案:

答案 0 :(得分:1)

问题在于:

   new Thread(new getImageTask(var)).start();
   viewHolder.mImage.setImageBitmap(downloadedBitmap);

由于线程执行并行工作不同步downloadedBitmap可以保留另一个线程&#34; old&#34;结果

答案 1 :(得分:1)

而不是

new Thread(new getImageTask(var)).start();
viewHolder.mImage.setImageBitmap(downloadedBitmap);

尝试使用

 final int position = i;
 viewHolder.position = i;
 new AsyncTask<Object, Void, Bitmap>() {
        private AlbumViewHolder v;

        @Override
        protected Bitmap doInBackground( Object[] params ) {
            v = (AlbumViewHolder) params[ 0 ];
            // download here your image
            return b;
        }

        @Override
        protected void onPostExecute( Bitmap result ) {
            super.onPostExecute( result );
            if ( v.position == position && result != null ) {
                // If this item hasn't been recycled already, hide the
                // progress and set and show the image
                    v.mImageView.setImageBitmap( result );
                    v.mImageView.setVisibility( View.VISIBLE );
                    v.mProgressBar.setVisibility( View.GONE );
            }
        }
    }.execute( viewHolder );

并在ViewHolder中:

public static class ViewHolder extends RecyclerView.ViewHolder {

    public TextView mTitle;
    public TextView mDescription;
    public ImageView mImage;
    public int position;

    public ViewHolder(View itemView) {
        super(itemView);

        mTitle = (TextView) itemView.findViewById(R.id.row_title);
        mDescription = (TextView) itemView.findViewById(R.id.row_description);
        mImage = (ImageView) itemView.findViewById(R.id.row_image);
    }
}

还有一件事 - 你的ViewHolder应该有位置参数。并考虑缓存。

答案 2 :(得分:0)

试试这个: 将Context添加到构造函数

public SimpleCardViewAdapter(List<CardViewData> dataset, Activity activity){
   this.mActivity = activity;
}

更改onBindViewHolder方法:

 new Thread(new getImageTask(var, viewHolder.mImage)).start();

并改变你的任务:

    class getImageTask implements Runnable {

        String imageUrl;
        ImageView imageView

        getImageTask(String imgUrl, ImageView imageView){
            imageUrl = imgUrl;
            this.imageView = imageView;
        }

        @Override
        public void run() {
            try {

                URL url = new URL(imageUrl);
                //change this line also
                Bitmap bitmap = BitmapFactory.decodeStream(url.openConnection().getInputStream());
                //set you downloaded image now...
                //new change ....

                mActivity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                       //Your code to run in GUI thread here
                       if(bitmap != null)
                       imageView.setImageBitmap(bitmap);
                    }
                });


            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            Message msg = new Message();
            Bundle b = new Bundle();
            b.putString("mfeApi", "1");
            msg.setData(b);
            handlerGroupedProductsImage.sendMessage(msg);
        }

    }

***但它不会缓存位图,每次在应用程序内滚动回收器时它会一次又一次地下载它。