【问题标题】:Android loading images to listview asynchronously?Android异步加载图像到listview?
【发布时间】:2011-10-04 18:04:47
【问题描述】:

我有一个列表视图,我在其中从用户的 SD 卡加载所有图像(作为预览)。我有一个自定义的 SimpleCursorAdapter,当我覆盖 getView() 方法时,我尝试启动后台线程以加载图像。

我要做的基本上是使用后台线程或其他东西将图像预览“延迟加载”到列表视图中。我愿意接受新的解决方案。主要问题是滚动非常慢,因为加载图像的操作非常昂贵。

这是我正在尝试的相关代码:

public class listOfImages extends SimpleCursorAdapter {

private Cursor c;
private Context context;


public listOfImages(Context context, int layout, Cursor c,
        String[] from, int[] to) {
    super(context, layout, c, from, to);
    this.c = c;
    this.context = context;

}

public View getView(int pos, View inView, ViewGroup parent) {
    View v = inView;
    if (v == null) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = inflater.inflate(R.layout.image_item, null);
    }


    this.c.moveToPosition(pos);     
    int columnIndex = this.c.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME);
    String name = this.c.getString(columnIndex);
    columnIndex = this.c.getColumnIndexOrThrow(MediaStore.Images.Media.SIZE);
    String size = this.c.getString(columnIndex);
    columnIndex = this.c.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    String data = this.c.getString(columnIndex); //gives the filename 



    TextView sTitle = (TextView) v.findViewById(R.id.image_title);
    sTitle.setText(name);

    imagePreviewLoader ipl = new imagePreviewLoader(v, data); 
    ipl.mainProcessing(); 


    v.setTag(data); 

    v.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {

            Toast.makeText(context, "Image: " + v.getTag(), Toast.LENGTH_SHORT).show();  

            String filename = (String) v.getTag(); 


            Intent intent = new Intent(context, ViewImage.class);
            intent.putExtra("filename", filename);
            context.startActivity(intent);

        }
    });

    return v; 
}

}

现在我正在尝试的后台线程:

public class imagePreviewLoader {

private Handler handler = new Handler(); 
private View v; 
private String data;

public imagePreviewLoader(View v, String data) {
    this.v = v;
    this.data = data; 
}

protected void mainProcessing() {
    Thread thread = new Thread(null, doBackground, "Background"); 
    thread.start(); 
}

private Runnable doBackground = new Runnable() {
    public void run() {
        backgroundThreadProcessing(); 
    }
};

private void backgroundThreadProcessing() {
    handler.post(doUpdateGUI); 
}

private Runnable doUpdateGUI = new Runnable() {
    public void run() {
        updateGUI();
    }
}; 

private void updateGUI() {
    ImageView img = (ImageView) v.findViewById(R.id.image_view); 
    BitmapFactory.Options bfo = new BitmapFactory.Options();
    bfo.inSampleSize = 30;
    bfo.inTargetDensity = 50; 
    Bitmap bm = BitmapFactory.decodeFile(data, bfo);
    img.setImageBitmap(bm);
}

}

问题是,当您滚动时,所有内容都会尝试立即加载,因此滚动速度非常慢。我认为会发生什么是图像视图将保持空白(或占位符),直到线程加载了适当的图像。我想不是。

感谢您的帮助。

【问题讨论】:

  • Java 类的命名约定是以大写字母开头。因此“listOfImages”应该是“ListOfImages”。我提到它只是因为构造函数让我困惑了一会儿。
  • 您可以在启动任务之前引入一些延迟,如果在任务完成之前尝试重用视图,则取消任务。这将涉及将任务与视图一起存储。

标签: java android multithreading listview


【解决方案1】:

看看我对this 问题的回答,它有一个示例项目,展示了如何做到这一点,但从网上下载图像。您应该能够很容易地对其进行修改,以便从 SD 卡中获取图像。

【讨论】:

  • 嘿,我已经调整了大部分代码以适应我的,我只是遇到了以下行的问题: final int stub_id=R.drawable.stub;什么是存根?谢谢。
  • 存根只是一个默认图像,在其他图像下载之前显示。
【解决方案2】:

我有一个基本公共领域许可下的易于使用的库,您可以查看它...它将取消未显示的行的加载并使用两个线程进行图像加载。

您可以在我的 GitHub 上查看:https://github.com/tbiehn/Android-Adapter-Image-Loader

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多