GlideDemo【Glide3.7.0版本的简单使用以及圆角功能】
版权声明:本文为HaiyuKing原创文章,转载请注明出处!
前言
本Demo主要记录Glide3.7.0版本的简单运用和实现圆角方案。
效果图
代码分析
Glide的centerCrop()和fitCenter()的使用效果:
Glide 提供了两个类似的方法 CenterCrop() 和 FitCenter(),CenterCrop() 方法是将图片按比例缩放到足矣填充 ImageView 的尺寸,但是图片可能会显示不完整;而 FitCenter() 则是图片缩放到小于等于 ImageView 的尺寸,这样图片是显示完整了,但是 ImageView 就可能不会填满了。
不论在布局文件中如何设置ImageView控件的android:scaleType值,Glide只要执行了CenterCrop() 或者FitCenter(),那么就会以Glide的设置为准。
使用步骤
一、项目组织结构图
注意事项:
1、 导入类文件后需要change包名以及重新import R文件路径
2、 Values目录下的文件(strings.xml、dimens.xml、colors.xml等),如果项目中存在,则复制里面的内容,不要整个覆盖
二、导入步骤
(1)在APP的build.gradle中添加Glide依赖
apply plugin: 'com.android.application' android {
compileSdkVersion 27
defaultConfig {
applicationId "com.why.project.glidedemo"
minSdkVersion 16
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
} dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' //glide引用(虽然多个库中引用属于重复引用,但是只有当前库中引用,当前库才可以使用,所以还是要引用的)
//(对于第三方库引用的glide版本,尽量不要修改)
compile 'com.github.bumptech.glide:glide:3.7.0'
compile 'com.android.support:support-v4:27.1.1'
//集成 OkHttp 作为 Glide 的网络库
//https://www.jianshu.com/p/7ce7b02988a4
//https://stackoverflow.com/questions/37129757/glide-with-okhttp3-integration-java-lang-noclassdeffounderror
compile 'com.github.bumptech.glide:okhttp-integration:1.4.0@aar'
compile 'com.squareup.okhttp:okhttp:2.7.5'
//注意,okHttp和okHttps不一样的配置
// compile 'com.github.bumptech.glide:okhttp3-integration:1.4.0@aar'
// compile 'com.squareup.okhttp3:okhttp:3.2.0'
}
(2)将GlideConfigModule.java复制到项目中
package com.why.project.glidedemo.glide; import android.content.Context; import com.bumptech.glide.Glide;
import com.bumptech.glide.GlideBuilder;
import com.bumptech.glide.load.DecodeFormat;
import com.bumptech.glide.load.engine.bitmap_recycle.LruBitmapPool;
import com.bumptech.glide.load.engine.cache.LruResourceCache;
import com.bumptech.glide.load.engine.cache.MemorySizeCalculator;
import com.bumptech.glide.module.GlideModule; /**
* Used 自定义Glide配置
*/
public class GlideConfigModule implements GlideModule{
int diskSize = 1024 * 1024 * 100;
int memorySize = (int) (Runtime.getRuntime().maxMemory()) / 8; // 取1/8最大内存作为最大缓存 /* (non-Javadoc)
* @see com.bumptech.glide.module.GlideModule#applyOptions(android.content.Context, com.bumptech.glide.GlideBuilder)
*/
@Override
public void applyOptions(Context context, GlideBuilder builder) {
// 定义缓存大小和位置
//builder.setDiskCache(new InternalCacheDiskCacheFactory(context, diskSize)); //内存中
//builder.setDiskCache(new ExternalCacheDiskCacheFactory(context, "cache", diskSize)); //sd卡中 // 默认内存和图片池大小
MemorySizeCalculator calculator = new MemorySizeCalculator(context);
int defaultMemoryCacheSize = calculator.getMemoryCacheSize(); // 默认内存大小
int defaultBitmapPoolSize = calculator.getBitmapPoolSize(); // 默认图片池大小
builder.setMemoryCache(new LruResourceCache(defaultMemoryCacheSize)); // 该两句无需设置,是默认的
builder.setBitmapPool(new LruBitmapPool(defaultBitmapPoolSize)); // 自定义内存和图片池大小
/*builder.setMemoryCache(new LruResourceCache(memorySize));
builder.setBitmapPool(new LruBitmapPool(memorySize));*/ // 定义图片格式
//builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);//与picasso相同
builder.setDecodeFormat(DecodeFormat.PREFER_RGB_565); // 默认
} /* (non-Javadoc)
* @see com.bumptech.glide.module.GlideModule#registerComponents(android.content.Context, com.bumptech.glide.Glide)
*/
@Override
public void registerComponents(Context arg0, Glide arg1) {
// TODO Auto-generated method stub } }
(3)在AndroidManifest.xml中添加以下代码【注意GlideConfigModule的路径】【根据实际情况添加权限,有些权限需要申请运行时权限】
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.why.project.glidedemo"> <!-- Glide -->
<!--如果你计划从 URL 或一个网络连接中加载数据,你需要添加 INTERNET 和 ACCESS_NETWORK_STATE 权限-->
<uses-permission android:name="android.permission.INTERNET"/>
<!--如果你正在从 URL 加载图片,Glide 可以自动帮助你处理片状网络连接:它可以监听用户的连接状态并在用户重新连接到网络时重启之前失败的请求。
如果 Glide 检测到你的应用拥有 ACCESS_NETWORK_STATE 权限,Glide 将自动监听连接状态而不需要额外的改动。-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!--要从本地文件夹或 DCIM 或图库中加载图片,你将需要添加 READ_EXTERNAL_STORAGE 权限-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!--而如果要将 Glide 的缓存存储到公有 SD 卡上,你还需要添加 WRITE_EXTERNAL_STORAGE 权限-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity> <!-- *************************自定义Glide配置文件************************* -->
<meta-data
android:name="com.why.project.glidedemo.glide.GlideConfigModule"
android:value="GlideModule" />
</application> </manifest>
(4)将transformations包(实现圆角方案)复制到项目中【里面一共是四种圆角方案,实际项目中选择其中一个即可】【根据需要复制到项目中】
三、使用方法
(1)布局文件
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f4f4f4">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="10dp"> <TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Glide的基础使用(使用fitCenter配合wrap_content显示原图大小):"/>
<!-- 图片使用src和android:scaleType="centerCrop"、android:adjustViewBounds="true",可以实现宽高等边 -->
<ImageView
android:id="@+id/img_base"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:contentDescription="@string/app_name"
android:scaleType="fitCenter"
android:src="@drawable/img_error"/> <TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Glide的重新改变图片大小(使用override):"/>
<!-- 图片使用src和android:scaleType="centerCrop"、android:adjustViewBounds="true",可以实现宽高等边 -->
<ImageView
android:id="@+id/img_override"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:contentDescription="@string/app_name"
android:scaleType="fitCenter"
android:src="@drawable/img_error"/> <TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Glide的圆角效果(使用MyRoundCornersTransformation,fitCenter()和centerCrop()方法会失效,自己设置的android:scaleType也会失效)"/>
<!-- 图片使用src和android:scaleType="centerCrop"、android:adjustViewBounds="true",可以实现宽高等边 -->
<ImageView
android:id="@+id/img_myRound"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:contentDescription="@string/app_name"
android:scaleType="fitCenter"
android:src="@drawable/img_error"/> <TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Glide的圆角效果(使用RoundCornersTransformation,fitCenter()和centerCrop()方法会失效,自己设置的android:scaleType也会失效)"/>
<!-- 图片使用src和android:scaleType="centerCrop"、android:adjustViewBounds="true",可以实现宽高等边 -->
<ImageView
android:id="@+id/img_round"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:contentDescription="@string/app_name"
android:scaleType="fitCenter"
android:src="@drawable/img_error"/> <TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Glide的圆角效果(使用GlideCircleTransform,fitCenter()和centerCrop()方法会失效,自己设置的android:scaleType也会失效)"/>
<!-- 图片使用src和android:scaleType="centerCrop"、android:adjustViewBounds="true",可以实现宽高等边 -->
<ImageView
android:id="@+id/img_circle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:contentDescription="@string/app_name"
android:scaleType="fitCenter"
android:src="@drawable/img_error"/> <TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Glide的圆角效果(使用BitmapCircleUtil)"/>
<!-- 图片使用src和android:scaleType="centerCrop"、android:adjustViewBounds="true",可以实现宽高等边 -->
<ImageView
android:id="@+id/img_circleUtil"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:contentDescription="@string/app_name"
android:scaleType="fitCenter"
android:src="@drawable/img_error"/> </LinearLayout> </ScrollView>
(2)代码中写法
package com.why.project.glidedemo; import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;
import android.view.WindowManager;
import android.widget.ImageView; import com.bumptech.glide.Glide;
import com.bumptech.glide.Priority;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.target.BitmapImageViewTarget;
import com.why.project.glidedemo.glide.transformations.BitmapCircleUtil;
import com.why.project.glidedemo.glide.transformations.GlideCircleTransform;
import com.why.project.glidedemo.glide.transformations.MyRoundCornersTransformation;
import com.why.project.glidedemo.glide.transformations.RoundCornersTransformation; public class MainActivity extends AppCompatActivity { private Context mContext; private ImageView mImgBase;
private ImageView mImgOverride;
private ImageView mImgMyRound;
private ImageView mImgRound;
private ImageView mImgCircle;
private ImageView mImgCircleUtil; private String imgUrl = "https://pic.cnblogs.com/avatar/93830/20170607145247.png"; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); mContext = this; initViews();
initDatas();
} private void initViews() {
mImgBase = findViewById(R.id.img_base);
mImgOverride = findViewById(R.id.img_override);
mImgMyRound = findViewById(R.id.img_myRound);
mImgRound = findViewById(R.id.img_round);
mImgCircle = findViewById(R.id.img_circle);
mImgCircleUtil = findViewById(R.id.img_circleUtil);
} private void initDatas() { glideBase();
glideOverride();
glideRound();
glideRound2();
glideRound3();
glideRound4();
} //Glide的基础使用
private void glideBase() {
Glide.with(mContext)
.load(imgUrl)
//设置等待时的图片
.placeholder(R.drawable.img_loading)
//设置加载失败后的图片显示
.error(R.drawable.img_error)
.fitCenter()
//默认淡入淡出动画
.crossFade()
//缓存策略,跳过内存缓存【此处应该设置为false,否则列表刷新时会闪一下】
.skipMemoryCache(false)
//缓存策略,硬盘缓存-仅仅缓存最终的图像,即降低分辨率后的(或者是转换后的)
.diskCacheStrategy(DiskCacheStrategy.RESULT)
//设置图片加载的优先级
.priority(Priority.HIGH)
.into(mImgBase);
} //Glide重新改变图片大小
private void glideOverride() {
setColumnNumber(mContext,3);//计算宽度和高度值(1:1.5或者1:1) Glide.with(mContext)
.load(imgUrl)
//设置等待时的图片
.placeholder(R.drawable.img_loading)
//设置加载失败后的图片显示
.error(R.drawable.img_error)
.centerCrop()
.override(imageWidthSize,imageHeightSize)
//默认淡入淡出动画
.crossFade()
//缓存策略,跳过内存缓存【此处应该设置为false,否则列表刷新时会闪一下】
.skipMemoryCache(false)
//缓存策略,硬盘缓存-仅仅缓存最终的图像,即降低分辨率后的(或者是转换后的)
.diskCacheStrategy(DiskCacheStrategy.RESULT)
//设置图片加载的优先级
.priority(Priority.HIGH)
.into(mImgOverride);
} //用于计算图片的宽高值
private int imageWidthSize;
private int imageHeightSize; private void setColumnNumber(Context context, int columnNumber) {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics metrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(metrics);
int widthPixels = metrics.widthPixels;
imageWidthSize = widthPixels / columnNumber;
imageHeightSize = (int)(imageWidthSize * 1.5);//长方形样式,二选一
//imageHeightSize = imageWidthSize;//正方形样式,二选一
} //Glide的圆角效果
private void glideRound() {
//该方案不合适,因为图片尺寸有大有小
Glide.with(mContext)
.load(imgUrl)
//设置等待时的图片
.placeholder(R.drawable.img_loading)
//设置加载失败后的图片显示
.error(R.drawable.img_error)
.centerCrop()
//默认淡入淡出动画
.crossFade()
//缓存策略,跳过内存缓存【此处应该设置为false,否则列表刷新时会闪一下】
.skipMemoryCache(false)
//缓存策略,硬盘缓存-仅仅缓存最终的图像,即降低分辨率后的(或者是转换后的)
.diskCacheStrategy(DiskCacheStrategy.RESULT)
//设置图片加载的优先级
.priority(Priority.HIGH)
.transform(new MyRoundCornersTransformation(mContext,dip2px(mContext,8),
MyRoundCornersTransformation.CornerType.TOP))
.into(mImgMyRound);
} private void glideRound2() {
Glide.with(mContext)
.load(imgUrl)
//设置等待时的图片
.placeholder(R.drawable.img_loading)
//设置加载失败后的图片显示
.error(R.drawable.img_error)
.centerCrop()
//默认淡入淡出动画
.crossFade()
//缓存策略,跳过内存缓存【此处应该设置为false,否则列表刷新时会闪一下】
.skipMemoryCache(false)
//缓存策略,硬盘缓存-仅仅缓存最终的图像,即降低分辨率后的(或者是转换后的)
.diskCacheStrategy(DiskCacheStrategy.RESULT)
//设置图片加载的优先级
.priority(Priority.HIGH)
.bitmapTransform(new RoundCornersTransformation(mContext,dip2px(mContext,8),
RoundCornersTransformation.CornerType.TOP))
.into(mImgRound);
} private void glideRound3() {
Glide.with(mContext)
.load(imgUrl)
//设置等待时的图片
.placeholder(R.drawable.img_loading)
//设置加载失败后的图片显示
.error(R.drawable.img_error)
.centerCrop()
//默认淡入淡出动画
.crossFade()
//缓存策略,跳过内存缓存【此处应该设置为false,否则列表刷新时会闪一下】
.skipMemoryCache(false)
//缓存策略,硬盘缓存-仅仅缓存最终的图像,即降低分辨率后的(或者是转换后的)
.diskCacheStrategy(DiskCacheStrategy.RESULT)
//设置图片加载的优先级
.priority(Priority.HIGH)
.transform(new GlideCircleTransform(mContext))
.into(mImgCircle);
} private void glideRound4() {
Glide.with(mContext)
.load(imgUrl)
.asBitmap()
//设置等待时的图片
.placeholder(R.drawable.img_loading)
//设置加载失败后的图片显示
.error(R.drawable.img_error)
.fitCenter()
//缓存策略,跳过内存缓存【此处应该设置为false,否则列表刷新时会闪一下】
.skipMemoryCache(false)
//缓存策略,硬盘缓存-仅仅缓存最终的图像,即降低分辨率后的(或者是转换后的)【设置为ALL,因为打开设置对话框界面的时候还需要展现缩略图】
.diskCacheStrategy(DiskCacheStrategy.ALL)
//设置图片加载的优先级
.priority(Priority.HIGH)
.into(new BitmapImageViewTarget(mImgCircleUtil){
@Override
protected void setResource(Bitmap resource) {
super.setResource(resource);
Bitmap result = new BitmapCircleUtil(dip2px(mContext,8),
BitmapCircleUtil.CornerType.TOP).circleCrop(resource);
mImgCircleUtil.setImageBitmap(result);
}
});
} /**
* dp转px
* 16dp - 48px
* 17dp - 51px*/
public static int dip2px(Context context, float dpValue) {
float scale = context.getResources().getDisplayMetrics().density;
return (int)((dpValue * scale) + 0.5f);
}
}
混淆配置
#====Glide====
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
#-keepresourcexmlelements manifest/application/meta-data@value=GlideModule #====glide-okhttp-integration-1.4.0.jar====
#-libraryjars libs/glide-okhttp-integration-1.4.0.jar
-dontwarn com.bumptech.glide.integration.okhttp.**
-keep class com.bumptech.glide.integration.okhttp.**
参考资料
Glide with okhttp3 integration java.lang.NoClassDefFoundError
Android 关于Glide的拓展(高斯模糊、加载监听、圆角图片)
Android一些容易被忽略的类-RoundedBitmapDrawable
Glide的一些用法(一)(写了一下午,其实几乎涵盖完了,欢迎收藏)
Android Glide加载图片时转换为圆形、圆角、毛玻璃等图片效果
项目demo下载地址
https://github.com/haiyuKing/GlideDemo
GlideDemo【Glide3.7.0版本的简单使用以及圆角功能】的更多相关文章
- GlideNewDemo【Glide4.7.1版本的简单使用以及圆角功能】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 简单记录下Glide4.7.1版本的使用和实现圆角方案. 注意:关于详细使用请仔细阅读<官方指南>. 效果图 使用步骤 ...
- webpack 4.0 版本的简单使用
webpack 4.0 学习指南 最近前端又要变天了,vue作者推出了vue-cli 3版本,并且里面使用了webpack 4. 但是webpack 3 和webpack 4 二者的使用方式完全不一样 ...
- 【转】cocos2d-x 2.0版本 自适应屏幕分辨率
http://codingnow.cn/cocos2d-x/975.html 我使用的版本是cocos2d-2.0-x-2.0.4,cocos2dx-2.0版本对多分辨率适配提供了很好的支持,使用起来 ...
- 【AngularJS】 2.0 版本发布
[AngularJS] 2.0 版本发布 w5cValidator[AngularJS] 2.0 版本发布 w5cValidator 插件基于angular原有的表单验证,在原有的基础上扩展了一些 ...
- w5cValidator【AngularJS】 2.0 版本发布
w5cValidator 插件基于angular原有的表单验证,在原有的基础上扩展了一些错误提示的功能,让大家不用在每个表单上写一些提示信息的模板,专心的去实现业务逻辑. 代码地址:https://g ...
- LitepalNewDemo【开源数据库ORM框架-LitePal2.0.0版本的使用】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 本Demo使用的是LitePal2.0.0版本,对于旧项目如何升级到2.0.0版本,请阅读<赶快使用LitePal 2.0版本 ...
- .NET Core 2.0版本预计于2017年春季发布
英文原文: NET Core 2.0 Planned for Spring 2017 微软项目经理 Immo Landwerth 公布了即将推出的 .NET Core 2.0 版本的细节,该版本预计于 ...
- Dapr v1.9.0 版本已发布
Dapr是一套开源.可移植的事件驱动型运行时,允许开发人员轻松立足云端与边缘位置运行弹性.微服务.无状态以及有状态等应用程序类型.Dapr能够确保开发人员专注于编写业务逻辑,而不必分神于解决分布式系统 ...
- geotrellis使用(二十)geotrellis1.0版本新功能及变化介绍
目录 前言 变化情况介绍 总结 一.前言 之前版本是0.9或者0.10.1.0.10.2,最近发现更新成为1.0.0-2077839.1.0应该也能称之为正式版了吧.发现其中有很多变化, ...
随机推荐
- yum 出现错误ImportError: No module named urlgrabber.grabber
yum 出现错误: root@iZ23t4pnz63Z ~]# yum update Loaded plugins: fastestmirror Loading mirror speeds from ...
- Java 读书笔记 (四) 常量
常量在程序运行时不能被修改. 在Java中使用final 关键字来修饰常量 ,声明方式和变量类似: final double PI=3.1415927 常量名也可以用小写,但为了便于识别,通常使用大写 ...
- Java单元测试初体验(JUnit4)
什么是单元测试 我们在编写大型程序的时候,需要写成千上万个方法或函数,这些函数的功能可能很强大,但我们在程序中只用到该函数的一小部分功能,并且经过调试可以确定,这一小部分功能是正确的.但是,我们同时应 ...
- [Usaco2015 Jan]Grass Cownoisseur 图论 tarjan spfa
先缩点,对于缩点后的DAG,正反跑spfa,枚举每条边进行翻转即可 #include<cstdio> #include<cstring> #include<iostrea ...
- Spring事务管理----事物回滚
Spring的事务管理默认只对未检查异常(java.lang.RuntimeException及其子类)进行回滚,如果一个方法抛出Checked异常,Spring事务管理默认不进行回滚. 改变默认方式 ...
- Github泄露扫描系统
Github leaked patrol Github leaked patrol为一款github泄露巡航工具: 提供了WEB管理端,后台数据库支持SQLITE3.MYSQL和POSTGRES 双引 ...
- Python + Appium 【已解决】driver(session)在多个class之间复用,执行完一个类的用例,再次执行下个类的用例时不需要初始化
实现效果:打开App进行自动化测试,只需打开APP一次,按先后顺序执行n个py文件中的相应操作,实现自动化测试. 示例:如截图示例,一个App,根据此APP内不同的模块,写成了不同的py文件, 预期结 ...
- MYSQL—— char 与 varchar的区别!
一.char 和 varchar 的区别: 1)取值范围: char:取值范围:0~255 varchar:取值范围:0~65535 2)空间占用与速度: char: 定长字符串,占用空间大,速度快, ...
- Android 两种方式实现类似水波扩散效果
原文链接 https://mp.weixin.qq.com/s/M19tp_ShOO6esKdozi7Nlg 两种方式实现类似水波扩散效果,先上图为敬 自定义view实现 动画实现 自定义view实现 ...
- OSI七层协议与TCP连接
概述 为了追求效率,我们写代码,不可能去关注底层知识,但往往到出了问题,或者性能调优.我们就会速手无策,仔细为自己查缺补漏,总结知识点. 网络协议 互联网的本质就是一系列的网络协议,让不同计算机能够互 ...