最近闲来无聊,决定写一个小小的android ImageView应用学习下。在写的过程中,出现了一些小问题,希望能够得到大家的帮助。这个应用大致的功能是,读取sdcard上的图片,然后使用gallery和ImageSwitcher显示出来。我刚开始完成了基本功能,现在想给应用加一个删除图片功能的时候,遇到了问题,现来看看的代码吧
package com.alan.android;import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.Gallery.LayoutParams;
import android.widget.ImageSwitcher;
import android.widget.ImageView;
import android.widget.ViewSwitcher.ViewFactory;public class ImageViewerActivity extends Activity implements ViewFactory, OnItemSelectedListener { private ImageSwitcher mImgSwitcher;
private Gallery mGallery;
private ImageAdapter adapter;
private ArrayList<String> mImgPathList;
//private String[] mImgPath;
//sdcard Path
private String mSdcardPath;
//cache for the Bitmap res
private HashMap<Integer, Bitmap> imgCache = new HashMap<Integer, Bitmap>();
private static final String LOG_TAG="ImageViewer";
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mImgPathList = new ArrayList<String>();
mSdcardPath = Environment.getExternalStorageDirectory().toString();
saveImagePathToList(mImgPathList, mSdcardPath);
//////////////////////////////////////////////
//print all the imgPath and see whether it's right
//for(int i = 0 ; i < mImgPathList.size() ; i++){
// Log.e("ImagePath",mImgPathList.get(i));
//}
//////////////////////////////////////////////
//set ImageSwitcher
mImgSwitcher = (ImageSwitcher)findViewById(R.id.imgswitcher);
mImgSwitcher.setFactory(this);
mImgSwitcher.setInAnimation(AnimationUtils.loadAnimation(this,android.R.anim.fade_in));
mImgSwitcher.setOutAnimation(AnimationUtils.loadAnimation(this,android.R.anim.fade_out)); //set Gallery
mGallery = (Gallery)findViewById(R.id.imgallery);
adapter = new ImageAdapter(this, mImgPathList);
mGallery.setAdapter(adapter);
mGallery.setOnItemSelectedListener(this);
mGallery.setOnItemLongClickListener(new OnItemLongClickListener(){ public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
final int position, long id) {
// TODO Auto-generated method stub
AlertDialog.Builder build = new Builder(ImageViewerActivity.this);
build.setTitle("你想执行下列哪个操作?")
.setPositiveButton("删除选中文件", new OnClickListener(){ public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
onDelBtnDown(position);
}
})
.setNegativeButton("重命名该图片", new OnClickListener(){ public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
onRenameBtnDown();
}
});
build.create().show();
return false;
}
});
}
//button down callbacks
private void onRenameBtnDown() {
// TODO Auto-generated method stub
}
private void onDelBtnDown(int pos) {
// TODO Auto-generated method stub
Log.d(LOG_TAG,"the pos will deleted is " + pos);
File current = new File(mImgPathList.get(pos));
current.delete();
mImgPathList.clear();
saveImagePathToList(mImgPathList, mSdcardPath);
// for(int i = 0 ; i < mImgPathList.size() ; i++){
// Log.e(LOG_TAG, mImgPathList.get(i));
// }
adapter = new ImageAdapter(this, mImgPathList);
mGallery.setAdapter(adapter);
mGallery.requestLayout();
RefreshView();
}
private void RefreshView(){
for(int i = 0 ; i < mImgPathList.size() ; i++){
Log.e("ImagePath",mImgPathList.get(i));
}
}
//get image path recursively
private void saveImagePathToList(ArrayList<String> list, String filePath) {
// TODO Auto-generated method stub
File mFile = new File(filePath);
File[] listFile = mFile.listFiles();
if(listFile != null){
for(int i = 0 ; i < listFile.length ; i++){
File file = listFile[i];
if(isAnImageFile(file.getAbsolutePath())){
list.add(file.getAbsolutePath());
}else if(file.isDirectory() && !file.getAbsolutePath().contains("DCIM")){
//get image path recursively
this.saveImagePathToList(mImgPathList, file.getAbsolutePath());
}
continue;
}
}
}
//check the fils's suffix and tell whether it's an image
private boolean isAnImageFile(String fileName){
String fileNameLowerCase = fileName.toLowerCase();
if(fileNameLowerCase.endsWith("jpg") || fileNameLowerCase.endsWith("gif")
|| fileNameLowerCase.endsWith("bmp") || fileNameLowerCase.endsWith("jpeg")
|| fileNameLowerCase.endsWith("png")){
return true;
}
return false;
} public View makeView() {
// TODO Auto-generated method stub
ImageView iv = new ImageView(this);
//iv.setBackgroundColor(0xFF000000);
iv.setScaleType(ImageView.ScaleType.FIT_CENTER);
iv.setLayoutParams(new ImageSwitcher.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));
return iv;
}
public class ImageAdapter extends BaseAdapter{
private Context mContext;
private int mGalleryBackground;
private ArrayList<String> mArrayList;
public ImageAdapter(Context c, ArrayList<String> list){
mContext = c;
mArrayList = list;
//use attrs.xml to specify the Gallery's attributes
TypedArray mTypeArray = obtainStyledAttributes(R.styleable.Gallery);
mGalleryBackground = mTypeArray.getResourceId(R.styleable.Gallery_android_galleryItemBackground, 0);
mTypeArray.recycle();
} public int getCount() {
// TODO Auto-generated method stub
return mArrayList.size();
} public Object getItem(int position) {
// TODO Auto-generated method stub
//just return position, will use it later
return position;
} public long getItemId(int position) {
// TODO Auto-generated method stub
//just return position will use it later
return position;
} public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
//new a ImageView for the image displaying
Log.d(LOG_TAG,"getView--->");
ImageView imgView = new ImageView(mContext);
//check the cache first
Bitmap current = imgCache.get(position);
if(current == null){
current = BitmapFactory.decodeFile(mArrayList.get(position));
imgCache.put(position, current);
}
imgView.setImageBitmap(current);
imgView.setScaleType(ImageView.ScaleType.FIT_XY);
imgView.setLayoutParams(new Gallery.LayoutParams(136, 88));
imgView.setBackgroundResource(mGalleryBackground);
return imgView;
}
} public void onItemSelected(AdapterView<?> arg0, View arg1, int pos,
long id) {
// TODO Auto-generated method stub
String imgPath = mImgPathList.get(pos);
Log.e(LOG_TAG,"Selected Img Path is " + imgPath);
Drawable drawadle = Drawable.createFromPath(imgPath);
mImgSwitcher.setImageDrawable(drawadle);
//release Bitmap resource
releaseBitmap();
} //just keep the bitmap in Visible range, release the rest
private void releaseBitmap() {
// TODO Auto-generated method stub
int begin = mGallery.getFirstVisiblePosition();
int end = mGallery.getLastVisiblePosition();
for(int i = 0 ; i < begin ; i++){
Bitmap delBitmap = imgCache.get(i);
if(delBitmap != null){
imgCache.remove(i);
delBitmap.recycle();
}
}
for(int i = end + 1 ; i < imgCache.size() ; i++){
Bitmap delBitmap = imgCache.get(i);
if(delBitmap != null){
imgCache.remove(i);
delBitmap.recycle();
}
}
}}代码很简单,劳烦大家看下,当我删除一张图片的时候,我该怎么更新gallery呢?我上面的用的方法大致能起作用,但是还是有一点bug,比如有时候,删除了一张图片,gallery上还是显示着,而ImageSwitcher显示了下一张。我知道, 我上面用的方法很搓,大家有好的方法,还希望多多分享。我没有做过android应用,最好能有实例提供,谢谢了先....
package com.alan.android;import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.Gallery.LayoutParams;
import android.widget.ImageSwitcher;
import android.widget.ImageView;
import android.widget.ViewSwitcher.ViewFactory;public class ImageViewerActivity extends Activity implements ViewFactory, OnItemSelectedListener { private ImageSwitcher mImgSwitcher;
private Gallery mGallery;
private ImageAdapter adapter;
private ArrayList<String> mImgPathList;
//private String[] mImgPath;
//sdcard Path
private String mSdcardPath;
//cache for the Bitmap res
private HashMap<Integer, Bitmap> imgCache = new HashMap<Integer, Bitmap>();
private static final String LOG_TAG="ImageViewer";
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mImgPathList = new ArrayList<String>();
mSdcardPath = Environment.getExternalStorageDirectory().toString();
saveImagePathToList(mImgPathList, mSdcardPath);
//////////////////////////////////////////////
//print all the imgPath and see whether it's right
//for(int i = 0 ; i < mImgPathList.size() ; i++){
// Log.e("ImagePath",mImgPathList.get(i));
//}
//////////////////////////////////////////////
//set ImageSwitcher
mImgSwitcher = (ImageSwitcher)findViewById(R.id.imgswitcher);
mImgSwitcher.setFactory(this);
mImgSwitcher.setInAnimation(AnimationUtils.loadAnimation(this,android.R.anim.fade_in));
mImgSwitcher.setOutAnimation(AnimationUtils.loadAnimation(this,android.R.anim.fade_out)); //set Gallery
mGallery = (Gallery)findViewById(R.id.imgallery);
adapter = new ImageAdapter(this, mImgPathList);
mGallery.setAdapter(adapter);
mGallery.setOnItemSelectedListener(this);
mGallery.setOnItemLongClickListener(new OnItemLongClickListener(){ public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
final int position, long id) {
// TODO Auto-generated method stub
AlertDialog.Builder build = new Builder(ImageViewerActivity.this);
build.setTitle("你想执行下列哪个操作?")
.setPositiveButton("删除选中文件", new OnClickListener(){ public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
onDelBtnDown(position);
}
})
.setNegativeButton("重命名该图片", new OnClickListener(){ public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
onRenameBtnDown();
}
});
build.create().show();
return false;
}
});
}
//button down callbacks
private void onRenameBtnDown() {
// TODO Auto-generated method stub
}
private void onDelBtnDown(int pos) {
// TODO Auto-generated method stub
Log.d(LOG_TAG,"the pos will deleted is " + pos);
File current = new File(mImgPathList.get(pos));
current.delete();
mImgPathList.clear();
saveImagePathToList(mImgPathList, mSdcardPath);
// for(int i = 0 ; i < mImgPathList.size() ; i++){
// Log.e(LOG_TAG, mImgPathList.get(i));
// }
adapter = new ImageAdapter(this, mImgPathList);
mGallery.setAdapter(adapter);
mGallery.requestLayout();
RefreshView();
}
private void RefreshView(){
for(int i = 0 ; i < mImgPathList.size() ; i++){
Log.e("ImagePath",mImgPathList.get(i));
}
}
//get image path recursively
private void saveImagePathToList(ArrayList<String> list, String filePath) {
// TODO Auto-generated method stub
File mFile = new File(filePath);
File[] listFile = mFile.listFiles();
if(listFile != null){
for(int i = 0 ; i < listFile.length ; i++){
File file = listFile[i];
if(isAnImageFile(file.getAbsolutePath())){
list.add(file.getAbsolutePath());
}else if(file.isDirectory() && !file.getAbsolutePath().contains("DCIM")){
//get image path recursively
this.saveImagePathToList(mImgPathList, file.getAbsolutePath());
}
continue;
}
}
}
//check the fils's suffix and tell whether it's an image
private boolean isAnImageFile(String fileName){
String fileNameLowerCase = fileName.toLowerCase();
if(fileNameLowerCase.endsWith("jpg") || fileNameLowerCase.endsWith("gif")
|| fileNameLowerCase.endsWith("bmp") || fileNameLowerCase.endsWith("jpeg")
|| fileNameLowerCase.endsWith("png")){
return true;
}
return false;
} public View makeView() {
// TODO Auto-generated method stub
ImageView iv = new ImageView(this);
//iv.setBackgroundColor(0xFF000000);
iv.setScaleType(ImageView.ScaleType.FIT_CENTER);
iv.setLayoutParams(new ImageSwitcher.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));
return iv;
}
public class ImageAdapter extends BaseAdapter{
private Context mContext;
private int mGalleryBackground;
private ArrayList<String> mArrayList;
public ImageAdapter(Context c, ArrayList<String> list){
mContext = c;
mArrayList = list;
//use attrs.xml to specify the Gallery's attributes
TypedArray mTypeArray = obtainStyledAttributes(R.styleable.Gallery);
mGalleryBackground = mTypeArray.getResourceId(R.styleable.Gallery_android_galleryItemBackground, 0);
mTypeArray.recycle();
} public int getCount() {
// TODO Auto-generated method stub
return mArrayList.size();
} public Object getItem(int position) {
// TODO Auto-generated method stub
//just return position, will use it later
return position;
} public long getItemId(int position) {
// TODO Auto-generated method stub
//just return position will use it later
return position;
} public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
//new a ImageView for the image displaying
Log.d(LOG_TAG,"getView--->");
ImageView imgView = new ImageView(mContext);
//check the cache first
Bitmap current = imgCache.get(position);
if(current == null){
current = BitmapFactory.decodeFile(mArrayList.get(position));
imgCache.put(position, current);
}
imgView.setImageBitmap(current);
imgView.setScaleType(ImageView.ScaleType.FIT_XY);
imgView.setLayoutParams(new Gallery.LayoutParams(136, 88));
imgView.setBackgroundResource(mGalleryBackground);
return imgView;
}
} public void onItemSelected(AdapterView<?> arg0, View arg1, int pos,
long id) {
// TODO Auto-generated method stub
String imgPath = mImgPathList.get(pos);
Log.e(LOG_TAG,"Selected Img Path is " + imgPath);
Drawable drawadle = Drawable.createFromPath(imgPath);
mImgSwitcher.setImageDrawable(drawadle);
//release Bitmap resource
releaseBitmap();
} //just keep the bitmap in Visible range, release the rest
private void releaseBitmap() {
// TODO Auto-generated method stub
int begin = mGallery.getFirstVisiblePosition();
int end = mGallery.getLastVisiblePosition();
for(int i = 0 ; i < begin ; i++){
Bitmap delBitmap = imgCache.get(i);
if(delBitmap != null){
imgCache.remove(i);
delBitmap.recycle();
}
}
for(int i = end + 1 ; i < imgCache.size() ; i++){
Bitmap delBitmap = imgCache.get(i);
if(delBitmap != null){
imgCache.remove(i);
delBitmap.recycle();
}
}
}}代码很简单,劳烦大家看下,当我删除一张图片的时候,我该怎么更新gallery呢?我上面的用的方法大致能起作用,但是还是有一点bug,比如有时候,删除了一张图片,gallery上还是显示着,而ImageSwitcher显示了下一张。我知道, 我上面用的方法很搓,大家有好的方法,还希望多多分享。我没有做过android应用,最好能有实例提供,谢谢了先....
另外,
需要注意处理边界情况,例如只剩一张图、删除最后一张图时的情况。对于gallery和switcher不同步的情况,可以调用ImageSwitcher的setImageDrawable()方法直接设定图片,以保持同步显示。
++
for(int i = 0 ; i < begin ; i++){
Bitmap delBitmap = imgCache.get(i);
if(delBitmap != null){
imgCache.remove(i);
delBitmap.recycle();
// notifyDataSetChanged()大约加在这就好了~
}
}
你好,谢谢你的回复,但是你好像没看清我的代码。
我之前考虑过这样的做法,当我没删除一张图片的时候private void onDelBtnDown(int pos) {
// TODO Auto-generated method stub
Log.d(LOG_TAG,"the pos will deleted is " + pos);
File current = new File(mImgPathList.get(pos));
current.delete();
mImgPathList.remove(pos);
adapter.notifyDataSetChanged();
// mGallery.setAdapter(adapter);
...
}
O,我刚刚尝试上面的方法,gallery能够删掉了,但是gallery图片还有点错乱。我再找找原因吧,大概是逻辑上有点问题。做过这方面的朋友,能够传授一点点经验吗? 再次感谢lsThanks in advance for any help!
http://download.csdn.net/detail/mci2004/4293560 就是这里