ConstraintLayout核心用法详解(五):Layer、ImageFilter*与MockView
整理旧电脑上的一些笔记前言ConstraintLayout核心用法详解一相对定位、边距、偏移与环形定位ConstraintLayout核心用法详解二尺寸约束与链约束ConstraintLayout核心用法详解三引导线、屏障、组和占位ConstraintLayout核心用法详解四ConstraintSet、MotionLayout与Flow今天继续整理ConstraintLayout。ConstraintLayout的特点扁平布局无嵌套一个层级就可以绘制复杂布局渲染性能高集合了线性布局、相对布局、百分比布局的特点和大多数功能支持可视化环境下拖拽绘制约束布局轻松地为应用中使用的 UI 组件添加动画效果。1. LayerLayer是ConstraintLayout 2.0加入的新的辅助类它同Guideline、Group类似都是虚拟辅助。Layer是用来控制一组视图的移动和旋转它和Group的场景不一样Group是用来简单控制视图的可见性VISIBILITY或INVISIBILITY。我们可以把Layer的效果看成是一个ViewGroup但是实际书写代码中并不需要把 view 包裹进去Layer。下面看具体 XML 代码示例?xml version1.0 encodingutf-8?androidx.constraintlayout.widget.ConstraintLayoutxmlns:androidhttp://schemas.android.com/apk/res/androidxmlns:apphttp://schemas.android.com/apk/res-autoxmlns:toolshttp://schemas.android.com/toolsandroid:idid/mainandroid:layout_widthmatch_parentandroid:layout_heightmatch_parenttools:context.constraintlayout.LayerActivityImageViewandroid:idid/iv_androidandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_marginTop50dpandroid:srcmipmap/ic_launcherapp:layout_constraintEnd_toEndOfparentapp:layout_constraintStart_toStartOfparentapp:layout_constraintTop_toTopOfparent/TextViewandroid:idid/tv_androidandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_marginTop10dpandroid:textandroidapp:layout_constraintEnd_toEndOfparentapp:layout_constraintStart_toStartOfparentapp:layout_constraintTop_toBottomOfid/iv_android/androidx.constraintlayout.helper.widget.Layerandroid:idid/layerandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentapp:constraint_referenced_idsiv_android,tv_androidapp:layout_constraintEnd_toEndOfparentapp:layout_constraintStart_toStartOfparent/Buttonandroid:idid/btn_rotationandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:textrotationapp:layout_constraintBottom_toBottomOfparentapp:layout_constraintEnd_toEndOfparentapp:layout_constraintStart_toStartOfparent//androidx.constraintlayout.widget.ConstraintLayout上面 XML 代码中关键属性constraint_referenced_ids指定要控制的视图ID如iv_android、tv_android逗号分隔Kotlin 代码示例classLayerActivity:AppCompatActivity(){overridefunonCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)setContentView(R.layout.activity_layer)vallayerfindViewByIdLayer(R.id.layer)valbuttonfindViewByIdButton(R.id.btn_rotation)button.setOnClickListener{valanimatorValueAnimator.ofFloat(0f,360f)animator.duration2000animator.addUpdateListener{animator-layer.rotationanimator.animatedValueasFloat layer.scaleX2.0flayer.scaleY2.0flayer.translationX100flayer.alpha0.3f}animator.start()}}}上面代码因为比较简单直接使用Kotlin原始方法findViewById实际推荐使用viewBinding减少模板代码。运行效果图2.ImageFilterView 和 ImageFilterButtonImageFilterView和ImageFilterButton也都是ConstraintLayout 2.0新添加的控件。它是 Android 第一次提供原生支持图像圆角、滤镜饱和度、亮度、对比度和色温、交叉淡入crossfade等特性。以往产品中遇到需要圆角图形如头像、歌曲专辑封面等往往采用自定义View或第三方控件实现有了ImageFitlerView就很好的解决了该场景问题。2.1 ImageFilterView首先介绍ImageFilterView支持的属性altSrc设置一个和src属性不同的图用来实现交叉淡入淡出效果saturation设置饱和度。其中0灰度1原始图2超饱和brightness设置亮度。0全黑1原始图2亮度加倍warmth设置色温。1中性2暖色0.5冷色contrast设置图像对比度。1不变0灰色2高对比度crossfade设置两张图像间的混合程度。0完全显示src图1完全显示altSrc图像round设置圆角半径roundPercent设置圆角半径为短边长的一个比例值overlay设置替代图(altSrc)是以叠加方式淡入原始图像上还是与原始图像进行交叉淡入淡出。默认trueXML代码展示androidx.constraintlayout.utils.widget.ImageFilterViewandroid:idid/iv_avatarandroid:layout_width100dpandroid:layout_height100dpandroid:srcdrawable/img_avatarapp:altSrcdrawable/img_duckapp:layout_constraintEnd_toEndOfparentapp:layout_constraintStart_toStartOfparentapp:layout_constraintTop_toTopOfparentapp:round20dp/Kotlin代码展示binding.sliderSaturation.addOnChangeListener{slider,value,fromUser-if(fromUser){valintValuevalue.toInt()Toast.makeText(this,$intValue,Toast.LENGTH_SHORT).show()when(intValue){0-binding.ivAvatar.saturation0f1-binding.ivAvatar.saturation1f2-binding.ivAvatar.saturation2f}}}binding.sliderBrightness.addOnChangeListener{slide,value,fromUser-if(fromUser){valintValuevalue.toInt()when(intValue){0-binding.ivAvatar.brightness0f1-binding.ivAvatar.brightness1f2-binding.ivAvatar.brightness2f}}}binding.sliderWarmth.addOnChangeListener{slide,value,fromUser-if(fromUser){valfloatValuevalue.toFloat()when(floatValue){0.5f-binding.ivAvatar.warmth0.5f1.0f-binding.ivAvatar.warmth1f2.0f-binding.ivAvatar.warmth2f}}}binding.sliderContrast.addOnChangeListener{slide,value,fromUser-if(fromUser){valintValuevalue.toInt()when(intValue){0-binding.ivAvatar.contrast0f1-binding.ivAvatar.contrast1f2-binding.ivAvatar.contrast2f}}}binding.seekbarCrossfade.setOnSeekBarChangeListener(object:SeekBar.OnSeekBarChangeListener{overridefunonProgressChanged(seekbar:SeekBar?,progress:Int,fromUser:Boolean){if(fromUser){valpercentageprogress/100.0fbinding.ivAvatar.crossfadepercentage}}overridefunonStartTrackingTouch(seekbar:SeekBar?){}overridefunonStopTrackingTouch(seekbar:SeekBar?){}})整体的代码示例还是很简单的我们结合下面的效果图来加深理解即可。2.2 ImageFilterButtonImageFilterButton是AppCompatImageButton的子类可以用来显示、组合和过滤图像。它与上面提到的ImageFilterView拥有相同的属性所不一样的就是ImageFilterButton兼具 Button 的特性。直接XML代码展示androidx.constraintlayout.utils.widget.ImageFilterButtonandroid:idid/btn_shareandroid:layout_width80dpandroid:layout_height80dpandroid:layout_marginTop20dpandroid:background#E91E63android:srcdrawable/icon_shareapp:layout_constraintEnd_toEndOfparentapp:layout_constraintStart_toStartOfparentapp:layout_constraintTop_toBottomOfid/seekbar_crossfadeapp:round40dp/androidx.constraintlayout.utils.widget.ImageFilterButtonandroid:idid/btn_favoriteandroid:layout_width80dpandroid:layout_height80dpandroid:layout_marginTop20dpandroid:background#E91E63android:srcdrawable/icon_favoriteapp:layout_constraintEnd_toEndOfparentapp:layout_constraintStart_toStartOfparentapp:layout_constraintTop_toBottomOfid/btn_shareapp:round40dp/效果图ImageFilterButton还是比较好理解的它支持的饱和度、对比度等特性参考上面ImageFilterView示例这里也就不再赘述了。3. MockView讲解MockView前先来看一张图。一些产品稿中会使用上图中带对角线的矩形来占位方便模拟一些视图而MockView也正是这样的用途。A view that is useful for prototyping layouts.MockView在布局中作为占位视图模拟真实数据或复杂视图的布局效果。实际开发中存在下面的场景真实数据还没有比如用户头像某些View是动态加载的比如RecyclerView加载的item;某些View是有不同的状态的比如loading、空数据提示我们当然可以在 Java(Kotlin) 中用代码模拟假数据来实现UI效果但当我们使用ConstraintLayout作为根布局时候更推荐MockView来模拟这些数据存在。下面是MockView的一些属性mock_label显示字体mock_labelColor字体颜色mock_labelBackgroundColor字体背景色mock_diagonalsColor对角线颜色mock_showDiagonals是否显示对角线XML代码示例androidx.constraintlayout.utils.widget.MockViewandroid:idid/backgroundandroid:layout_width0dpandroid:layout_height100dpapp:layout_constraintEnd_toEndOfparentapp:layout_constraintStart_toStartOfparentapp:layout_constraintTop_toTopOfparentapp:mock_labelLOGO或风景图app:mock_labelBackgroundColor#9C27B0app:mock_labelColorcolor/whiteapp:mock_showDiagonalstrue/androidx.constraintlayout.utils.widget.MockViewandroid:idid/loginandroid:layout_width200dpandroid:layout_height40dpandroid:layout_marginTop30dpapp:layout_constraintEnd_toEndOfparentapp:layout_constraintStart_toStartOfparentapp:layout_constraintTop_toBottomOfid/backgroundapp:mock_diagonalsColor#2196F3app:mock_label登录app:mock_showDiagonalstrue/androidx.constraintlayout.utils.widget.MockViewandroid:idid/registerandroid:layout_width200dpandroid:layout_height40dpandroid:layout_marginTop30dpapp:layout_constraintEnd_toEndOfparentapp:layout_constraintStart_toStartOfparentapp:layout_constraintTop_toBottomOfid/loginapp:mock_diagonalsColor#2196F3app:mock_label注册app:mock_showDiagonalstrue/预览图MockView作为辅助设计的控件它不能设置事件而且正式发布项目前建议要移除MockView保持布局干净。4.参考资料Developer-ConstraintLayouthttps://developer.android.google.cn/reference/androidx/constraintlayout/widget/ConstraintLayoutConstraintLayout历史版本https://developer.android.google.cn/jetpack/androidx/releases/constraintlayout?hlzh_cnImageFilterViewhttps://developer.android.google.cn/reference/kotlin/androidx/constraintlayout/utils/widget/ImageFilterView?hlenImageFilterButtonhttps://developer.android.google.cn/reference/androidx/constraintlayout/utils/widget/ImageFilterButton?hlenMockViewhttps://developer.android.google.cn/reference/kotlin/androidx/constraintlayout/utils/widget/MockView?hlen