Gridview Recycling проблема с асинхронной
Когда я прокручиваю назад и вперед через мой GridView
мои изображения не будут правильно переработаны и в конечном итоге будут отображаться в сетке.
адаптер
public class ImageAdapter extends BaseAdapter {
private Context mContext;
private List<String> mList;
private int mheight;
private int mwidth;
private Bitmap nBitmap;
public ImageAdapter(Context context, List<String> list, int height, int width) {
mContext = context;
mList = list;
mheight = height;
mwidth = width;
}
@Override
public int getCount() {
return mList.size();
}
@Override
public Object getItem(int position) {
return mList.get(position).toString();
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(mContext);
InputStream is;
try {
is = mContext.getAssets().open(mList.get(position));
Bitmap bm = BitmapFactory.decodeStream(is);
Bitmap mBitmap = Bitmap.createScaledBitmap(bm, mwidth / 3, mwidth / 3, false);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
this.nBitmap = mBitmap;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
imageView = (ImageView) convertView;
}
imageView.setImageBitmap(nBitmap);
return imageView;
}
}
я попытался декодировать растровое изображение из прокрутки потока пользовательского интерфейса, работающей быстро, но миниатюры, загружаемые 1 на 1 при запуске приложения, и вид восстановленных миниатюр изменяются из исходного представления и при сбое приложения с низким уровнем памяти при сбое приложений при загрузке миниатюр из AsyncTask здесь обновляется код
public class ImageAdapter extends BaseAdapter {
private Context mContext;
private List<String> mList;
private int mheight;
private int mwidth;
private InputStream is;
public ImageAdapter(Context context, List<String> list, int height, int width) {
mContext = context;
mList = list;
mheight = height;
mwidth = width;
}
@Override
public int getCount() {
return mList.size();
}
@Override
public Object getItem(int position) {
return mList.get(position).toString();
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(mContext);
} else {
imageView = (ImageView) convertView;
}
InputStream is;
try {
is = mContext.getAssets().open(mList.get(position));
Loadimage task = new Loadimage(imageView , mheight , mwidth);
task.execute(is);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return imageView ;
}
public class Loadimage extends AsyncTask<InputStream, Void, Bitmap>{
private final WeakReference<ImageView> imageViewReference;
private InputStream is = null;
private int width;
public Loadimage(ImageView imageView, int mheight, int mwidth) {
imageViewReference = new WeakReference<ImageView>(imageView);
this.width=mwidth;
// TODO Auto-generated constructor stub
}
@Override
protected Bitmap doInBackground(InputStream... params) {
is = params[0];
if (is !=null) {
Bitmap bitmap = BitmapFactory.decodeStream(is);
Bitmap nBitmap =Bitmap.createScaledBitmap(bitmap,width/3 , width/3, false);
return nBitmap;
}
return null;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
if (imageViewReference != null && bitmap != null) {
final ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(bitmap);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
}
}
}
1 ответ
Вам нужно переместить блок, в котором вы генерируете растровое изображение, за пределы if/then
, Прямо сейчас вы генерируете новое растровое изображение только тогда, когда convertView == null
,
Я считаю, что ваш код будет правильным как:
public class ImageAdapter extends BaseAdapter {
private Context mContext;
private List<String> mList;
private int mheight;
private int mwidth;
public ImageAdapter(Context context, List<String> list, int height, int width) {
mContext = context;
mList = list;
mheight = height;
mwidth = width;
}
@Override
public int getCount() {
return mList.size();
}
@Override
public Object getItem(int position) {
return mList.get(position).toString();
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(mContext);
} else {
imageView = (ImageView) convertView;
}
InputStream is;
try {
is = mContext.getAssets().open(mList.get(position));
Bitmap bm = BitmapFactory.decodeStream(is);
Bitmap bitmap = Bitmap.createScaledBitmap(bm, mwidth / 3, mwidth / 3, false);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
return imageView;
}
}
Ваша прокрутка не будет очень плавной, и вы получите много пропущенных кадров, потому что ваш код декодирования растровых изображений неэффективен (без кэширования), и все это происходит в потоке пользовательского интерфейса, что плохо для отзывчивости. Узким местом в вашем текущем коде является не выделение, а сборка мусора ImageView
s.
Узким местом является (вероятно, безусловно) ваша обработка и создание Bitmap
s.
Вы можете взглянуть на следующие ссылки для совета:
Эффективное отображение растровых изображений
И именно этот:
Обработка растровых изображений вне потока пользовательского интерфейса