package com.mfh.comna.view.img; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.text.TextUtils; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.widget.FrameLayout; import android.widget.ImageView; import com.mfh.comna.api.utils.ImageUtil; import com.mfh.comna.api.utils.MLog; import com.mfh.comna.bizz.AppConfig; import com.mfh.comna.bizz.material.logic.BitMapCacheService; import com.mfh.comn.config.UConfig; import com.mfh.comna.R; import com.mfh.comna.comn.cfg.UConfigHelper; import com.mfh.comna.comn.database.dao.FileNetDao; import com.mfh.comna.comn.logic.MyAsyncTask; import com.mfh.comna.comn.logic.ServiceFactory; import org.slf4j.LoggerFactory; import java.io.File; import java.util.HashMap; import java.util.Map; /** * 关于图像显示的自定义类。 * 支持先从网络(网络地址通过配置项serverUrlconfigItem指定)上下载存到本地(本地目录名在变量localDir中指定), * 然后再显示;以后就直接从本地进行显示了。 * 支持图片过大时使用缩略图。 * Created by Shicy on 14-3-19. */ public class FineImgView extends FrameLayout { private ImageView imageView; private BitMapCacheService cache; private FileNetDao fao; private Bitmap bitmap; //private String serverUrlconfigItem = DEFAULT_ITEM;//图片服务器配置项,若为null代表是全地址,不需要。 //private String localDir = LOCAL_DIR; private Integer maxWidth = null;//若设置了最大宽度,则应考虑采用缩略图显示,避免内存溢出。 private boolean needSample = false;//是否需要使用缩略图。 private static String DEFAULT_ITEM = "app.head.server.url"; private static String LOCAL_DIR = "headImgDir"; private static Map<String, FileNetDao> fileDaoMap = new HashMap<String, FileNetDao>(); /** * 获取网络文件访问对象 * @param configKeyParam 网络文件服务器url地址配置项,可以为空 * @param localDir 网络文件下载到本地存储的目录 * @return */ public static FileNetDao getFao(String configKeyParam, String localDir) { String configKey = configKeyParam; if (configKey == null || configKey.length() == 0) configKey = localDir; FileNetDao ret = fileDaoMap.get(configKey); if (ret == null) { String imgServerUrl = null; if (configKey != null) { imgServerUrl = UConfigHelper.getConfig().getDomain(UConfig.CONFIG_COMMON) .getString(configKey, "http://resource.manfenmm.com/mfh/image/wxuser/"); if (!imgServerUrl.endsWith( "/")) imgServerUrl += "/"; } else imgServerUrl = ""; ret = new FileNetDao(localDir, imgServerUrl); fileDaoMap.put(configKey, ret); } return ret; } /** * 布局文件 * @return */ protected int getLayOutResource() { return R.layout.subview_member_head; } public FineImgView(Context context, AttributeSet attrs) { super(context, attrs); View view = LayoutInflater.from(context).inflate(getLayOutResource(), this, true); imageView = (ImageView)view.findViewById(R.id.ms_headImgView); cache = ServiceFactory.getService(BitMapCacheService.class, context); } public static FileNetDao getHeadImgFao() { if(AppConfig.RELEASE){ return getFao(DEFAULT_ITEM, LOCAL_DIR); }else{ return getFao("dev." + DEFAULT_ITEM, LOCAL_DIR); } } public ImageView getImageView() { return imageView; } public void setFao(FileNetDao fao) { this.fao = fao; } public FileNetDao getFao() { return fao; } /** * 设置显示宽度,可以用于判断是否需要使用缩略图显示以节省内存加快速度。 * @param reqWidth */ public void setMaxWidth(Integer reqWidth) { this.maxWidth = reqWidth; } public void setNeedSample(boolean needSample) { this.needSample = needSample; } /*public void setServerUrlconfigItem(String serverUrlconfigItem) { this.serverUrlconfigItem = serverUrlconfigItem; } public void setLocalDir(String localDir) { this.localDir = localDir; }*/ /** * 设置网络图片地址,未来内部应使用缓存。 * @param url */ public void setSrc(final String url) { if (TextUtils.isEmpty(url)) { imageView.setImageResource(R.drawable.chat_tmp_user_head); return; } // final String cacheKey = url + Boolean.toString(this.needSample) // + (maxWidth == null ? "" : maxWidth.toString());//生成cacheKey if (cache != null) {//优先使用缓存 bitmap = cache.getBitmapFromMemCache(url); if (bitmap != null) { imageView.setImageBitmap(bitmap); return; } } //***下面这一块是从内存卡中读取 File file = new File(url); if (file.exists()) { new BitmapAysn(false,true).execute(url); return; } //****** if (fao == null) { fao = getHeadImgFao();//使用默认的 } fao.processFile(url, new FileNetDao.CallBack() { @Override public void processFile(File file) { MLog.d("processFile: " + file.toString()); try { bitmap = null; if (needSample){ new BitmapAysn(false,false).executeOnExecutor(cache.getBitmapExecutor(), file.getName()); } else { bitmap = BitmapFactory.decodeFile(file.getAbsolutePath()); imageView.setImageBitmap(bitmap); if (cache != null)//加入缓存 cache.addBitmapToMemoryCache(url, bitmap); } } catch (Throwable e) { if (e instanceof OutOfMemoryError && !needSample) { try { bitmap = ImageUtil.compressImageBySize(file.getAbsolutePath(), maxWidth); imageView.setImageBitmap(bitmap); } catch (Throwable e1) { LoggerFactory.getLogger(this.getClass()).error(e1.getMessage(), e1); } } else LoggerFactory.getLogger(this.getClass()).error(e.getMessage(), e); } } @Override public void onFailure(String fileName, Throwable e) { MLog.d(String.format("file:%s, because:%s", fileName, e.toString())); } }); } // /** // * 获取原始位图 // * @param file // * @return // */ // private Bitmap genBitmap(File file) { // InputStream is = null; // try { // is = new FileInputStream(file); // return BitmapFactory.decodeStream(is); // } // catch (IOException e) { // LoggerFactory.getLogger(this.getClass()).error(e.getMessage(), e); // return null; // } // finally { // if (is != null) { // try { // is.close(); // } catch (IOException e) { // } // } // } // } /** // * 获取缩略图 // * @param theWidth 允许宽度 // * @return // */ // private Bitmap decodeSampledBitmap(String filePath, Integer theWidth) { // if (theWidth == null) // theWidth = this.getWidth(); // try { // BitmapFactory.Options options = new BitmapFactory.Options(); // // options.inJustDecodeBounds = true; // Bitmap bitmap = BitmapFactory.decodeFile(filePath); // // double dh = options.outHeight; // double dw = options.outWidth; // int sample = calculateInSampleSize(options, theWidth, (int) (theWidth * (dh / dw))); // options.inSampleSize = sample; // options.inJustDecodeBounds = false; // return BitmapFactory.decodeFile(filePath,options); // } // catch (Throwable e) { // LoggerFactory.getLogger(this.getClass()).error(e.getMessage(), e); // return null; // } // } // /** // * 获取缩放比例,大于1代表要缩小原图 // * @param options // * @param reqWidth // * @param reqHeight // * @return // */ // public static int calculateInSampleSize( // BitmapFactory.Options options, int reqWidth, int reqHeight) { // // Raw height and width of image // final int height = options.outHeight; // final int width = options.outWidth; // int inSampleSize = 1; // // if (height > reqHeight || width > reqWidth) { // if (width > height) { // inSampleSize = Math.round((float)height / (float)reqHeight); // } else { // inSampleSize = Math.round((float)width / (float)reqWidth); // } // } // return inSampleSize; // } public Bitmap getBitmap() { return bitmap; } private class BitmapAysn extends MyAsyncTask<String, Bitmap> { private boolean isSd; protected BitmapAysn(boolean showDialog,boolean isSd) { super(showDialog); this.isSd = isSd; } @Override protected Bitmap doInBackgroundInner(String... params) { if (maxWidth == null) { maxWidth = getWidth(); } String url = params[0]; if (!isSd) url = fao.readFile(url).getAbsolutePath(); bitmap = ImageUtil.compressImageBySize(url,maxWidth); bitmap = ImageUtil.solveBitmap(bitmap); if (cache != null && !TextUtils.isEmpty(params[0]) && bitmap != null) //加入缓存 cache.addBitmapToMemoryCache(params[0], bitmap); return bitmap; } @Override protected void onPostExecuteInner(Bitmap result, String... params) { imageView.setImageBitmap(result); } } }