介紹一下Android圖片加載的4種框架的基本使用方法canvas
定義了Constants類來存儲一些圖片網址緩存
以後就一步一步來就能夠了(註釋很詳細~~~)併發
一,Glide:框架
public class GlideActivity extends AppCompatActivity { private ListView listView; private String[] imageUrl; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_list); listView = (ListView) findViewById(R.id.listview_my); imageUrl = Constants.imagesGif; listView.setAdapter(new GlideAdapter()); } class GlideAdapter extends BaseAdapter { @Override public int getCount() { return imageUrl.length; } @Override public Object getItem(int position) { return imageUrl[position]; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { convertView = getLayoutInflater().inflate(R.layout.list_item_gif, parent, false); holder = new ViewHolder(convertView); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } initGlide(holder,position); return convertView; } class ViewHolder { private ImageView imageView; public ViewHolder(View view) { super(); imageView = (ImageView) view.findViewById(R.id.iv_gif); } } } public void initGlide(GlideAdapter.ViewHolder holder, int pos) { //這也是最基本的寫法 // Glide.with(this).load(imageUrl[pos]).into(holder.imageView); ViewPropertyAnimation.Animator animationObject = new ViewPropertyAnimation.Animator() { @Override public void animate(View view) { view.setAlpha( 0f ); ObjectAnimator fadeAnim = ObjectAnimator.ofFloat(view, "alpha", 0f, 1f ); fadeAnim.setDuration( 2500 ); fadeAnim.start(); } }; // Glide.with(this).load(imageUrl[pos]) .placeholder(R.mipmap.ic_launcher) .error(R.mipmap.ic_launcher) .animate(animationObject) //漸變更畫 // .dontAnimate()//移除動畫 //.skipMemoryCache(true) //禁止內存緩存 //.diskCacheStrategy(DiskCacheStrategy.NONE) //禁止磁盤緩存 //DiskCacheStrategy.SOURCE:緩存原始數據, // DiskCacheStrategy.RESULT:緩存變換(如縮放、裁剪等)後的資源數據, // DiskCacheStrategy.NONE:什麼都不緩存, // DiskCacheStrategy.ALL:緩存SOURC和RESULT。 // 默認採用DiskCacheStrategy.RESULT策略, // 對於download only操做要使用DiskCacheStrategy.SOURCE。 .priority(Priority.HIGH) //優先加載 //指定加載的優先級,優先級越高越優先加載,但不保證全部圖片都按序加載 //Priority.IMMEDIATE,Priority.HIGH,Priority.NORMAL,Priority.LOW。默認爲Priority.NORMAL。 .thumbnail(0.5f) //利用原圖的一半做爲縮略圖 //請求給定係數的縮略圖。若是縮略圖比全尺寸圖先加載完,就顯示縮略圖,不然就不顯示。 // 係數sizeMultiplier必須在(0,1)之間,能夠遞歸調用該方法。 //.override(100,100)//從新設置寬高 單爲 px //先添加依賴 compile 'jp.wasabeef:glide-transformations:2.0.0' .bitmapTransform(new CropCircleTransformation(this))//圓形處理 // .bitmapTransform(new RoundedCornersTransformation // (this,30,0, RoundedCornersTransformation.CornerType.ALL))//圓角處理 .into(holder.imageView); } }
二,Picasso:ide
public class PicassoActivity extends AppCompatActivity { private ListView listView; private String[] imageUrl; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_list); listView = (ListView) findViewById(R.id.listview_my); imageUrl = Constants.images; listView.setAdapter(new PicassoAdapter()); } class PicassoAdapter extends BaseAdapter { @Override public int getCount() { return imageUrl.length; } @Override public Object getItem(int position) { return imageUrl[position]; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { convertView = getLayoutInflater().inflate(R.layout.list_item, parent, false); holder = new ViewHolder(convertView); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } initPicasso(holder,position); return convertView; } class ViewHolder { private ImageView imageView; public ViewHolder(View view) { super(); imageView = (ImageView) view.findViewById(R.id.iv_item); } } } public void initPicasso(PicassoAdapter.ViewHolder holder, int pos) { //最最基本的寫法 //Picasso.with(this).load(imageUrl[pos]).into(holder.imageView); Picasso.with(this).load(imageUrl[pos]) .placeholder(R.mipmap.ic_launcher)//加載時的圖片 .error(R.mipmap.ic_launcher) //失敗時的圖片 // .resize(50, 50).centerCrop()//剪裁圖片 .transform(new CircleTransform())//自定義轉換圓形圖片 // .memoryPolicy(MemoryPolicy.NO_CACHE,MemoryPolicy.NO_STORE)//不使用內存緩存 // .networkPolicy(NetworkPolicy.NO_CACHE,NetworkPolicy.NO_STORE)//不使用磁盤緩存 .into(holder.imageView); } public class CircleTransform implements Transformation { @Override public Bitmap transform(Bitmap source) { int size = Math.min(source.getWidth(), source.getHeight()); int x = (source.getWidth() - size) / 2; int y = (source.getHeight() - size) / 2; Bitmap squaredBitmap = Bitmap.createBitmap(source, x, y, size, size); if (squaredBitmap != source) { source.recycle(); } Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig()); Canvas canvas = new Canvas(bitmap); Paint paint = new Paint(); BitmapShader shader = new BitmapShader(squaredBitmap, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP); paint.setShader(shader); paint.setAntiAlias(true); float r = size / 2f; canvas.drawCircle(r, r, r, paint); squaredBitmap.recycle(); return bitmap; } @Override public String key() { return "circle"; } } }
三,Fresco:post
public class FrescoActivity extends AppCompatActivity { private String[] imageUrl; private ListView listView; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); Fresco.initialize(this);//必定要在setContentView以前寫 setContentView(R.layout.activity_list); listView = (ListView) findViewById(R.id.listview_my); imageUrl = Constants.images; listView.setAdapter(new FrescoAdapter()); } class FrescoAdapter extends BaseAdapter { @Override public int getCount() { return imageUrl.length; } @Override public Object getItem(int position) { return imageUrl[position]; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { convertView = getLayoutInflater().inflate(R.layout.list_item_fresco, null); holder = new ViewHolder(convertView); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } Uri uri = Uri.parse(imageUrl[position]); initDraweeView(holder.simpleDraweeView, uri); return convertView; } class ViewHolder { private SimpleDraweeView simpleDraweeView; public ViewHolder(View view) { super(); simpleDraweeView = (SimpleDraweeView) view.findViewById(R.id.draw); } } } public void initDraweeView(SimpleDraweeView simpleDraweeView, Uri uri) { DraweeController draweeController = Fresco.newDraweeControllerBuilder() .setUri(uri) .setAutoPlayAnimations(true) .build(); simpleDraweeView.setController(draweeController); } }
四,Android Universal Image Loader:動畫
part1:ui
public class UILApp extends Application { @Override public void onCreate() { super.onCreate(); initMyImageLoader(this); } /** * 4這個方法是對ImageLoaderConfiguration各屬性解釋 * 切記不要瞎用 */ public static void initImageLoader(Context context) { //這裏的路徑能夠自定義 File cacheDir = StorageUtils.getCacheDirectory(context); ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context) // 默認等於你的屏幕尺寸,設備屏幕寬高 .memoryCacheExtraOptions(480, 800) // 在將下載的圖片保存到你的sd卡以前會從新計算,壓縮。 // 這個屬性不要濫用,只有你在對應的需求時再用,由於他會使你的ImageLoader變的很慢。 .diskCacheExtraOptions(480, 800, null) //用於執行從源獲取圖片任務的 Executor,爲configuration中的 taskExecutor, // 若是爲null,則會調用DefaultConfigurationFactory.createExecutor(…)根據配置返回一個默認的線程池。 .taskExecutor(null) //用於執行從緩存獲取圖片任務的 Executor,爲configuration中的 taskExecutorForCachedImages, // 若是爲null,則會調用DefaultConfigurationFactory.createExecutor(…)根據配置返回一個默認的線程池。 .taskExecutorForCachedImages(null) // 表示核心池大小(最大併發數) 默認爲3 .threadPoolSize(3) // 線程優先級,默認Thread.NORM_PRIORITY - 2 .threadPriority(Thread.NORM_PRIORITY - 2) // 任務進程的順序,默認爲:FIFO 先進先出 .tasksProcessingOrder(QueueProcessingType.FIFO) //設置內存緩存不容許緩存一張圖片的多個尺寸,默認容許。 .denyCacheImageMultipleSizesInMemory() //圖片內存緩存 .memoryCache(new LruMemoryCache(2 * 1024 * 1024)) //memoryCacheSize 爲 0,則設置該內存緩存的最大字節數爲 App 最大可用內存的 1/8。 .memoryCacheSize(2 * 1024 * 1024) // 建立最大的內存緩存百分比,默認爲 13% .memoryCacheSizePercentage(13) // 硬盤緩存路徑,默認爲StorageUtils.getCacheDirectory(context) .diskCache(new UnlimitedDiskCache(cacheDir)) //硬盤緩存大小 .diskCacheSize(50 * 1024 * 1024) //緩存文件數量 .diskCacheFileCount(100) // 硬盤緩存文件名生成器,默認爲哈希文件名生成器 .diskCacheFileNameGenerator(new HashCodeFileNameGenerator()) // 建立圖片下載器,默認是BaseImageDownloader .imageDownloader(new BaseImageDownloader(context)) // 圖片解碼器,負責將圖片輸入流InputStream轉換爲Bitmap對象 .imageDecoder(new BaseImageDecoder(true)) // 圖片顯示的配置項。好比加載前、加載中、加載失敗應該顯示的佔位圖片,圖片是否須要在磁盤緩存,是否須要在內存緩存等。 .defaultDisplayImageOptions(DisplayImageOptions.createSimple()) //是否顯示調試log信息 .writeDebugLogs() .build(); ImageLoader.getInstance().init(config); } /** * 這個是推薦的寫法 */ public static void initMyImageLoader(Context context) { //緩存文件的目錄 File cacheDir = StorageUtils.getOwnCacheDirectory(context, "imageloader/Cache"); ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context) .memoryCacheExtraOptions(480, 800) // max width, max height,即保存的每一個緩存文件的最大長寬 .threadPoolSize(3) //線程池內加載的數量 .threadPriority(Thread.NORM_PRIORITY - 2) .denyCacheImageMultipleSizesInMemory() .diskCacheFileNameGenerator(new Md5FileNameGenerator()) //將保存的時候的URI名稱用MD5 加密 .memoryCache(new UsingFreqLimitedMemoryCache(2 * 1024 * 1024)) //你能夠經過本身的內存緩存實現 .memoryCacheSize(2 * 1024 * 1024) // 內存緩存的最大值 .diskCacheSize(50 * 1024 * 1024) // 50 Mb sd卡(本地)緩存的最大值 .tasksProcessingOrder(QueueProcessingType.LIFO) .diskCache(new UnlimitedDiskCache(cacheDir))//自定義緩存路徑 .imageDownloader(new BaseImageDownloader(context, 5 * 1000, 30 * 1000)) // connectTimeout (5 s), readTimeout (30 s)超時時間 .writeDebugLogs() .build(); //全局初始化此配置 ImageLoader.getInstance().init(config); } }
part2:this
public class UILActivity extends AppCompatActivity implements View.OnClickListener { private ListView listView; private String[] imageUrl; private DisplayImageOptions options; private ImageLoader imageLoader; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_list_uil); imageLoader = ImageLoader.getInstance(); listView = (ListView) findViewById(R.id.listview_uil); findViewById(R.id.btn_clear_disk).setOnClickListener(this); findViewById(R.id.btn_clear_memory).setOnClickListener(this); imageUrl = Constants.images; initMyOptions(); listView.setAdapter(new UILAdapter()); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_clear_disk: imageLoader.clearDiskCache(); Toast.makeText(UILActivity.this, "已清除本地緩存", Toast.LENGTH_SHORT).show(); break; case R.id.btn_clear_memory: imageLoader.clearMemoryCache(); Toast.makeText(UILActivity.this, "已清除內存緩存", Toast.LENGTH_SHORT).show(); break; } } class UILAdapter extends BaseAdapter { @Override public int getCount() { return imageUrl.length; } @Override public Object getItem(int position) { return imageUrl[position]; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { convertView = getLayoutInflater().inflate(R.layout.list_item, parent, false); holder = new ViewHolder(convertView); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } imageLoader.displayImage(imageUrl[position], holder.imageView, options); return convertView; } class ViewHolder { private ImageView imageView; public ViewHolder(View view) { super(); imageView = (ImageView) view.findViewById(R.id.iv_item); } } } /** * 這裏是對options全部屬性的解釋 */ public void initOptions() { options = new DisplayImageOptions.Builder() // 正在加載時顯示的佔位圖 .showImageOnLoading(R.mipmap.ic_launcher) // URL爲空時顯示的佔位圖 .showImageForEmptyUri(R.mipmap.ic_launcher) // 加載失敗時顯示的佔位圖 .showImageOnFail(R.mipmap.ic_launcher) // 在加載前是否重置 view,默認爲false .resetViewBeforeLoading(false) //設置在開始加載前的延遲時間,單位爲毫秒,經過 Builder 構建的對象默認爲 0 .delayBeforeLoading(1000) // 是否緩存在內存中,經過 Builder 構建的對象默認爲 false .cacheInMemory(false) // 是否緩存在磁盤中,經過 Builder 構建的對象默認爲 false。 .cacheOnDisk(false) //緩存在內存以前的處理程序,默認爲 null .preProcessor(null) //緩存在內存以後的處理程序,默認爲 null。 .postProcessor(null) //下載器須要的輔助信息。下載時傳入ImageDownloader.getStream(String, Object)的對象,方便用戶本身擴展,默認爲 null。 .extraForDownloader(null) // 是否考慮圖片的 EXIF 信息,經過 Builder 構建的對象默認爲 false。 .considerExifParams(false) // 圖片的縮放類型,經過 Builder 構建的對象默認爲IN_SAMPLE_POWER_OF_2 .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2) // bitmap的質量,默認爲ARGB_8888 .bitmapConfig(Bitmap.Config.ARGB_8888) //爲 BitmapFactory.Options,用於BitmapFactory.decodeStream(imageStream, null, decodingOptions)獲得圖片尺寸等信息。 .decodingOptions(null) // 在ImageAware中顯示 bitmap 對象的接口。可在實現中對 bitmap 作一些額外處理,好比加圓角、動畫效果。 .displayer(new SimpleBitmapDisplayer()) // handler 對象,默認爲 null .handler(new Handler()) .build(); } /** * 這是我要使用的options */ public void initMyOptions() { // 使用DisplayImageOptions.Builder()建立DisplayImageOptions options = new DisplayImageOptions.Builder() .showImageOnLoading(R.mipmap.ic_launcher) // 設置圖片下載期間顯示的圖片 .showImageForEmptyUri(R.mipmap.ic_launcher) // 設置圖片Uri爲空或是錯誤的時候顯示的圖片 .showImageOnFail(R.mipmap.ic_launcher) // 設置圖片加載或解碼過程當中發生錯誤顯示的圖片 .cacheInMemory(true) // 設置下載的圖片是否緩存在內存中 .cacheOnDisk(true) // 設置下載的圖片是否緩存在SD卡中 .displayer(new RoundedBitmapDisplayer(20)) // 設置成圓角圖片 .build(); // 構建完成 } }