作者:新小梦
链接:https://juejin.im/post/6854573221312725000
【Android进阶小刘】是我的头条号,里面会不定期更新一些Android进阶学习视频,感兴趣可以关注一下!
一年前写ConstraintLayout,看完一篇真的就够了么? 文章的时候说过,任何技术都会有时限性,只有不断的学习,不断的更新自我,才不会outer。 有朋友也留言,希望更新…那就有本文了。
目前2.0只是新增了一些新功能和新玩法,对1.x版本无取代之意,所以1.x版本还是得学习的。好文推荐 2.0版本新增的内容在实践开发也是非常实用的,建议可以上车了。
「由于无知与惰性,让我们感觉摸到了技术的天花板」
「对你有用,帮忙点赞~」
基于本文发表,ConstraintLayout版本已经更新到2.0.0-beta8,所以添加依赖的姿势:
AndroidX:
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta8'
支持库:
implementation 'com.android.support.constraint:constraint-layout:2.0.0-beta8'
版本说明:
alpha:内部测试版,bug多多;
beta:公开测试版本,bug少点,支持尝鲜;
rc:候选版本,功能不增,和发布版本一致,修修小bug;
stable:稳定版本,你尽管用,bug能找到是福气。
正常情况下,列表显示一般采用ListView或者RecyclerView来实现,但其子Item布局是非常呆板的。想象一下,如果一部作品的详情页结束打上一堆标签,样式如下,该怎么实现?
这种布局采用Flow来实现特别的简单和方便,而且通过flow_wrapMode属性可以设置不同对齐方式。
下面布局代码简单示例:Flow布局通过constraint_referenced_ids属性将要约束的View的id进行关联,这里简单关联A到G的TextView,由于TextView没有设置约束条件,所以Android Studio 4.0 会报红,给ConstraintLayout布局添加tools:ignore="MissingConstraints"忽略报红提示。
Flow布局的flow_horizontalGap属性表示水平之间两个View的水平间隔,flow_verticalGap则是垂直方向间隔。
flow_wrapMode属性一共有三种值,在上面的布局的基础上,更换一下不同的值,看一下效果:
「none值」:所有引用的View形成一条链,水平居中,超出屏幕两侧的View不可见。
「chian值」:所引用的View形成一条链,超出部分会自动换行,同行的View会平分宽度。
「aligned值」:所引用的View形成一条链,但View会在同行同列。
即然是一条链,那么可以通过链的样式进行约束。
当flow_wrapMode属性为aligned和chian属性时,通过链进行约束。ConstraintLayout,看完一篇真的就够了么? 此文有谈到链约束(Chain)。
给Flow布局添加以下属性进行不同chain约束:
以上属性,取值有:spread、spread_inside、packed
「效果:」
「spread值:」
代码:
「spread_inside值:」
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-urvObrNR-1596201474480)(https://upload-images.jianshu.io/upload_images/23087078-e86d2423bb51e37e?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]
代码:
「packed值:」
代码:
其他效果大家在实践可以尝试看看效果,建议**「点赞」**收藏本文,在使用不会可以翻阅一下,效率事半功倍,免得重新浪费时间谷歌搜索。
上文XML布局中,所有TextView的宽高是一致的,所以看着整整齐齐,当宽高不一致时,可以进行对齐处理。个人试了一下app:flow_wrapMode="aligned"下的对齐,没啥效果,估计有默认值了吧。看看flow_wrapMode属性为none和chain情况吧。
给Flow布局添加以下属性进行不同Align约束:
对齐方向一般与链的方向相反才可生效,例如垂直链样式,一般对齐View的左右边和中间。
简单举个例子:垂直方向顶部对齐。
「效果图:」
可以看到E和G、F顶部对齐。
代码:
简单的理解aligned和chian是none的定制版,通过添加不同的属性定制而成。由于Flow是虚拟布局,简单理解就是约束助手,它并不会增加布局层级,却可以像正常的布局一样使用。
「其他属性」
上文的XML的布局没有设置Flow对View的组织方式(水平or 垂直),可以通过orientation属性来设置水平horizontal和垂直vertical方向,例如改为垂直方向。
当flow_wrapMode属性为aligned和chian时,通过flow_maxElementsWrap属性控制每行最大的子View数量。例如:flow_maxElementsWrap=3。
当flow_wrapMode属性为none时,A和G被挡住了,看不到。
要A或者G可见,通过设置flow_horizontalBias属性,取值在0-1之间。前提条件是flow_horizontalStyle属性为packed才会生效。
「效果图:」
设置flow_horizontalBias=1那么G就可以看到了。该属性还有其他类似ChainStyle的属性w玩法,具体可以实践体验。当然,也可以在flow_wrapMode属性为其他值生效。
通过不同的属性可以搭配很多不同的效果,再加上MotionLayout动画,那就更炫酷了。
Layer也是一个约束助手ConstraintHelper,相对Flow比较简单,常用来增加背景,或者共同动画。由于ConstraintHelper本身继承自View,跟我们自己通过View在ConstraintLayout布局中给多个View添加共同背景没什么区别,只是更方便而已。
「1、添加背景」
给ImageView和TextView添加个共同背景:
「效果:」
「代码:」
「2、共同动画」
通过属性动画给ImageView和TextView添加通过动画效果。
「效果:」
「代码:」
val animator = ValueAnimator.ofFloat( 0f, 360f)
animator.repeatMode=ValueAnimator.RESTART
animator.duration=2000
animator.interpolator=LinearInterpolator()
animator.repeatCount=ValueAnimator.INFINITE
animator.addUpdateListener {
layer.rotation= it.animatedValue as Float
}
layer.setOnClickListener {
animator.start()
}
对属性动画模糊的同学可以看看:Android属性动画,看完这篇够用了吧
支持:旋转、位移、缩放动画。透明效果试了一下,是针对自身的,而不是约束的View。
Flow和Layer都是ConstraintHelper的子类,当两者不满足需求时,可以通过继承ConstraintHelper来实现想要的约束效果。
在某乎APP有这么个类似的动画广告:
那么通过自定义ConstraintHelper来实现就非常简单:
class AdHelper :
ConstraintHelper {
constructor(context: Context?) : super(context)
constructor(context: Context?,attributeSet: AttributeSet):super(context,attributeSet)
constructor(context: Context?,attributeSet: AttributeSet,defStyleAttr: Int):super(context,attributeSet,defStyleAttr)
override fun updatePostLayout(container: ConstraintLayout?) {
super.updatePostLayout(container)
val views = getViews(container)
views.forEach {
val anim = ViewAnimationUtils.createCircularReveal(it, 0, 0, 0f, it.width.toFloat())
anim.duration = 5000
anim.start()
}
}
}
布局引用AdHleper:
圆角图片,圆形图片怎么实现?自定义View?通过ImageFilterButton,一个属性就搞定;ImageFilterButto能做的还有更多。
看看如何实现圆角或圆形图片:
「原图:」
将roundPercent属性设置为1,取值在0-1,由正方形向圆形过渡。
「效果:」
也可以通过设置round属性来实现:
「其他属性:」
altSrc和src属性是一样的概念,altSrc提供的资源将会和src提供的资源通过crossfade属性形成交叉淡化效果。默认情况下,crossfade=0,altSrc所引用的资源不可见,取值在0-1。 例如:
crossfade=0.5时,效果:
crossfade=1时,效果:
接下来几个属性是对图片进行调节:
warmth色温:1=neutral自然, 2=warm暖色, 0.5=cold冷色
brightness亮度:0 = black暗色, 1 = original原始, 2 = twice as bright两倍亮度;这个效果不好贴图,大家自行验证;
saturation饱和度:0 = grayscale灰色, 1 = original原始, 2 = hyper saturated超饱和;
contrast对比:1 = unchanged原始, 0 = gray暗淡, 2 = high contrast高对比;
上面属性的取值都是0、1、2,不过大家可以取其他值,效果也是不一样的。 最后一个属性overlay,表示不知道怎么用,看不到没效果,大家看看评论跟我说声?
ImageFilterView与ImageFilterButton的属性一模一样,只是它两继承的父类不一样,一些操作也就不一样。ImageFilterButton继承自AppCompatImageButton,也就是ImageButtion。而ImageFilterView继承自ImageView。
还记得你家项目经理给你的UI原型图么?想不想回敬一下项目经理,是时候了~
MockView能简单的帮助构建UI界面,通过对角线形成的矩形+标签。例如:
「效果:」
中间黑色显示的是MockView的id。通过MockView可以很好的构建一些UI思路。
MitionLayou主要是用来实现动作动画,可以参考我的另一篇文章:Android MotionLayout动画:续写ConstraintLayout新篇章
有ConstraintLayout实践经验的朋友应该知道margin设置负值在ConstraintLayout是没有效果的。例如下面布局:TextView B的layout_marginLeft和layout_marginTop属性是不会生效的。
「效果:」
可以通过轻量级的Space来间接实现这种效果。
「效果:」
2.0还增加了ConstraintProperties类用于通过api(代码)更新ConstraintLayout子视图;其他一些可以参考官方文档,估计也差不多了。