看到小米手机和其他一些图片显示软件,gridview显示图片时候,长按某个item,可以进入编辑模式,试着也做了个。
在Android拍照、预览、上传综合的基础上改进,实现效果,长按gridview一个item图片显示,进入编辑模式,可以批量删除图片。两个需要注意的地方:
1、选中图片的边框效果。
实现方法:设置背景图片为将要显示的图片,然后设置图片源setImageResource为带2像素边框的透明小图片。
2、图片右上角给个小对号图片,标示选中。
实现方法:使用相对布局是这个小图片放在右上角。
总结:网上也没有找到一个得劲的实现方式,我做这个后来发现有些瑕疵,本来可以做的更好,如:需要在java代码中控制gridview的全屏以及上下隔出间距显示按钮等其他元素(因为我使用的是Framelayout,各个元素是重叠的,设置显示为gone也没用);如果使用Linearlayout应该可以做到不用java代码设置间距。
效果图如下:
这个没有demo,我把需要的图片,样式给放出来,关键地方有注释说明,源码如下:
【1】、图片展示类gridview
/**
* 图片预览
* @author: aokunsang
* @date: 2012-8-1
*/
public class PictureScanAct extends Activity {
private GridView gridView;
private ImageAdapter imgAdapter;
private TextView seclectNumView;
private Button deleteButton;
private List<LoadImage> fileNameList = new ArrayList<LoadImage>(); //保存Adapter中显示的图片详情(要跟adapter里面的List要对应)
private List<LoadImage> selectFileLs = new ArrayList<LoadImage>(); //保存选中的图片信息
private boolean isDbClick = false; //是否正在长按状态
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.picturescan);
gridView = (GridView)findViewById(R.id.picture_grid);
seclectNumView = (TextView)findViewById(R.id.pic_seclet_num);
deleteButton = (Button)findViewById(R.id.pic_delete);
deleteButton.setOnClickListener(delClickListener);
imgAdapter = new ImageAdapter(this);
gridView.setAdapter(imgAdapter);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
LoadImage loadimg = fileNameList.get(position);
ViewHolder holder = (ViewHolder)view.getTag();
if(isDbClick){
if(selectFileLs.contains(loadimg)){
holder.image1.setImageDrawable(null);
holder.image2.setVisibility(View.GONE);
imgAdapter.delNumber(position+"");
selectFileLs.remove(loadimg);
}else{
holder.image1.setImageResource(R.drawable.border); //添加图片(带边框的透明图片)[主要目的就是让该图片带边框]
holder.image2.setVisibility(View.VISIBLE); //设置图片右上角的对号显示
imgAdapter.addNumber(position+""); //把该图片添加到adapter的选中状态,防止滚动后就没有在选中状态了。
selectFileLs.add(loadimg);
}
seclectNumView.setText("选中"+selectFileLs.size()+"张图片");
}else{
startActivity(new Intent(PictureScanAct.this, PictureViewAct.class).putExtra("flag","upload").putExtra("imagePath",loadimg.getFileName()));
}
}
});
gridView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {
LoadImage loadimg = fileNameList.get(position);
ViewHolder holder = (ViewHolder)view.getTag();
if(!isDbClick){
isDbClick = true;
gridView.setPadding(0, 50, 0, 50); //长按后,让gridview上下都分出点空间,显示删除按钮之类的。看效果图就知道了。
seclectNumView.setVisibility(View.VISIBLE);
deleteButton.setVisibility(View.VISIBLE);
holder.image1.setImageResource(R.drawable.border);
holder.image2.setVisibility(View.VISIBLE);
imgAdapter.addNumber(position+"");
selectFileLs.add(loadimg);
seclectNumView.setText("选中1张图片");
return true;
}
return false;
}
});
Toast.makeText(this, "加载图片中....", Toast.LENGTH_SHORT).show();
new AsyncLoadedImage().execute();
}
/**
* 删除监听器事件
*/
private android.view.View.OnClickListener delClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if(selectFileLs.isEmpty()) {
Toast.makeText(PictureScanAct.this, "请选择图片", Toast.LENGTH_SHORT).show();
return ;
}
for(LoadImage loadimg : selectFileLs){
File file = new File(loadimg.getFileName());
boolean isTrue = file.delete();
Log.i("----------------------删除图片------", isTrue+"---------------");
}
imgAdapter.deletePhoto(selectFileLs);
seclectNumView.setText("选中0张图片");
}
};
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(isDbClick && keyCode == KeyEvent.KEYCODE_BACK){ //点击返回按键
isDbClick = false;
gridView.setPadding(0, 0, 0, 0); //退出编辑转台时候,使gridview全屏显示
seclectNumView.setVisibility(View.GONE);
deleteButton.setVisibility(View.GONE);
selectFileLs.clear();
imgAdapter.clear();
return false;
}
return super.onKeyDown(keyCode, event);
}
/**
* 异步加载图片展示
* @author: aokunsang
* @date: 2012-8-1
*/
class AsyncLoadedImage extends AsyncTask<Object, LoadImage, Boolean> {
@Override
protected Boolean doInBackground(Object... params) {
File fileDir = new File(Const.imgPath);
File[] files = fileDir.listFiles();
boolean result = false;
if(files!=null){
for(File file:files){
String fileName = file.getName();
if (fileName.lastIndexOf(".") > 0
&& fileName.substring(fileName.lastIndexOf(".") + 1,
fileName.length()).equals("jpg")){
Bitmap bitmap;
Bitmap newBitmap;
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 10;
bitmap = BitmapFactory.decodeFile(file.getPath(), options);
newBitmap = ThumbnailUtils.extractThumbnail(bitmap, 67, 70);
bitmap.recycle();
if (newBitmap != null) {
LoadImage loadImage = new LoadImage(file.getPath(),newBitmap);
fileNameList.add(loadImage);
publishProgress(loadImage);
result = true;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
return result;
}
@Override
public void onProgressUpdate(LoadImage... value) {
for(LoadImage loadImage:value){
imgAdapter.addPhoto(loadImage);
}
}
@Override
protected void onPostExecute(Boolean result) {
if(!result){
showDialog(1);
}
}
}
@Override
protected Dialog onCreateDialog(int id) {
AlertDialog dialog = new AlertDialog.Builder(PictureScanAct.this).setTitle("温馨提示").setMessage("暂时还没有照片,请先采集照片!")
.setPositiveButton("确定", new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
startActivity(new Intent(PictureScanAct.this,TakePhotoAct.class));
}
}).setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
}).show();
return dialog;
}
/**
* 图片详细信息bean
* @author: aokunsang
* @date: 2012-8-31
*/
public class LoadImage {
private String fileName;
private Bitmap bitmap;
public LoadImage() {
super();
// TODO Auto-generated constructor stub
}
public LoadImage(String fileName, Bitmap bitmap) {
super();
this.fileName = fileName;
this.bitmap = bitmap;
}
/**
* @return the fileName
*/
public String getFileName() {
return fileName;
}
/**
* @param fileName the fileName to set
*/
public void setFileName(String fileName) {
this.fileName = fileName;
}
/**
* @return the bitmap
*/
public Bitmap getBitmap() {
return bitmap;
}
/**
* @param bitmap the bitmap to set
*/
public void setBitmap(Bitmap bitmap) {
this.bitmap = bitmap;
}
@Override
public int hashCode() {
return this.getFileName().hashCode();
}
@Override
public boolean equals(Object o) {
LoadImage loadImg = (LoadImage)o;
return this.getFileName().equals(loadImg.getFileName());
}
}
【2】、图片展示布局
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <GridView android:id="@+id/picture_grid" android:layout_width="match_parent" android:layout_height="match_parent" android:numColumns="auto_fit" android:stretchMode="columnWidth" android:columnWidth="70dip" android:gravity="center" /> <TextView android:id="@+id/pic_seclet_num" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@drawable/btn" android:textSize="20sp" android:gravity="center" android:visibility="gone" /> <Button android:id="@+id/pic_delete" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/deletecontact" android:layout_gravity="bottom" android:textSize="20sp" android:visibility="gone" style="@style/btn_style" /> </FrameLayout>
【3】、适配器类
/**
* 图片适配器
* @author aokunsang
* @Date 2011-12-6
*/
public class ImageAdapter extends BaseAdapter {
private List<LoadImage> picList = new ArrayList<LoadImage>(); //图片集合
private List<String> picNumber = new ArrayList<String>(); //选中图片的位置集合
private LayoutInflater inflater;
public ImageAdapter(Context mContext){
inflater = LayoutInflater.from(mContext);
}
@Override
public int getCount() {
return picList.size();
}
@Override
public Object getItem(int position) {
return picList.get(position);
}
/**
* 添加选中状态的图片位置
* @param position
*/
public void addNumber(String position){
picNumber.add(position);
}
/**
* 去除已选中状态的图片位置
* @param position
*/
public void delNumber(String position){
picNumber.remove(position);
}
/**
* 清空已选中的图片状态
*/
public void clear(){
picNumber.clear();
notifyDataSetChanged();
}
/**
* 添加图片
* @param bitmap
*/
public void addPhoto(LoadImage loadImage){
picList.add(loadImage);
notifyDataSetChanged();
}
/**
* 删除图片
* @param loadimgLs
*/
public void deletePhoto(List<LoadImage> loadimgLs){
for(LoadImage img:loadimgLs){
if(picList.contains(img)){
picList.remove(img);
}
}
picNumber.clear();
notifyDataSetChanged();
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if(holder==null){
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.picturescan_item, null);
holder.image1 = (ImageView)convertView.findViewById(R.id.scan_img);
holder.image2 = (ImageView)convertView.findViewById(R.id.scan_select);
convertView.setTag(holder);
}else{
holder = (ViewHolder)convertView.getTag();
}
Drawable bit = new BitmapDrawable(picList.get(position).getBitmap());
holder.image1.setBackgroundDrawable(bit);
if(picNumber.contains(""+position)){ //如果该图片在选中状态,使其右上角的小对号图片显示,并且添加边框。
holder.image2.setVisibility(View.VISIBLE);
holder.image1.setImageResource(R.drawable.border);
}else{
holder.image2.setVisibility(View.GONE);
}
return convertView;
}
public static class ViewHolder{
public ImageView image1; //要显示的图片
public ImageView image2; //图片右上角的小对号图片(标示选中状态的玩意)
}
}
【4】、gridview的item布局
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingTop="3dip" android:paddingRight="3dip" > <ImageView android:id="@+id/scan_img" android:scaleType="centerCrop" android:layout_height="75dip" android:layout_width="90dip" /> <ImageView android:id="@+id/scan_select" android:layout_height="wrap_content" android:layout_width="wrap_content" android:src="@drawable/selected" android:layout_alignRight="@id/scan_img" android:layout_alignParentTop="true" android:padding="4dip" /> </RelativeLayout>