longwalker
longwalker

Reputation: 1664

GridView is not updated with notifyDataSetChanged()

I have an Activity with GridView, with images in it. The images are parsed from the SD card of the device. Once the Activity starts, images are downloaded to the SD card using AsyncTask.

The problem is that this GridView does not get updated when images are downloaded. I want this GridView to be updated if more images are added to the directory (i.e. if more images are downloaded). I have tried notifyDataSetChanged() and invalidateViews(), however they are not helping.

Here is my code for the MainActivity, Image adapter and AsyncTask. Please try to show me where I made the mistake.

MainActivity:

ImageAdapter ia = new ImageAdapter(this);   
GridView gridView; 

@Override   
public void onCreate(Bundle savedInstanceState){  
    super.onCreate(savedInstanceState);
    setContentView(R.layout.grid_layout);

    gridView = (GridView) findViewById(R.id.grid_view);

    // Instance of ImageAdapter Class   
    ImageAdapter iAdapter = new ImageAdapter(this);     
    gridView.setAdapter(iAdapter);      
    iAdapter.notifyDataSetChanged();
    gridView.invalidateViews();
    new ImageDownlader(AndroidGridLayoutActivity.this, this).execute(downloadUrl);
    gridView.setOnItemClickListener(new OnItemClickListener() {
         @Override
         public void onItemClick(AdapterView<?> parent, View v,
                int position, long id) {

            // Sending image id to FullScreenActivity
            Intent i = new Intent(getApplicationContext(), FullImageActivity.class);
            // passing array index
            i.putExtra("id", position);
            startActivity(i);
        }
    });     

getView() of Image Adapter:

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
         ImageView imageView = new ImageView(mContext);
         imageView.setImageBitmap(getImageByIndex(imageThumbnails, position));
         imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
         imageView.setLayoutParams(new GridView.LayoutParams(155, 155));
         return imageView;
    }

ImageDownlader:

class ImageDownlader extends AsyncTask<String, Void, Void> {
    private Context context;
    public ImageDownlader(Context c){
    context = c;
}


Sync s = new Sync();

@Override
protected Void doInBackground(String... param) {
        // this is where images are downloaded to SD card
    saveToSD ();
    return null;
}

@Override
protected void onPreExecute() {
    Log.i("Async-Example", "onPreExecute Called");
}

protected void onPostExecute()
{
    Log.i("Async-Example", "onPostExecute Called");
}

Upvotes: 0

Views: 6024

Answers (1)

Luc
Luc

Reputation: 2805

The first, you should download Image from URL and return it.

import java.io.InputStream;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ImageView;

public class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
      ImageView bmImage;

      public DownloadImageTask(ImageView bmImage) {
          this.bmImage = bmImage;
      }

      protected Bitmap doInBackground(String... urls) {
          String urldisplay = urls[0];
          Bitmap mIcon11 = null;
          try {
            InputStream in = new java.net.URL(urldisplay).openStream();
            mIcon11 = BitmapFactory.decodeStream(in);
          } catch (Exception e) {
              Log.e("Error", e.getMessage());
              e.printStackTrace();
          }
          return mIcon11;
      }

      protected void onPostExecute(Bitmap result) {
          bmImage.setImageBitmap(result);
      }
}   

The second, create an Adapter

import java.util.List;

import vn.mve.obj.Video;
import vn.mve.util.DownloadImageTask;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import vn.mve.e4u.Detail;
import vn.mve.e4u.R;

public class VideoAdapter extends BaseAdapter {
    private List<Video> list;
    private Context context;
    private LayoutInflater inflater;
    public VideoAdapter(Context context, List<Video> list) {
        this.context = context;
        this.list = list;
        inflater = LayoutInflater.from(context);
    }
    @Override
    public int getCount() {
        return list.size();
    }

    @Override
    public Object getItem(int position) {
        return list.get(position);
    }

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

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        View view = inflater.inflate(R.layout.layout_video_gridview, parent, false);
        ImageView iv_thumb = (ImageView) view.findViewById(R.id.iv_thumb);
        new DownloadImageTask(iv_thumb).execute(list.get(position).getThumbnail());

        TextView tv_title = (TextView) view.findViewById(R.id.tv_title);
        tv_title.setText(list.get(position).getTitle());

        LinearLayout item = (LinearLayout) view.findViewById(R.id.item);
        item.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(context, Detail.class);
                intent.putExtra("ID", list.get(position).getId());
                context.startActivity(intent);
            }
        });
        return view;
    }

}

Right here:

new DownloadImageTask(iv_thumb).execute(list.get(position).getThumbnail());

You can Create an Instance of DownloadImageTask, after that you can get an Image like that:

imageTask = new DownloadImageTask(iv_thumb).execute(list.get(position).getThumbnail());
Bitmap myImage = imageTask.get(); // Please put in try-catch

The last, in MainActivity

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    List<Video> list = null;
    MVideo mVideo = new MVideo(getApplicationContext());
    list = mVideo.getList(VideoType.GET_ALL);
    VideoAdapter adapter = new VideoAdapter(this, list);
    if (list != null) {
        GridView gvVideo = (GridView) findViewById(R.id.gv_video);
        gvVideo.setAdapter(adapter);
    }
}

Hope this will help you!

Upvotes: 1

Related Questions