美文网首页
Constraint Layout 2.0 several ne

Constraint Layout 2.0 several ne

作者: 十八子记 | 来源:发表于2021-04-26 14:08 被阅读0次

    转自:Constraint Layout 2.0 several new features-2

    Constraint Layout Practice and Summary-1
    Constraint Layout 2.0 several new features-2

    Flow

    Flow是虚拟布局(virtual layout,因此不会将级别添加到布局层次结构中)。类似于一个链,可以快速的横向或纵向布局constraint_referenced_ids里面所有的elements,通过flow_wrapMode可以指定三种展示方式。

    • wrap none: 简单的创建一个链,所有引用的视图以一条链的方式进行布局,如果内容溢出则溢出内容不可见。
    • wrap chain: 根据空间的大小创建一个或多个链,当出现溢出时,溢出的内容会自动换行,以新的一条链的方式进行布局。
    • wrap aligned: 与wrap chain相似,列的元素会对齐。
    // 省略width、height、textColor等代码
    <TextView
        android:id="@+id/tvZi"
        android:text="子" />
    // tvChou,tvYin,tvMao,tvChen,tvSi,tvWu,tvWei等代码同tvZi一致
    
    <androidx.constraintlayout.helper.widget.Flow
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:constraint_referenced_ids="tvZi,tvChou,tvYin,tvMao,tvChen,tvSi,tvWu,tvWei"
        app:flow_horizontalGap="8dp"
        app:flow_verticalGap="10dp"
        app:flow_wrapMode="aligned" />
    

    三种展示方式的效果(图片来自网络):

    4.gif

    还可以配合其他属性进行不同需求的展示:

    • flow_horizontalStyle = "spread|spread_inside|packed"
    • flow_verticalStyle = "spread|spread_inside|packed"
    • flow_horizontalBias = "float"
    • flow_verticalBias = "float"
    • flow_horizontalGap = "dimension"
    • flow_verticalGap = "dimension"
    • flow_horizontalAlign = "start|end"
    • flow_verticalAlign = "top|bottom|center|baseline

    Layer

    作为一种新的辅助工具,可以让您在多个视图上创建一个虚拟的图层。同Flow不同,它并不会对视图进行布局,而是对多个视图同时进行变换(transformation)操作,比如多个视图整体进行旋转(rotate)、平移(translate)或缩放(scale)操作,Layer 将会是最佳的选择。

    // 部分代码省略
    <androidx.constraintlayout.helper.widget.Layer
        android:id="@+id/layer"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@drawable/corner_white"
        app:constraint_referenced_ids="tvZi,tvChou,tvYin,tvMao"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    
    <!--子丑寅卯辰巳午未申酉戌亥-->
    <TextView
        android:id="@+id/tvZi"
        android:text="子"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginStart="50dp"
        android:layout_marginTop="16dp" />
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_layer)
    
        layerDemo()
    }
    
    /**
     * 执行layer区域动画
     */
    private fun layerDemo() {
        val layer = findViewById<Layer>(R.id.layer)
        val valueAnimator = ValueAnimator.ofFloat(0f, 60f, -30f, 0f, -20f, 0f, -8f, 0f)
        valueAnimator.addUpdateListener(AnimatorUpdateListener { animation ->
            if (null == animation.animatedValue) {
                return@AnimatorUpdateListener
            }
            val animatedValue = animation.animatedValue.toString().toFloat()
            layer.translationX = animatedValue
        })
        valueAnimator.duration = 800
        valueAnimator.start()
    }
    

    执行效果如下,所有控件类似snack移动效果。

    6.png

    ConstraintHelper

    FlowLayer均继承自ConstraintHelper,类属于辅助工具类,而且可以自定义实现。

    1、ConstraintHelper持有view的引用,所以可以获取views(getViews)对其进行操作,提供了·onLayout·前后的回调(updatePreLayout)。

    以下是对view作出CircularReveal的效果,ViewAnimationUtils给我们提供了createCircularReveal这个函数,

    class CircularAnimationHelper @JvmOverloads constructor(
            context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
    ) : ConstraintHelper(context, attrs, defStyleAttr) {
    
        // updatePostLayout会在onLayout之后调用,在这里做动画
        override fun updatePostLayout(container: ConstraintLayout) {
            super.updatePostLayout(container)
            val views = getViews(container)
            views.forEach {
                // 计算出中心点centerX,centerY和endRadius(半径)
                val createCircularReveal = ViewAnimationUtils.createCircularReveal(it, it.width / 2,
                        it.height / 2, 0f,
                        hypot((it.height / 2).toDouble(), (it.width / 2).toDouble()).toFloat()
                );
    
                createCircularReveal.duration = 1000 + Random.nextLong(500) * Random.nextInt(5)
                createCircularReveal.start()
            }
        }
    }
    
    2、CircularRevealHelper可以直接在xml里面使用,在constraint_referenced_ids里面指定需要做动画view。如果有其他view也有同样的需求则直接复用即可。
    <TextView
        android:id="@+id/tvZi"
        android:text="子"
        android:textColor="#ffffff"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginStart="50dp"
        android:layout_marginTop="16dp" />
        
    <cn.edu.iflifeonlyasfirstseen.constraint.layout.CircularAnimationHelper
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:constraint_referenced_ids="tvZi,tvChou,tvYin,tvMao" />
        
    <cn.edu.iflifeonlyasfirstseen.constraint.layout.FlyhereAnimationHelper
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:constraint_referenced_ids="tvMao,tvYin" />
    
    3、执行效果,由中心向四周扩散和飞入效果
    5.gif 7.gif

    ImageFilterView

    An ImageView that can display, combine and filter images. Added in 2.0
    Subclass of ImageView to handle various common filtering operations

    一个可以显示,合并和过滤的图像,放在utils.widget目录中的一个View,继承自AppCompatImageView

    属性

    Attributes Meaning
    altSrc 提供src图像的替代图像以允许淡入淡出
    saturation 设置图像的饱和度。
    0 =灰度,1 =原始,2 =超饱和
    brightness 设置图像的亮度。
    0 =黑色,1 =原始,2 =两倍的亮度
    warmth 调整图像的表观色温。
    1 =中性,2 =温暖,.5 =冷
    contrast 设置对比度。
    1 =不变,0 =灰色,2 =高对比度
    crossfade 设置两个图像之间的当前混合。
    0 = src 1 = altSrc图片
    round 用于实现圆角,以 dimension 为值,
    call the TransitionListener with this trigger id
    roundPercent 用于实现圆角,取值在0f-1f之间,为1f时将形成一张圆形图片
    overlay 定义替换图像是在原始图像上淡入淡出还是与其交叉淡入淡出。
    默认为true。对于半透明对象设置为false

    布局中添加ImageFilterView

    // activity_image_filter.xml
    
    <androidx.constraintlayout.utils.widget.ImageFilterView
        android:id="@+id/iv_1"
        android:layout_width="120dp"
        android:layout_height="120dp"
        app:srcCompat="@mipmap/cat" />
    
    <androidx.constraintlayout.utils.widget.ImageFilterView
        android:id="@+id/iv_7"
        android:layout_width="120dp"
        android:layout_height="120dp"
        app:altSrc="@drawable/tiger"
        app:srcCompat="@drawable/cat" />
    
    <!-- Omit code... -->
    
    <androidx.constraintlayout.helper.widget.Flow
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:constraint_referenced_ids="iv_1,iv_2,iv_3,iv_4,iv_5,iv_6,iv_7,iv_8"
        app:flow_horizontalGap="40dp"
        app:flow_horizontalStyle="packed"
        app:flow_verticalGap="20dp"
        app:flow_wrapMode="aligned" />
    
    <androidx.appcompat.widget.AppCompatSeekBar
        android:id="@+id/seekbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:max="100"
        android:progress="0"
        app:layout_constraintBottom_toBottomOf="parent" />
    

    通过seekbar来更改属性值演示效果。

    class ImageFilterActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_image_filter)
    
            val iv1: ImageFilterView = findViewById(R.id.iv_1)
            // ...Omit code
    
            val seekBar: SeekBar = findViewById(R.id.seekbar)
            seekBar.setOnSeekBarChangeListener(object : OnSeekBarChangeListener {
                override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
                    if (fromUser) {
                        // 如果是用户行为触发的,才作相应操作。false为code执行。
                        val realProgress = (progress / 100.0).toFloat()
                        iv1.saturation = realProgress * 10
                        iv2.brightness = 1 - realProgress
                        iv3.warmth = realProgress * 20
                        iv4.contrast = realProgress * 2
                        iv5.round = realProgress * 100
                        iv6.roundPercent = realProgress
                        iv7.crossfade = realProgress
                    }
                }
    
                override fun onStartTrackingTouch(seekBar: SeekBar?) {
                    // TODO("not yet implemented")
                }
    
                override fun onStopTrackingTouch(seekBar: SeekBar?) {
                }
    
            })
        }
    

    执行效果

    8.gif
    输出是最好的输入方式!
    

    相关文章

      网友评论

          本文标题:Constraint Layout 2.0 several ne

          本文链接:https://www.haomeiwen.com/subject/ctherltx.html