public Bitmap toGrayscale(Bitmap bmpOriginal)
{
int width, height;
height = bmpOriginal.getHeight();
width = bmpOriginal.getWidth();
Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
Canvas c = new Canvas(bmpGrayscale);
Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
paint.setColorFilter(f);
c.drawBitmap(bmpOriginal, 0, 0, paint);
return bmpGrayscale;
}
通过GridView的getLastVisiblePosition()和getFirstVisiblePosition()方法确认当前GridView控件中将会显示Dataset中的数据范围,在该范围之内的图片应该是已经解码过的,而不在该区间中的图片,可以在适当的时候使用recycle()方法回收。实现方式可以使用HashMap来存储对应的ID和Bitmap
HashMap<Integer, Bitmap> picMap,Integer的值对应path的ArrayList即可,系统每次回调getView()的时候,通过上面的两个方法,确定需要显示的ID范围,遍历该范围中的ID,从picMap中查询,如果对应ID的Bitmap为空的话,就通过path的ArrayList中对应的文件名解码图像,如果不为空,那么就直接设置即可。而不在该区间的图片最好是调用recycle()回收,要不就很有可能出现OOM错误。
至于预加载的意思就是每次得到需要显示的范围之后,再扩大一定的范围,使得用户在快速切换图片时,不至于出现因为解码而感觉到的停滞感。
建议扩大的范围为起始位置和终止位置分别往前和往后扩大当前GridView一行显示缩略图的个数,例如已知将显示8~23号图片,GridView每行显示4个缩略图,那么将其范围扩大到4~27,保证处于该区间的ID对应的图片解码成功,并设置给ImageView,而不在该区间内的图片尽量使用recycle()方法回收。不过如果楼主的应用中不会碰到特别多的图片的话,建议不要把问题复杂化。当然如果有需求的话,这样做会保证程序不出错,只是稍微复杂了一些。
private int PicPosition;
private Handler handler = new Handler();
private Runnable runnable = new Runnable() {
public void run() {
myslideshow();
handler.postDelayed(this, 1000);.
}
};
private void myslideshow()
{
PicPosition = gallery.getSelectedItemPosition() +1;
if (PicPosition >= Pictures.size())
PicPosition = gallery.getSelectedItemPosition(); //stop
else
gallery.setSelection(PicPosition);//move to the next gallery element.
}