【问题标题】:GridView is not updated with notifyDataSetChanged()GridView 未使用 notifyDataSetChanged() 更新
【发布时间】:2013-06-10 09:03:18
【问题描述】:

我有一个ActivityGridView,里面有图片。图像是从设备的 SD 卡中解析的。一旦Activity 启动,图像就会使用AsyncTask 下载到 SD 卡中。

问题是这个GridView 在下载图像时没有得到更新。 如果向目录中添加更多图像(即下载更多图像),我希望更新此 GridView。我试过notifyDataSetChanged()invalidateViews(),但它们没有帮助。

这是我的 MainActivity、图像适配器和 AsyncTask 的代码。请尝试告诉我我在哪里犯了错误。

主活动:

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()

    @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;
    }

图像下载器:

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");
}

【问题讨论】:

  • notifyDataSetChanged();当你想更新视图适配器时使用它。
  • 你要在哪个事件上更新适配器。你把它写在 OnCreate();
  • 是的,我在 Main Activity 中这样使用它:iAdapter.notifyDataSetChanged();
  • @Ganesh,我想在我的 AsyncTask 完成后更新它。更准确地说,当通过 AsyncTask 下载将新图像添加到 SD 卡目录时。
  • 然后在 AsyncTask 之后更新它......在你的代码中你更新它之前。或者在 onResume();

标签: android gridview android-asynctask android-gridview notifydatasetchanged


【解决方案1】:

首先,你应该从 URL 下载图片并返回它。

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);
      }
}   

第二个,创建一个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;
    }

}

就在这里:

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

你可以创建一个DownloadImageTask的实例,然后你就可以得到一个这样的Image:

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

最后一个,在 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);
    }
}

希望对您有所帮助!

【讨论】:

  • 谢谢,我会看看这个。当添加新数据集时,您的示例中的 gridview 是否会更新?
  • 是的,它有效,但我的代码结构非常不同。所以我无法在我的应用中实现它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-02
相关资源
最近更新 更多