详解Glide最新版V4使用指南

概述

Glide是一个Android的图片加载和缓存库,它主要专注于大量图片的流畅加载,Glide几乎可以胜任任何你需要使用到图片从网络拉取,压缩,显示的场景。

本文主要基于Glide4.0版本介绍其基本使用方法。

1 集成

Github地址: https://github.com/bumptech/glide

app或lib级别的build.gradle文件添加依赖:

repositories {
 mavenCentral()
 maven { url 'https://maven.google.com' }
}

dependencies {
 compile 'com.github.bumptech.glide:glide:4.3.1'
 annotationProcessor 'com.github.bumptech.glide:compiler:4.3.1'
}

Android Studio3.0使用:

dependencies {
 implementation 'com.github.bumptech.glide:glide:4.3.1'
 annotationProcessor 'com.github.bumptech.glide:compiler:4.3.1'
}

使用implementation还是api需要视情况而定,implementation只能用于当前module,如果在库中以这种方式设置依赖,那么在app的module是引用不到的,但是api可以,api相当于compile。

在proguard.pro/proguard.cfg中添加混淆:

-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.module.AppGlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
 **[] $VALUES;
 public *;
}

# for DexGuard only
-keepresourcexmlelements manifest/application/meta-data@value=GlideModule

2 基本用法

大多数情况下加载图片只需要一行代码:

Glide.with(fragment)
 .load(myUrl)
 .into(imageView);

取消加载也很简单:

Glide.with(fragment).clear(imageView);

实际上你并不需要取消加载。。。

因为当你在with方法中传入的Activity或Fragment被销毁的时候,Glide会自动取消加载并且回收所有的加载过程中所使用的资源。

3 注解(V4新特性)和自定义方法

Glide使用了annotation processor来生成API,允许应用修改RequestBuilder、RequestOptions和任意的包含在单一流式API库中的方法。这是V4的特性,运用注解后使用起来更方便:

GlideApp.with(fragment)
 .load(myUrl)
 .placeholder(R.drawable.placeholder)
 .fitCenter()
 .into(imageView);

Glidev4中的Glide.with().load()后没有之前版本的fitCenter和placeholder这样的方法,但是GlideApp有,可以直接在builder中使用。GlideApp可以代替之前版本的Glide开头。

这样做的目的是:

1.对于library项目来讲可以使用自定义方法继承Glide的API
2.对于应用来讲,在继承Glide的API后,可以通过添加自定义方法。

虽然你也可以手动继承RequestOptions,但是显然这样做更加麻烦,也破坏了流式API特性。

3.1 在项目中实现AppGlideModule:

@GlideModule
public class CustomGlideModule extends AppGlideModule {}

这个类实现必须要有@GlideModule注解,如果你添加的方法失效,那就检查下这里。

如果是library就实现LibraryGlideModule,以使用OkHttp为例:

@GlideModule
public final class OkHttpLibraryGlideModule extends LibraryGlideModule {
 @Override
 public void registerComponents(Context context, Registry registry) {
 registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory());
 }
}

OkHttpUrlLoader是Glide的OKHttp扩展库中的类,如果需要使用Glide的实现,可以在依赖中添加:

compile 'com.github.bumptech.glide:okhttp3-integration:4.3.1'

Android Studio 3.0

implementation 'com.github.bumptech.glide:okhttp3-integration:4.3.1'

添加完依赖不需要自己实现OkHttpLibraryGlideModule类,库中已经自带了,会自动使用OKHttp的。

然后编译工程可以发现在build中生成了四个类:

3.2 GlideExtension

为了添加新的方法,修改已有的方法或者添加对其他类型格式的支持,你需要在扩展中使用加了注解的静态方法。

GlideOption用来添加自定义的方法,GlideType用来支持新的格式。

3.2.1 GlideOption

先新建一个CustomGlideExtension类:

@GlideExtension
public class CustomGlideExtension {
 //缩略图的最小尺寸,单位:px
 private static final int MINI_THUMB_SIZE = 100;

 /**
 * 将构造方法设为私有,作为工具类使用
 */
 private CustomGlideExtension() {
 }

 /**
 * 1.自己新增的方法的第一个参数必须是RequestOptions options
 * 2.方法必须是静态的
 * @param options
 */
 @GlideOption
 public static void miniThumb(RequestOptions options) {
 options
 .fitCenter()
 .override(MINI_THUMB_SIZE);
 }
}

编译工程,打开build目录中的GlideOptions,可以看见自动生成了两个方法:

public class GlideOptions extends RequestOptions {

 /**
 * @see CustomGlideExtension#miniThumb(RequestOptions)
 */
 public GlideOptions miniThumb() {
 CustomGlideExtension.miniThumb(this);
 return this;
 }

 /**
 * @see CustomGlideExtension#miniThumb(RequestOptions)
 */
 public static GlideOptions miniThumbOf() {
 return new GlideOptions().miniThumb();
 }
 ...
}

现在可以使用你自定义的方法了:

GlideApp.with(fragment)
 .load(url)
 .miniThumb(thumbnailSize)
 .into(imageView);

3.2.2 GlideType

以添加对GIF格式的支持为例,只是举例,实际上API中已经支持了。

在刚才的CustomGlideExtension类中加上:

@GlideExtension
public class CustomGlideExtension {
 private static final RequestOptions DECODE_TYPE_GIF = GlideOptions.decodeTypeOf(GifDrawable.class).lock();
 @GlideType(GifDrawable.class)
 public static void asGIF(RequestBuilder<GifDrawable> requestBuilder) {
 requestBuilder
 .transition(new DrawableTransitionOptions())
 .apply(DECODE_TYPE_GIF);
 }
}

编译工程,打开build目录中的GlideRequests,可以看见自动生成了一个方法:

public class GlideRequests extends RequestManager {
 /**
 * @see CustomGlideExtension#asGIF(RequestBuilder)
 */
 public GlideRequest<GifDrawable> asGIF() {
 GlideRequest<GifDrawable> requestBuilder = this.as(GifDrawable.class);
 CustomGlideExtension.asGIF(requestBuilder);
 return requestBuilder;
 }
}

现在可以使用你添加的类型了:

GlideApp.with(fragment)
 .asGIF()
 .load(url)
 .into(imageView);

4 占位符

占位符就是请求的图片没加载出来时显示的默认图片。

Glide支持三种不同情况下的占位符:

  1. Placeholder 请求图片加载中
  2. Error 请求图片加载错误
  3. Fallback 请求url/model为空

设置占位符:

GlideApp.with(fragment)
 .load(url)
 .placeholder(R.drawable.placeholder)
 .error(new ColorDrawable(Color.RED))
 .fallback(new ColorDrawable(Color.GREY))
 .into(view);

之后的显示优先级,我画了个流程图。

5 Options

5.1 RequestOptions

Glide中的大多请求参数都可以通过RequestOptions类和apply()方法来设置。

Glide中的请求参数主要有:

  1. Placeholders 占位符
  2. Transformations 变换
  3. Caching Strategies 缓存策略
  4. 组件特定参数:编码质量,解码参数等。

比如,要将图片的显示方式设为CenterCrop,你可以这么做:

import static com.bumptech.glide.request.RequestOptions.centerCropTransform;

Glide.with(fragment)
 .load(url)
 .apply(centerCropTransform(context))
 .into(imageView);

但是其实完全可以在layout文件中设置ImageView为android:scaleType="centerCrop",Glide会自动根据这个属性设置图片的显示方式。

apply方法可以调用多次,但是如果两次apply存在冲突的设置,会以最后一次为准。

5.2 TransitionOptions

TransitionOptions决定图片加载完成如何从占位符图片(或者之前的图片)过渡。

  1. 淡入
  2. 交叉淡入
  3. 不过渡
Glide.with(fragment)
 .load(url)
 .transition(DrawableTransitionOptions.withCrossFade())
 .into(view);

注意

TransitionOptions是和你要加载的资源的类型绑定的,也就是说,如果你请求一张位图(Bitmap),你就需要使用BitmapTransitionOptions,而不是DrawableTransitionOptions。因此,你请求的这张位图,你需要用简单的淡入,而不能用 交叉淡入(DrawableTransitionOptions.withCrossFade())。

如果既不是Bitmap也不是Drawable可以使用GenericTransitionOptions

5.3 RequestBuilder

作用:

  1. 指定加载类型。asBitmap()、asGif()、asDrawable()、asFile()。
  2. 指定要加载url/model。
  3. 指定要加载到那个View。
  4. 指定要应用的RequestOption
  5. 指定要应用的TransitionOption
  6. 指定要加载的缩略图

那么如何得到RequestBuilder呢?

RequestBuilder<Drawable> requestBuilder = Glide.with(fragment);

默认得到一个Drawable RequestBuilder,如果要指定类型为Bitmap,可以这样写:

RequestBuilder<Bitmap> requestBuilder = Glide.with(fragment).asBitmap();

应用RequestOptions

RequestBuilder<Drawable> requestBuilder = Glide.with(fragment);
requestBuilder.apply(requestOptions);
requestBuilder.transition(transitionOptions);

RequestBuilder也可以重复使用:

RequestBuilder<Drawable> requestBuilder =
 Glide.with(fragment)
  .asDrawable()
  .apply(requestOptions);

for (int i = 0; i < numViews; i++) {
 ImageView view = viewGroup.getChildAt(i);
 String url = urls.get(i);
 requestBuilder.load(url).into(view);
}

6 Transformations

Glide会自动读取ImageView的缩放类型,所以一般在layout文件指定scaleType即可。

CenterCrop, CenterInside, CircleCrop, FitCenter, RoundedCorners

Glide支持在java代码中设置这些缩放类型:

  1. CenterCrop 缩放宽和高都到达View的边界,有一个参数在边界上,另一个参数可能在边界上,也可能超过边界
  2. CenterInside 如果宽和高都在View的边界内,那就不缩放,否则缩放宽和高都进入View的边界,有一个参数在边界上,另一个参数可能在边界上,也可能在边界内
  3. CircleCrop 圆形且结合了CenterCrop的特性
  4. FitCenter 缩放宽和高都进入View的边界,有一个参数在边界上,另一个参数可能在边界上,也可能在边界内
  5. RoundedCorners 圆角

有三种用法:

1 使用RequestOptions

RequestOptions options = new RequestOptions();
options.centerCrop();

Glide.with(fragment)
 .load(url)
 .apply(options)
 .into(imageView);

2 使用RequestOptions中的transform方法

Glide.with(fragment)
 .load(url)
 .apply(RequestOptions.fitCenterTransform())
 .into(imageView);

3 V4特性

GlideApp.with(fragment)
 .load(url)
 .fitCenter()
 .into(imageView);

第三种方法最简便,推荐。

多个变换

Glide.with(fragment)
 .load(url)
 .transform(new MultiTransformation(new FitCenter(), new YourCustomTransformation())
 .into(imageView);

7 Transitions(动画)

普通动画

Glide中的过渡动画是指占位符到请求图片或缩略图到完整尺寸请求图片的动画。过渡动画只能针对单一请求,不能跨请求执行。

过渡动画执行时机:

1.图片在磁盘缓存
2.图片在本地
3.图片在远程

如果图片在内存缓存上是不会执行过渡动画的。如果需要在内存缓存上加载动画,可以这样:

GlideApp.with(this).load(R.drawable.img_default).listener(new RequestListener(){

 @Override
 public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
 return false;
 }

 @Override
 public boolean onResourceReady(Object resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) {
 if (dataSource == DataSource.MEMORY_CACHE) {
  //当图片位于内存缓存时,glide默认不会加载动画
  imageView.startAnimation(AnimationUtils.loadAnimation(getActivity(), R.anim.fade_in));
 }
 return false;
 }
}).fitCenter().transition(GenericTransitionOptions.with(R.anim.fade_in)).into(imageView);

通常的用法如下:

Glide.with(fragment)
 .load(url)
 .transition(DrawableTransitionOptions.withCrossFade())
 .into(view);

TransitionOptions的介绍:TransitionOptions。有三种TransitionOptions:

  1. GenericTransitionOptions 通用型
  2. DrawableTransitionOptions
  3. BitmapTransitionOptions

如果要使用自定义的动画,可以使用GenericTransitionOptions.with(int viewAnimationId)或者BitmapTransitionOptions.withCrossFade(int animationId, int duration)或者DrawableTransitionOptions.withCrossFade(int animationId, int duration)。

出于性能考虑,最好不要在ListView,GridView,RecycleView中使用过渡动画,使用TransitionOptions.dontTransition()可以不加载动画,也可以使用dontAnimate不加载动画

GlideApp.with(mContext)
 .load(imgUrl)
 .placeholder(R.drawable.img_default)
 .dontAnimate()
 .into(holder.imageview);

自定义过渡动画

1.实现TransitionFactory
2.重写build()

可以控制图片在内存缓存上是否执行动画。

具体写法参考DrawableCrossFadeFactory,然后调用TransitionOptions的with(TransitionFactory transitionFactory)加载。

8 基本配置

8.1 配置内存缓存

Glide会自动合理分配内存缓存,但是也可以自己手动分配。

方法一

通过MemorySizeCalculator设置

@GlideModule
public class CustomGlideModule extends AppGlideModule {
 @Override
 public void applyOptions(Context context, GlideBuilder builder) {
 MemorySizeCalculator calculator = new MemorySizeCalculator.Builder(context)
  .setMemoryCacheScreens(2)
  .build();
 builder.setMemoryCache(new LruResourceCache(calculator.getMemoryCacheSize()));
 }
}

setMemoryCacheScreens设置MemoryCache应该能够容纳的像素值的设备屏幕数,说白了就是缓存多少屏图片,默认值是2。

方法二

@GlideModule
public class CustomGlideModule extends AppGlideModule {
 @Override
 public void applyOptions(Context context, GlideBuilder builder) {
 int memoryCacheSizeBytes = 1024 * 1024 * 20; // 20mb
 builder.setMemoryCache(new LruResourceCache(memoryCacheSizeBytes));
 }
}

方法三

@GlideModule
public class YourAppGlideModule extends AppGlideModule {
 @Override
 public void applyOptions(Context context, GlideBuilder builder) {
 builder.setMemoryCache(new CustomGlideMemoryCache());
 }
}

自己实现MemoryCache接口。

清理内存缓存,在主线程调用:

GlideApp.get(context).clearMemory();

在使用的时候,可以跳过内存缓存:

 GlideApp.with(getActivity())
  .load(url)
  .skipMemoryCache(true)
  .dontAnimate()
  .centerCrop()
  .into(imageView);

8.2 磁盘缓存

Glide使用DiskLruCacheWrapper作为默认的磁盘缓存,默认大小是250M,缓存文件放在APP的缓存文件夹下。

@GlideModule
public class CustomGlideModule extends AppGlideModule {
 @Override
 public void applyOptions(Context context, GlideBuilder builder) {
 int diskCacheSizeBytes = 1024 * 1024 * 100; // 100 MB
 builder.setDiskCache(new InternalCacheDiskCacheFactory(context, diskCacheSizeBytes));
// builder.setDiskCache(new InternalCacheDiskCacheFactory(context, "cacheFolderName", diskCacheSizeBytes));
// builder.setDiskCache(new ExternalCacheDiskCacheFactory(context));
 }
}

用法如上,可以指定缓存在内部存储或外部存储,也可以指定缓存大小和文件夹。

自定义磁盘缓存

@GlideModule
public class CustomGlideModule extends AppGlideModule {
 @Override
 public void applyOptions(Context context, GlideBuilder builder) {
 builder.setDiskCache(new DiskCache.Factory() {
 @Override
 public DiskCache build() {
  return new YourAppCustomDiskCache();
 }
 });
 }
}

自己实现DiskCache接口。

清理磁盘缓存,在子线程调用:

GlideApp.get(context).clearDiskCache();

加载图片时设置磁盘缓存策略:

GlideApp.with(getActivity())
  .load(url)
  .diskCacheStrategy(DiskCacheStrategy.ALL)
  .dontAnimate()
  .centerCrop()
  .into(imageView);

默认的策略是DiskCacheStrategy.AUTOMATIC

DiskCacheStrategy有五个常量:

  1. DiskCacheStrategy.ALL 使用DATA和RESOURCE缓存远程数据,仅使用RESOURCE来缓存本地数据。
  2. DiskCacheStrategy.NONE 不使用磁盘缓存
  3. DiskCacheStrategy.DATA 在资源解码前就将原始数据写入磁盘缓存
  4. DiskCacheStrategy.RESOURCE 在资源解码后将数据写入磁盘缓存,即经过缩放等转换后的图片资源。
  5. DiskCacheStrategy.AUTOMATIC 根据原始图片数据和资源编码策略来自动选择磁盘缓存策略。

8.3 禁止解析Manifest文件

主要针对V3升级到v4的用户,可以提升初始化速度,避免一些潜在错误。

@GlideModule
public class CustomGlideModule extends AppGlideModule {
 @Override
 public boolean isManifestParsingEnabled() {
 return false;
 }
}

8.4 View尺寸

Glide对ImageView的width和height属性是这样解析的:

  1. 如果width和height都大于0,则使用layout中的尺寸。
  2. 如果width和height都是WRAP_CONTENT,则使用屏幕尺寸。
  3. 如果width和height中至少有一个值<=0并且不是WRAP_CONTENT,那么就会在布局的时候添加一个OnPreDrawListener监听ImageView的尺寸

Glide对WRAP_CONTENT的支持并不好,所以尽量不要用。

那么如何在运行修改ImageView尺寸呢?

方法一 继承ImageViewTarget

我这里指定的View的类型是ImageView,资源类型是Bitmap,可根据需要修改,onResourceReady(Bitmap bitmap, Transition<? super Bitmap> transition)方法中可以通过bitmap获取图片的尺寸。

public class CustomImageViewTarget extends ImageViewTarget<Bitmap> {

 private int width, height;

 public CustomImageViewTarget(ImageView view) {
  super(view);
 }

 public CustomImageViewTarget(ImageView view, int width, int height) {
  super(view);
  this.width = width;
  this.height = height;
 }

 @Override
 public void onResourceReady(Bitmap bitmap, Transition<? super Bitmap> transition) {
  super.onResourceReady(bitmap,transition);
 }

 @Override
 protected void setResource(@Nullable Bitmap resource) {
  view.setImageBitmap(resource);
 }

 @Override
 public void getSize(SizeReadyCallback cb) {
  if (width > 0 && height > 0) {
  cb.onSizeReady(width, height);
  return;
  }
  super.getSize(cb);
 }
 }

使用:

GlideApp.with(context)
 .asBitmap()
 .load(url)
 .dontAnimate()
 .placeholder(R.drawable.img_default)
 .into(new CustomImageViewTarget(imageview, 300, 300));

方法二 使用override()

GlideApp.with(mContext)
 .load(url)
 .override(width,height)
 .into(view);

获取bitmap

如果只想用Glide解析url获取一个bitmap,然后自己对其进行处理,可以使用SimpleTarget<Z>,

/**
 * Constructor for the target that uses {@link Target#SIZE_ORIGINAL} as the target width and
 * height.
 */
 public SimpleTarget() {
 this(SIZE_ORIGINAL, SIZE_ORIGINAL);
 }

 /**
 * Constructor for the target that takes the desired dimensions of the decoded and/or transformed
 * resource.
 *
 * @param width The width in pixels of the desired resource.
 * @param height The height in pixels of the desired resource.
 */
 public SimpleTarget(int width, int height) {
 this.width = width;
 this.height = height;
 }

SimpleTarget也可以指定宽和高,用法示例:

Glide.with(itemView.getContext()).asBitmap().load(url).into(new SimpleTarget<Bitmap>() {
 @Override
 public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) {

 }
});

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

您可能感兴趣的文章:

  • Android基于Glide v4.x的图片加载进度监听
(0)

相关推荐

  • Android基于Glide v4.x的图片加载进度监听

    Glide是一款优秀的图片加载框架,简单的配置便可以使用起来,为开发者省下了很多的功夫.不过,它没有提供其加载图片进度的api,对于这样的需求,实现起来还真颇费一番周折. 尝试 遇到这个需求,第一反应是网上肯定有人实现过,不妨借鉴一下别人的经验. Glide加载图片实现进度条效果 可惜,这个实现是基于3.7版本的,4.0版本以上的glide改动比较大,using函数已经被移除了 using() The using() API was removed in Glide 4 to encourage

  • 详解Glide最新版V4使用指南

    概述 Glide是一个Android的图片加载和缓存库,它主要专注于大量图片的流畅加载,Glide几乎可以胜任任何你需要使用到图片从网络拉取,压缩,显示的场景. 本文主要基于Glide4.0版本介绍其基本使用方法. 1 集成 Github地址: https://github.com/bumptech/glide app或lib级别的build.gradle文件添加依赖: repositories { mavenCentral() maven { url 'https://maven.google

  • 详解Mybatis框架SQL防注入指南

    前言 SQL注入漏洞作为WEB安全的最常见的漏洞之一,在java中随着预编译与各种ORM框架的使用,注入问题也越来越少.新手代码审计者往往对Java Web应用的多个框架组合而心生畏惧,不知如何下手,希望通过Mybatis框架使用不当导致的SQL注入问题为例,能够抛砖引玉给新手一些思路. 一.Mybatis的SQL注入 Mybatis的SQL语句可以基于注解的方式写在类方法上面,更多的是以xml的方式写到xml文件.Mybatis中SQL语句需要我们自己手动编写或者用generator自动生成.

  • 详解升级react-router 4 踩坑指南

    一.前言 上午把近日用React做的一个新闻项目所依赖的包升级到了最新的版本,其中从react-router(2.8.1)升级到react-router(4.1.2)中出现了很多问题, 故总结一下在升级过程中遇到的问题. 二.react-router,V4版本修改内容 1. 所有组件更改为从react-router-dom导入 之前的所有路由组件均是从react-router中导入,在我之前的项目中,导入相关组件如下: //v2 import {Router,Route,hashHistory}

  • 详解pytorch 0.4.0迁移指南

    总说 由于pytorch 0.4版本更新实在太大了, 以前版本的代码必须有一定程度的更新. 主要的更新在于 Variable和Tensor的合并., 当然还有Windows的支持, 其他一些就是支持scalar tensor以及修复bug和提升性能吧. Variable和Tensor的合并导致以前的代码会出错, 所以需要迁移, 其实迁移代价并不大. Tensor和Variable的合并 说是合并, 其实是按照以前(0.1-0.3版本)的观点是: Tensor现在默认requires_grad=F

  • 详解Vue2.5+迁移至Typescript指南

    为什么要迁移至Typescript Javascript本身是动态弱类型的语言,这样的特点导致了Javascript代码中充斥着很多Uncaught TypeError的报错,给开发调试和线上代码稳定都带来了不小的负面影响. 而Typescript提供了静态类型检查,使很多类型错误在编写时就已经发现,不会带到测试阶段. 同时,Javascript不定义model就可以使用一个对象,有人喜欢这样的灵活性,的确这样的语法在model不复杂的时候可以快速的开发出需要的功能,但一旦model庞大,找一个

  • 详解Pycharm与anaconda安装配置指南

    关于文件下载 官网都有提供最新版本的推荐自行下载,如果不介意旧版本的,可以留言我可以分享我是用的版本~ Anaconda安装 打开下载的.exe文件 依次点击:next -> I agree -> All User 选择安装软件的目录,推荐D盘 因为我的C盘比较满,安装在D盘也方便Pycharm的安装和Python文件的存储.(当然如果你的C盘剩余内存较多,就当我的理由是胡扯吧) 当然,不管你选择安装在哪里,确保自己后期找得到安装位置!!!(这点很重要) 路径中不可以出现中文会导致报错!!!

  • 详解React-Router中Url参数改变页面不刷新的解决办法

    问题 今天在写页面的时候发现一个问题,就是在React Router中使用了Url传参的功能,像这样: export class MainRouter extends React.Component { render() { return ( <BrowserRouter> <Switch> ... <Route exact path={'/channel/:channelId'} component={ChannelPerPage}/> ... </Switch

  • 详解阿里Node.js技术文档之process模块学习指南

    模块概览 process是node的全局模块,作用比较直观.可以通过它来获得node进程相关的信息,比如运行node程序时的命令行参数.或者设置进程相关信息,比如设置环境变量. 环境变量:process.env 使用频率很高,node服务运行时,时常会判断当前服务运行的环境,如下所示 if(process.env.NODE_ENV === 'production'){ console.log('生产环境'); }else{ console.log('非生产环境'); } 运行命令 NODE_EN

  • 详解Matisse与Glide--java.lang.NoSuchMethodError:com.bumptech.glide.RequestManager.load

    问题描述 在使用 Matisse 与 glide 4.0.0 以及 4.0.0 之后的版本过程中,发现通过 Matisse 的 wiki 代码调用选取图片的方式后,会出现本文标题的错误 1.以下为 wiki 调用代码: Matisse.from(MainActivity.this) .choose(MimeType.allOf()) .countable(true) .maxSelectable(9) .addFilter(new GifSizeFilter(320, 320, 5 * Filt

  • JS表格组件神器bootstrap table使用指南详解

    bootstrap table详细使用指南分享,供大家参考,具体内容如下 1.bootstrap-table简介 1.1.bootstrap table简介及特征: Bootstrap table是国人开发的一款基于 Bootstrap 的 jQuery 表格插件,通过简单的设置,就可以拥有强大的单选.多选.排序.分页,以及编辑.导出.过滤(扩展)等等的功能.目前在github上已经有2600多个Star,可见其受欢迎程度.其官方网站地址为:http://bootstrap-table.wenz

随机推荐