2011-07-13 9 views
1

私はユーザーの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); 
} 

}

問題がスクロールするとすべてが一度に読み込もうとするので、スクロールは本当に遅いです。私は、スレッドが適切なイメージをロードするまで、イメージビューは空白(またはプレースホルダ)のままになります。私は思っていない。

ありがとうございました。

+0

Javaの命名規則は、彼らが大文字で始まるということです。したがって、 "listOfImages"は "ListOfImages"でなければなりません。コンストラクタがこれのために私をしばらく混乱させたからだけ言及します。 –

+0

タスクを開始する前にいくつかの遅延を導入し、タスクが完了する前にビューを再利用しようとするとタスクを取り消すことができます。これには、ビューにタスクを格納することが含まれます。 –

+0

[Lazy Loading Images](http://evancharlton.com/thoughts/lazy-loading-images-in-a-listview/)をご覧ください。 –

答えて

1

this質問への私の答えを見て、どのようにそれを行うが、ネットから画像をダウンロードするサンプルプロジェクトがあります。 SDカードから画像を取得するためには、簡単に変更することができます。

+0

ありがとう、私は見てみる – JDS

+0

ちょっと、私はコードのほとんどを私のものに適応させた、私はちょうど次の行の問題に実行しています:最終int stub_id = R.drawable.stub;スタブとは何ですか?ありがとう。 – JDS

+0

スタブは、他のイメージがダウンロードされるまで表示されたデフォルトイメージに過ぎません。 – Kenny

1

私はあなたがチェックアウトできる基本的なパブリックドメインライセンスの下で使いやすいライブラリを持っています...それは表示されていない行の読み込みをキャンセルし、画像読み込みを行うために2つのスレッドを使用します。

あなたは私のGitHub上でそれをチェックアウトすることができます:クラスのためhttps://github.com/tbiehn/Android-Adapter-Image-Loader

関連する問題