GridView 异步加载SD卡图片

用GridView实现异步加载SD卡图片,图片无错位。

初学安卓,遇到了很多问题,在网上得到了很多帮助,谢谢各位好心人。把代码发下来与大家分享,有啥问题欢迎讨论~

import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Menu;
import android.widget.GridView;


public class MainActivity extends Activity {
private String mRootPath = Environment.getExternalStorageDirectory().getPath()+"/"+"dcim"+"/"; 
private Intent mIntent;
private ProgressDialog m_ProgressDialog = null;
    final int MENU_ONE = Menu.FIRST;
    final int MENU_TWO = Menu.FIRST + 1;
    public static List<String> lstFilePath = null;
    
/** 清除LST */
public static void unloadLstFilePath() {
   if (lstFilePath != null) {
     lstFilePath.clear();
     lstFilePath = null;
   }
 }
 
private void getValues() {
   if (lstFilePath == null) {
     Log.v("***InLstFilePath***", "OK");
     lstFilePath = new ArrayList<String>();
     lstFilePath.clear();

     new FileTool().ListFiles(mRootPath, lstFilePath);
     String addPath = this.getFilesDir().getPath();
     new FileTool().ListFiles(addPath, lstFilePath);
   } else {
     try {
       Thread.sleep(500);
     } catch (InterruptedException e) {
       e.printStackTrace();
     }
     ;
   }
   runOnUiThread(returnRes);
 }

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        mIntent = this.getIntent();
        
        Runnable viewOrders = new Runnable() {
            public void run() { getValues();  }
        };
          
        Thread thread = new Thread(null, viewOrders, "MagentoBackground");
        thread.start();

        m_ProgressDialog = ProgressDialog.show( MainActivity.this, "请稍后", "数据读取中...", true); 
        
        
        
    }
        
        
    
    private Runnable returnRes = new Runnable() {

        public void run() {
          DisplayMetrics metric = new DisplayMetrics();
             getWindowManager().getDefaultDisplay().getMetrics(metric);
             int columnWidth = metric.widthPixels/4;     // 屏幕宽度(像素)
          GridView gridview = (GridView) findViewById(R.id.gv_photolist);
          GridViewAdapter iadapter = new GridViewAdapter(MainActivity.this, lstFilePath);
             gridview.setAdapter(iadapter);
          gridview.setColumnWidth(columnWidth);                 
             m_ProgressDialog.dismiss();
        }
      };
}

import java.util.List;
import com.yjx.yibu.AsyncImageLoader3.ImageCallback;
import android.content.Context;
import android.graphics.Bitmap;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;



public class GridViewAdapter extends BaseAdapter {

private LayoutInflater layoutInflater;
private List<String> imgUrls;
private AsyncImageLoader3 imageLoader = new AsyncImageLoader3();

public GridViewAdapter(Context context, List<String> imgUrls) {
layoutInflater = LayoutInflater.from(context);
this.imgUrls = imgUrls;
}


@Override
public int getCount() {
return imgUrls.size();
}

@Override
public Object getItem(int position) {

return position;
}

@Override
public long getItemId(int position) {

return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {


final ViewHolder viewHolder;
String path = imgUrls.get(position);
if(convertView==null) {
viewHolder = new ViewHolder();
convertView = layoutInflater.inflate(R.layout.photolist_item, null);
viewHolder.ivImage = (ImageView)convertView.findViewById(R.id.iv_photoicon_photolist_item);
viewHolder.ivImage.setScaleType(ImageView.ScaleType.CENTER);
convertView.setTag(viewHolder);
       }

else {
viewHolder = (ViewHolder)convertView.getTag();
}
         Bitmap cachedImage = imageLoader.loadBitmap(path,viewHolder.ivImage, new ImageCallback() {  	 
  public void imageLoaded(Bitmap imageBitmap,ImageView image,String imageUrl) {
 viewHolder.ivImage.setImageBitmap(imageBitmap);
}
});
        
         if(cachedImage!= null) {
        viewHolder.ivImage.setImageBitmap(cachedImage);
 
          }
else if(cachedImage == null) {
viewHolder.ivImage.setImageResource(R.drawable.icon);
        }
return convertView;
}

class ViewHolder {
/**
* 图片
*/
public ImageView ivImage;
/**
* 图片信息
*/
//	public TextView tvInfo;

}
}

import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import android.graphics.Bitmap;
import android.os.Handler;
import android.widget.ImageView;

public class AsyncImageLoader3 {
// 为了加快速度,在内存中开启缓存(主要应用于重复图片较多时,或者同一个图片要多次被访问,比如在ListView时来回滚动)
public Map<String, SoftReference<Bitmap>> imageCache = new HashMap<String, SoftReference<Bitmap>>();
private ExecutorService executorService = Executors.newFixedThreadPool(5); // 固定五个线程来执行任务
private final Handler handler = new Handler();

/**
* 
* @param imageUrl
*            图像url地址
* @param callback
*            回调接口
* @return 返回内存中缓存的图像,第一次加载返回null
*/
public Bitmap loadBitmap(final String imageUrl, final ImageView image,final ImageCallback callback) {
// 如果缓存过就从缓存中取出数据
if (imageCache.containsKey(imageUrl)) {
SoftReference<Bitmap> softReference = imageCache.get(imageUrl);
if (softReference.get() != null) {
return softReference.get();
}
}
// 缓存中没有图像,则从SDcard取出数据,并将取出的数据缓存到内存中
executorService.submit(new Runnable() {
public void run() {
try {
final Bitmap bitmap = loadImageFromSD(imageUrl); 
imageCache.put(imageUrl, new SoftReference<Bitmap>(
bitmap));

handler.post(new Runnable() {
public void run() {
callback.imageLoaded(bitmap, image,imageUrl);
}
});
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
return null;
}

// 从SDcard取数据方法
protected Bitmap loadImageFromSD(String path) {
try {
// 测试时,模拟网络延时,实际时这行代码不能有
//	SystemClock.sleep(2000);
Bitmap bm = new BitmapTool().charge(path);
return bm;
} catch (Exception e) {
throw new RuntimeException(e);
}
}

// 对外界开放的回调接口
public interface ImageCallback {
// 注意 此方法是用来设置目标对象的图像资源
public void imageLoaded(Bitmap imageDrawable, ImageView image, String imageUrl);
}

}

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;

public class BitmapTool {
public BitmapTool() {
}
/** 图片适配大小 */
  public Bitmap change(String path) {

    Bitmap bm = null;   
    
    BitmapFactory.Options optsa = new BitmapFactory.Options();
    optsa.inSampleSize = 10;
    bm = BitmapFactory.decodeFile(path, optsa);
    
    if(bm != null) {
    } else {
      return null;
    }

    /**不同尺寸图片的缩放比例*/
   if((bm.getHeight() ) <=150 || (bm.getWidth()) <=100 ) {
    optsa.inSampleSize = 1;
 	     bm = BitmapFactory.decodeFile(path, optsa);
    }
   else  if( (bm.getHeight() )<=300  || (bm.getWidth()) <= 200){
    optsa.inSampleSize =10;
    bm = BitmapFactory.decodeFile(path, optsa);
}
   
   else if(  ( (bm.getHeight() )<=450 ) ||(  (bm.getWidth()) <= 300)){
    optsa.inSampleSize =20;
    bm = BitmapFactory.decodeFile(path, optsa);
 } 
   else if(  ((bm.getHeight() )<=600 ) ||(  (bm.getWidth()) <= 400)){
    optsa.inSampleSize =30;
    bm = BitmapFactory.decodeFile(path, optsa);
  } 
   else if(  ( (bm.getHeight() )<=750 ) ||(   (bm.getWidth()) <= 500)) {
    optsa.inSampleSize = 40;
    bm = BitmapFactory.decodeFile(path, optsa);
  } 
   else  if(  ((bm.getHeight() )<=900 ) ||(   (bm.getWidth()) <= 600)) {
    optsa.inSampleSize = 50;
    bm = BitmapFactory.decodeFile(path, optsa);
  } 
   else  {
 	     optsa.inSampleSize = 60;
 	     bm = BitmapFactory.decodeFile(path, optsa);
   } 
   
    return bm;
  }
  
  /** 图片适配大小 ,同时缩放比例*/
  public Bitmap charge(String path) {
    Bitmap bm = this.change(path);
    int sWidth = bm.getWidth();
    int sHeigth = bm.getHeight();
    
    if(bm != null) {
      bm = this.zoomImage(bm,  sWidth,sHeigth);  
    } 
    
    return bm;
  }

  /***
     * 图片的缩放方法
     *
     * @param bgimage
     *            :源图片资源
     * @param newWidth
     *            :缩放后宽度
     * @param newHeight
     *            :缩放后高度
     * @return
     */
    public Bitmap zoomImage(Bitmap bgimage, int newWidth, int newHeight) {
            // 获取这个图片的宽和高
            int width = bgimage.getWidth();
            int height = bgimage.getHeight();
            // 创建操作图片用的matrix对象
            Matrix matrix = new Matrix();
            // 计算缩放率,新尺寸除原始尺寸
            float scaleWidth = ((float) newWidth) / width;
            float scaleHeight = ((float) newHeight) / height;
            // 缩放图片动作
            matrix.postScale(scaleWidth, scaleHeight);            
            Bitmap bitmap = Bitmap.createBitmap(bgimage, 0, 0, width, height,
                            matrix, true);
            return bitmap;
    }
}

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;
import android.os.Environment;
import android.util.Log;


public class FileTool {
 /** 图片内存最小值 5K */
 private final static int PIC_FILE_SIZE_MIN = 5;
 /** 图片内存最大值 300K */
 private final static int PIC_FILE_SIZE_MAX = 6000;
 
 
 /**
    * 遍历目录,得到所有图片文件路径集群
    * @param path
    * @return
    */
   public void ListFiles(String path, List<String> lstPaths){
  
       File file = new File(path);   

       
     if(file == null)
       return;
     
     if(file.isDirectory() ) {       
       String curpath = Environment.getExternalStorageDirectory().getPath()+"/"+"dcim"+"/"+".thumbnails";
       if(path.equals(curpath))
         return;
     }
     
     File[] fs = file.listFiles();
     if(fs==null) 
   	  return;
     for(File f : fs){
        if(f==null)
             continue;
       
        String fName = f.getName();     
        String htx = fName.substring(fName.lastIndexOf(".") + 1,
        fName.length()).toLowerCase();  //得到扩展名
     
       if(htx.equals("png") || htx.equals("jpg") ||
         htx.equals("gif") || htx.equals("bmp")) {
       
       if(fileSizeValidity(f.getPath())) {
         lstPaths.add(f.getPath());
         Log.v("***PIC_FILE***", fName);
       }
     } else {

     }

     path = f.getAbsolutePath();
     if(f.isDirectory() == true) {
       ListFiles(path, lstPaths);      //当f为文件夹的时候,进入文件夹中      
     }
   }
   }
   
   /** 
    * 判断文件大小有效性
    * 如果文件内存在5K-300K之间则有效,否则返回FALSE
    * @param path
    * @return
    */
   private boolean fileSizeValidity(String path) {
     File f = new File(path);
     if(f.exists()) {
       int cur = 0;
       FileInputStream fis = null;
     try {
       fis = new FileInputStream(f);
       
       cur = fis.available()/1000;
       
     } catch (FileNotFoundException e) {
       e.printStackTrace();
     } catch (IOException e) {
       e.printStackTrace();
     } finally {
       try {
         fis.close();            
       } catch (IOException e) {
         e.printStackTrace();
       }
     }
     
     //图片内存在5K-300K之间,表示有效
     if(cur>=PIC_FILE_SIZE_MIN && cur<=PIC_FILE_SIZE_MAX)
       return true;
     
     }
     
     return false;
   }
}

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fillable_area"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center_horizontal"
    android:orientation="vertical" >

<GridView xmlns:android="http://schemas.android.com/apk/res/android"   
    android:id="@+id/gv_photolist"      
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"  
    android:padding="10dp"  
    android:verticalSpacing="10dp"  
    android:horizontalSpacing="10dp"  
    android:numColumns="auto_fit"  
    android:columnWidth="100dp"  
    android:stretchMode="columnWidth"  
    android:gravity="center"  >
</GridView>
</LinearLayout>

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"   
android:layout_height="wrap_content"   
android:paddingBottom="4dip" android:layout_width="fill_parent">  
<ImageView android:layout_height="100px"   
android:layout_width="150px"   
android:layout_centerHorizontal="true"
android:id="@+id/iv_photoicon_photolist_item"/>   
           
</RelativeLayout>  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值