简体   繁体   中英

Images GridView doesn't invalidate

I've been trying to update my Images GridView .
The images get updated only if I set the adapter again. Setting the adapter again makes my activity scroll back to top and I try to avoid that.

Here's some code:

private class LoadImagesTask extends AsyncTask<Object,Void, Object> {
    private ImageAdapter imageAdapter;
    private ArrayList<Integer> idsArray;
    @Override
    protected void onPreExecute() {   
        imageAdapter = new ImageAdapter(getApplicationContext());
        Bitmap bmap = BitmapFactory.decodeResource(getResources(),
                R.drawable.locked_image);
        idsArray = dbHelper.getPicturesIdsByAlbumId(1);
        for(int i = 0;i<idsArray.size();i++){
            imageAdapter.bitmaps.add(bmap);
        }

        gridView.setAdapter(imageAdapter);
    }
    @Override
    protected Void doInBackground(Object... arg) {

        for(int i = 0;i<idsArray.size();i++){
            byte[] data = dbHelper.getPictureById(idsArray.get(i)).littlePicBytes;
            imageAdapter.bitmaps.set(i, BitmapFactory.decodeByteArray(data, 0, data.length));
            publishProgress(); //********** This line calls onProgressUpdate()  *********
        }
        return null;

    }
}

Now, this code works for updating the views:

@Override
protected void onProgressUpdate(Void... params) {
    gridView.setAdapter(imageAdapter);
}

But this doesnt:

@Override
protected void onProgressUpdate(Void... params) {
    imageAdapter.notifyDataSetChanged();
    gridView.invalidateViews();
}

What could be the reason for not updating my views? Thank you!

EDIT: The ImageAdapter code:

public class ImageAdapter extends BaseAdapter {
    private Context mContext;
    public ArrayList<Bitmap> bitmaps = new ArrayList<Bitmap>();
    public ImageAdapter(Context c) {
        mContext = c;

    }

    public int getCount() {
        return bitmaps.size();
    }

    public Object getItem(int position) {
        return position;
    }

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

    // create a new ImageView for each item referenced by the Adapter
    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater) mContext
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            View gridView;

            if (convertView == null) {

                gridView = new View(mContext);

                // get layout from mobile.xml
                gridView = inflater.inflate(R.layout.image_adapter, null);

                // set image based on selected text
                ImageView imageView = (ImageView) gridView
                        .findViewById(R.id.imageView);
                imageView.setImageBitmap(bitmaps.get(position));
            }
                else{ 
                    gridView = (View) convertView;
                }
            return gridView;
    }
}

you have 2 main problems in your code:

  1. in the doInBackground , you change the data of the adapter, which is not a thread safe operation, since the adapter might read now from the data while you change it. i'm talking about this line:

     imageAdapter.bitmaps.set(i, BitmapFactory.decodeByteArray(data, 0, data.length)); 

    instead, you should update its data only on the UI thread, for example inside the onProgressUpdate .

  2. in the getView, you have implemented it incorrectly . when the convertView is not null, you never update the content of the imageView. what it should be like is something like:

 public View getView(int position, View convertView, ViewGroup parent) { View rootView=convertView; ViewHolder holder; if (rootView != null) holder=(ViewHolder) rootView.getTag(); else { rootView = inflater.inflate(R.layout.image_adapter, null,false); holder = new ViewHolder(); holder.imageView = (ImageView) rootView.findViewById(R.id.imageView); rootView.setTag(holder); } holder.imageView.setImageBitmap(getItem(position)); return rootView; } private Bitmap getItem(final int position) { return bitmaps.get(position); } private static class ViewHolder { ImageView imageView; } 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM