Constraint Layout 2.0 several new features

轉(zhuǎn)自: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,因此不會(huì)將級(jí)別添加到布局層次結(jié)構(gòu)中)。類似于一個(gè)鏈,可以快速的橫向或縱向布局constraint_referenced_ids里面所有的elements,通過(guò)flow_wrapMode可以指定三種展示方式。

  • wrap none: 簡(jiǎn)單的創(chuàng)建一個(gè)鏈,所有引用的視圖以一條鏈的方式進(jìn)行布局,如果內(nèi)容溢出則溢出內(nèi)容不可見(jiàn)。
  • wrap chain: 根據(jù)空間的大小創(chuàng)建一個(gè)或多個(gè)鏈,當(dāng)出現(xiàn)溢出時(shí),溢出的內(nèi)容會(huì)自動(dòng)換行,以新的一條鏈的方式進(jìn)行布局。
  • wrap aligned: 與wrap chain相似,列的元素會(huì)對(duì)齊。
// 省略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" />

三種展示方式的效果(圖片來(lái)自網(wǎng)絡(luò)):

4.gif

還可以配合其他屬性進(jìn)行不同需求的展示:

  • 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

作為一種新的輔助工具,可以讓您在多個(gè)視圖上創(chuàng)建一個(gè)虛擬的圖層。同Flow不同,它并不會(huì)對(duì)視圖進(jìn)行布局,而是對(duì)多個(gè)視圖同時(shí)進(jìn)行變換(transformation)操作,比如多個(gè)視圖整體進(jìn)行旋轉(zhuǎn)(rotate)、平移(translate)或縮放(scale)操作,Layer 將會(huì)是最佳的選擇。

// 部分代碼省略
<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()
}

/**
 * 執(zhí)行l(wèi)ayer區(qū)域動(dòng)畫
 */
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()
}

執(zhí)行效果如下,所有控件類似snack移動(dòng)效果。

6.png

ConstraintHelper

FlowLayer均繼承自ConstraintHelper,類屬于輔助工具類,而且可以自定義實(shí)現(xiàn)。

1、ConstraintHelper持有view的引用,所以可以獲取views(getViews)對(duì)其進(jìn)行操作,提供了·onLayout·前后的回調(diào)(updatePreLayout)。

以下是對(duì)view作出CircularReveal的效果,ViewAnimationUtils給我們提供了createCircularReveal這個(gè)函數(shù),

class CircularAnimationHelper @JvmOverloads constructor(
        context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : ConstraintHelper(context, attrs, defStyleAttr) {

    // updatePostLayout會(huì)在onLayout之后調(diào)用,在這里做動(dòng)畫
    override fun updatePostLayout(container: ConstraintLayout) {
        super.updatePostLayout(container)
        val views = getViews(container)
        views.forEach {
            // 計(jì)算出中心點(diǎn)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里面指定需要做動(dòng)畫view。如果有其他view也有同樣的需求則直接復(fù)用即可。
<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、執(zhí)行效果,由中心向四周擴(kuò)散和飛入效果
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

一個(gè)可以顯示,合并和過(guò)濾的圖像,放在utils.widget目錄中的一個(gè)View,繼承自AppCompatImageView。

屬性

Attributes Meaning
altSrc 提供src圖像的替代圖像以允許淡入淡出
saturation 設(shè)置圖像的飽和度。
0 =灰度,1 =原始,2 =超飽和
brightness 設(shè)置圖像的亮度。
0 =黑色,1 =原始,2 =兩倍的亮度
warmth 調(diào)整圖像的表觀色溫。
1 =中性,2 =溫暖,.5 =冷
contrast 設(shè)置對(duì)比度。
1 =不變,0 =灰色,2 =高對(duì)比度
crossfade 設(shè)置兩個(gè)圖像之間的當(dāng)前混合。
0 = src 1 = altSrc圖片
round 用于實(shí)現(xiàn)圓角,以 dimension 為值,
call the TransitionListener with this trigger id
roundPercent 用于實(shí)現(xiàn)圓角,取值在0f-1f之間,為1f時(shí)將形成一張圓形圖片
overlay 定義替換圖像是在原始圖像上淡入淡出還是與其交叉淡入淡出。
默認(rèn)為true。對(duì)于半透明對(duì)象設(shè)置為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" />

通過(guò)seekbar來(lái)更改屬性值演示效果。

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) {
                    // 如果是用戶行為觸發(fā)的,才作相應(yīng)操作。false為code執(zhí)行。
                    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?) {
            }

        })
    }

執(zhí)行效果

8.gif

輸出是最好的輸入方式!
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容