我正在开发 SdCard 上所有图片的缩略图马赛克。如果用户长按图片,我想开始拖放过程。
我显然设法获取所有图像文件并在 GridView 中使用我自己的 BaseAdapter 显示它们,但是这个过程很长,因为我以这种方式创建每个图像的预览:
uri = Uri.fromFile(file);
try {
bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
if (bitmap != null) {
newBitmap = Bitmap.createScaledBitmap(bitmap, 200, 200, true);
bitmap.recycle();
// here code to add the bitmap to the adapter (see after)
}
} catch (IOException e) {
//Error fetching image, try to recover
}
因此,为了避免长时间等待,我将图像加载到 AsyncTask 中。该过程运行良好,图像一张一张出现,但现在 LongClick 上出现错误,代码如下:
mGrid.setOnItemLongClickListener(new OnItemLongClickListener()
{
public boolean onItemLongClick(AdapterView<?> adapter, View view, int position, long id)
{
ClipData data = ClipData.newPlainText("AdapterPosition", String.valueOf(position) );
view.startDrag(data, new DragShadowBuilder(view), null, 0);
return true;
}
});
和错误:
12-27 16:54:14.980: E/View(8089): Unable to initiate drag
12-27 16:54:14.980: E/View(8089): java.lang.NullPointerException
12-27 16:54:14.980: E/View(8089): at android.view.View.startDrag(View.java:11470)
12-27 16:54:14.980: E/View(8089): at renault.limandroid.widget.PartageWidgetActivity$9.onItemLongClick(PartageWidgetActivity.java:547)
有人有想法吗?
这是我的代码的很大一部分:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_partage_widget);
// ... //
mImageAdapter = new ImageAdapter(this);
loadImages();
mGrid.setOnItemLongClickListener(new OnItemLongClickListener()
{
public boolean onItemLongClick(AdapterView<?> adapter, View view, int position, long id)
{
ClipData data = ClipData.newPlainText("AdapterPosition", String.valueOf(position) );
view.startDrag(data, new DragShadowBuilder(view), null, 0);
return true;
}
});
mGrid.setAdapter(mImageAdapter);
}
private void loadImages()
{
// si c'est la première fois qu'on passe ici
if (mLoadImageTask.getStatus() == AsyncTask.Status.PENDING)
{
mLoadImageTask.execute();
}
// si le scan est terminé mais qu'on veut le remettre à jour
// on va recréer la tâche
else if (mLoadImageTask.getStatus() == AsyncTask.Status.FINISHED)
{
mLoadImageTask = new LoadImagesFromSDCard();
mLoadImageTask.execute();
}
}
@Override
protected Object doInBackground(Object... params) {
setProgressBarIndeterminateVisibility(true);
Log.d(TAG,"LoadImages - do in background");
Bitmap bitmap = null;
Bitmap newBitmap = null;
Uri uri = null;
List<File> listFiles = new ArrayList<File>();
listFiles = StorageManager.findImageFiles();
for (File file : listFiles)
{
// mImageListFile contains the files that have already been loaded
if (!mImageListFile.contains(file))
{
uri = Uri.fromFile(file);
try {
bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
if (bitmap != null) {
newBitmap = Bitmap.createScaledBitmap(bitmap, 200, 200, true);
bitmap.recycle();
if (newBitmap != null) {
publishProgress(new LoadedImage(newBitmap));
}
}
} catch (IOException e) {
//Error fetching image, try to recover
}
mImageListFile.add(file);
}
}
return null;
}
/**
* Add a new LoadedImage in the images grid.
*
* @param value The image.
*/
@Override
public void onProgressUpdate(LoadedImage... value)
{
mImageAdapter.addPhoto(value[0]);
mImageAdapter.notifyDataSetChanged();
}
/**
* Set the visibility of the progress bar to false.
*
* @see android.os.AsyncTask#onPostExecute(java.lang.Object)
*/
@Override
protected void onPostExecute(Object result)
{
setProgressBarIndeterminateVisibility(false);
mGrid.invalidate();
}
}
class ImageAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<LoadedImage> photos = new ArrayList<LoadedImage>();
public ImageAdapter(Context context) {
mContext = context;
photos.add(new LoadedImage(BitmapFactory.decodeResource(context.getResources(),
R.drawable.click)));
}
public void addPhoto(LoadedImage photo)
{
photos.add(photo);
}
public int getCount() {
return photos.size();
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent)
{
final ImageView imageView;
final int pos = position;
if (convertView == null) {
imageView = new ImageView(mContext);
} else {
imageView = (ImageView) convertView;
}
imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
imageView.setPadding(2, 2, 2, 2);
imageView.setLayoutParams(new GridView.LayoutParams(parent.getWidth()/4, parent.getWidth()/4));
imageView.setImageBitmap(photos.get(position).getBitmap());
return imageView;
}
public Object getItem(int position)
{
return photos.get(position);
}
}
/**
* A LoadedImage contains the Bitmap loaded for the image.
*/
private static class LoadedImage {
Bitmap mBitmap;
LoadedImage(Bitmap bitmap) {
mBitmap = bitmap;
}
public Bitmap getBitmap() {
return mBitmap;
}
}