将大图像加载到列表视图中
Loading large Images into Listview
所以我的 Listview 一直滞后,因为我在其中加载了太多图片。所以我在网上搜索了一下,找到了两个解决问题的具体思路:
因此,由于我是使用 Android 进行开发的新手,所以我试了一下 AsyncTask 但失败了。我看到的示例主要是使用 URL 下载图片,并且由于我使用的是 sqlite 数据库,所以我无法让这些示例为我工作。
这是我的尝试:
static class ViewHolder {
TextView imageTextView;
ImageView favImageView;
int position;
}
//Constructor for List Items
private class favImagesListAdapter extends ArrayAdapter<FavImages>{
private LayoutInflater mInflater = LayoutInflater.from(context);
public favImagesListAdapter(){
super (MainActivity.this, R.layout.listview_item, FavImages);
}
@Override
public View getView (final int position, View convertView, ViewGroup parent){
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.listview_item, parent, false);
holder = new ViewHolder();
holder.imageTextView = (TextView) convertView.findViewById(R.id.favName);
holder.favImageView = (ImageView) convertView.findViewById(R.id.favImage);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
FavImages currentFav = FavImages.get(position);
holder.imageTextView.setText(currentFav.getImageName());
new AsyncTask<ViewHolder, Void, Bitmap>() {
private ViewHolder v;
@Override
protected Bitmap doInBackground(ViewHolder... params) {
v = params[0];
return mFakeImageLoader.getImage();
}
@Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
if (v.position == position) {
// If this item hasn't been recycled already, hide the
// progress and set and show the image
//v.progress.setVisibility(View.GONE);
v.favImageView.setVisibility(View.VISIBLE);
v.favImageView.setImageBitmap(result);
}
}
}.execute(holder);
//old Version that causes lags
ContentResolver cr = getContentResolver();
try {
holder.favImageView.setImageBitmap(MediaStore.Images.Media.getBitmap(cr, currentFav.getImagePath()));
} catch (IOException e) {
e.printStackTrace();
}
return convertView;
}
}
由于我没有参考 FakeImageLoader 的功能,我尝试减小其中图像的大小,但没有用,所以我使用了在 [=49 上找到的参考代码=] 像这样的网站:
public class FakeImageLoader {
private Bitmap mBmp;
public FakeImageLoader(Context cxt)
{
mBmp= BitmapFactory.decodeResource(cxt.getResources(), R.drawable.ic_launcher);
}
public Bitmap getImage()
{
try {
Thread.sleep(new Random().nextInt(5000));
} catch (InterruptedException e) {
e.printStackTrace();
}
return mBmp;
}
}
但是使用 class 只会导致错误(因为用于完全不同的东西?)。
所以我想问,我需要 FakeImageLoader(可能不是一个好名字)做什么,以最好地加载图像(猜测只需要按比例缩小图像),主要是我该怎么做.
我也读过关于 Picasso 的文章,但我想保持 App 小巧,边做边学(或问)。如果更多代码有帮助,我会在询问时这样做。
编辑:
使用 FakeImageLoader class 不起作用(实际上很明显),所以我将整个 ListAdapter 与 Asynctask 更改为:
static class ViewHolder {
TextView imageTextView;
ImageView favImageView;
int position;
}
//Constructor for List Items
private class favImagesListAdapter extends ArrayAdapter<FavImages>{
private LayoutInflater mInflater = LayoutInflater.from(context);
public favImagesListAdapter(){
super (MainActivity.this, R.layout.listview_item, FavImages);
}
@Override
public View getView (final int position, View convertView, ViewGroup parent){
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.listview_item, parent, false);
holder = new ViewHolder();
holder.imageTextView = (TextView) convertView.findViewById(R.id.favName);
holder.favImageView = (ImageView) convertView.findViewById(R.id.favImage);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final FavImages currentFav = FavImages.get(position);
holder.imageTextView.setText(currentFav.getImageName());
class MyAsyncTask extends AsyncTask<ViewHolder, Void, Bitmap> {
private ViewHolder v;
@Override
protected Bitmap doInBackground(ViewHolder... params) {
v = params[0];
return getImage();
}
private Bitmap getImage() {
Bitmap mBmp;
ContentResolver cr = getContentResolver();
MainActivity.ViewHolder holder = null;
com.adrianopaulus.favoriten.FavImages currentFav1 = FavImages.get(position);
try {
mBmp = holder.favImageView.setImageBitmap(MediaStore.Images.Media.getBitmap(cr, currentFav1.getImagePath()));
return mBmp;
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
//return mBmp;
}
@Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
if (v.position == position) {
// If this item hasn't been recycled already, hide the
// progress and set and show the image
//v.progress.setVisibility(View.GONE);
v.favImageView.setVisibility(View.VISIBLE);
v.favImageView.setImageBitmap(result);
}
}
}MyAsyncTask.execute((Runnable) holder);
return convertView;
}
}
但是下面一行有问题:
mBmp = holder.favImageView.setImageBitmap(MediaStore.Images.Media.getBitmap(cr, currentFav1.getImagePath()));
而且我不知道我做错了什么。
利用通用图像加载器库。这会异步加载图像,并且不会滞后于您的列表视图。
https://github.com/nostra13/Android-Universal-Image-Loader
里面有例子。
尽情享受吧:)
//延迟加载用于Aquery的图像加载。
//尝试使用查询在列表视图中加载图像
http://programmerguru.com/android-tutorial/introduction-to-aquery-android-query/
AQuery aq = aq = new AQuery(convertView);
// id means -> ImageView object or Imageview id
// path means-> Url of Image.
//Download a jar file, Copy and Past into a lib folder.
aq.id(imgDisplay).image(path,true, true, 0,R.drawable.default_image, null,AQuery.CACHE_DEFAULT,0.0f).visible();
所以我的 Listview 一直滞后,因为我在其中加载了太多图片。所以我在网上搜索了一下,找到了两个解决问题的具体思路:
因此,由于我是使用 Android 进行开发的新手,所以我试了一下 AsyncTask 但失败了。我看到的示例主要是使用 URL 下载图片,并且由于我使用的是 sqlite 数据库,所以我无法让这些示例为我工作。
这是我的尝试:
static class ViewHolder {
TextView imageTextView;
ImageView favImageView;
int position;
}
//Constructor for List Items
private class favImagesListAdapter extends ArrayAdapter<FavImages>{
private LayoutInflater mInflater = LayoutInflater.from(context);
public favImagesListAdapter(){
super (MainActivity.this, R.layout.listview_item, FavImages);
}
@Override
public View getView (final int position, View convertView, ViewGroup parent){
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.listview_item, parent, false);
holder = new ViewHolder();
holder.imageTextView = (TextView) convertView.findViewById(R.id.favName);
holder.favImageView = (ImageView) convertView.findViewById(R.id.favImage);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
FavImages currentFav = FavImages.get(position);
holder.imageTextView.setText(currentFav.getImageName());
new AsyncTask<ViewHolder, Void, Bitmap>() {
private ViewHolder v;
@Override
protected Bitmap doInBackground(ViewHolder... params) {
v = params[0];
return mFakeImageLoader.getImage();
}
@Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
if (v.position == position) {
// If this item hasn't been recycled already, hide the
// progress and set and show the image
//v.progress.setVisibility(View.GONE);
v.favImageView.setVisibility(View.VISIBLE);
v.favImageView.setImageBitmap(result);
}
}
}.execute(holder);
//old Version that causes lags
ContentResolver cr = getContentResolver();
try {
holder.favImageView.setImageBitmap(MediaStore.Images.Media.getBitmap(cr, currentFav.getImagePath()));
} catch (IOException e) {
e.printStackTrace();
}
return convertView;
}
}
由于我没有参考 FakeImageLoader 的功能,我尝试减小其中图像的大小,但没有用,所以我使用了在 [=49 上找到的参考代码=] 像这样的网站:
public class FakeImageLoader {
private Bitmap mBmp;
public FakeImageLoader(Context cxt)
{
mBmp= BitmapFactory.decodeResource(cxt.getResources(), R.drawable.ic_launcher);
}
public Bitmap getImage()
{
try {
Thread.sleep(new Random().nextInt(5000));
} catch (InterruptedException e) {
e.printStackTrace();
}
return mBmp;
}
}
但是使用 class 只会导致错误(因为用于完全不同的东西?)。
所以我想问,我需要 FakeImageLoader(可能不是一个好名字)做什么,以最好地加载图像(猜测只需要按比例缩小图像),主要是我该怎么做.
我也读过关于 Picasso 的文章,但我想保持 App 小巧,边做边学(或问)。如果更多代码有帮助,我会在询问时这样做。
编辑:
使用 FakeImageLoader class 不起作用(实际上很明显),所以我将整个 ListAdapter 与 Asynctask 更改为:
static class ViewHolder {
TextView imageTextView;
ImageView favImageView;
int position;
}
//Constructor for List Items
private class favImagesListAdapter extends ArrayAdapter<FavImages>{
private LayoutInflater mInflater = LayoutInflater.from(context);
public favImagesListAdapter(){
super (MainActivity.this, R.layout.listview_item, FavImages);
}
@Override
public View getView (final int position, View convertView, ViewGroup parent){
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.listview_item, parent, false);
holder = new ViewHolder();
holder.imageTextView = (TextView) convertView.findViewById(R.id.favName);
holder.favImageView = (ImageView) convertView.findViewById(R.id.favImage);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final FavImages currentFav = FavImages.get(position);
holder.imageTextView.setText(currentFav.getImageName());
class MyAsyncTask extends AsyncTask<ViewHolder, Void, Bitmap> {
private ViewHolder v;
@Override
protected Bitmap doInBackground(ViewHolder... params) {
v = params[0];
return getImage();
}
private Bitmap getImage() {
Bitmap mBmp;
ContentResolver cr = getContentResolver();
MainActivity.ViewHolder holder = null;
com.adrianopaulus.favoriten.FavImages currentFav1 = FavImages.get(position);
try {
mBmp = holder.favImageView.setImageBitmap(MediaStore.Images.Media.getBitmap(cr, currentFav1.getImagePath()));
return mBmp;
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
//return mBmp;
}
@Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
if (v.position == position) {
// If this item hasn't been recycled already, hide the
// progress and set and show the image
//v.progress.setVisibility(View.GONE);
v.favImageView.setVisibility(View.VISIBLE);
v.favImageView.setImageBitmap(result);
}
}
}MyAsyncTask.execute((Runnable) holder);
return convertView;
}
}
但是下面一行有问题:
mBmp = holder.favImageView.setImageBitmap(MediaStore.Images.Media.getBitmap(cr, currentFav1.getImagePath()));
而且我不知道我做错了什么。
利用通用图像加载器库。这会异步加载图像,并且不会滞后于您的列表视图。
https://github.com/nostra13/Android-Universal-Image-Loader
里面有例子。
尽情享受吧:)
//延迟加载用于Aquery的图像加载。
//尝试使用查询在列表视图中加载图像
http://programmerguru.com/android-tutorial/introduction-to-aquery-android-query/
AQuery aq = aq = new AQuery(convertView);
// id means -> ImageView object or Imageview id
// path means-> Url of Image.
//Download a jar file, Copy and Past into a lib folder.
aq.id(imgDisplay).image(path,true, true, 0,R.drawable.default_image, null,AQuery.CACHE_DEFAULT,0.0f).visible();