美文网首页Android
ConstraintLayout代码动态控制约束布局

ConstraintLayout代码动态控制约束布局

作者: 寻水的鱼Chock | 来源:发表于2021-11-26 16:20 被阅读0次

1. 动态控制

我个人对它的定义是:区别于使用xml的方式,使用代码来实现对View的约束控制的这么一种方式叫动态控制。虽然有的databinding以后, xml也并不完全是“静态的”,在这里不做过多无意义的争论。其实XML是Android实现UI的常见方式,已经可以实现大部分的需求,但是恰当的加入一些动态控制也是对实现需求的一种不错补充。

2. 什么是ConstraintLayout(约束布局)

约束布局ConstraintLayout是一个ViewGroup,可以在API 9以上的Android系统使用它,它的出现主要是为了解决布局嵌套过多的问题,以灵活的方式定位和调整小部件,是对LinearLayoutRelatedLayout的一种补充或者说取代。
如何在XML中使用ConstraintLayout在此也不做过多的说明,网上已有很多资料,请君移步查阅。

3. ConstraintLayout初体验

val mWebView = findViewById<WebView>(R.id.mWebView)
if (mWebView.layoutParams is ConstraintLayout.LayoutParams) {
    val pView = mWebView.parent
    if (pView is ConstraintLayout) {
        val bottomView = LayoutInflater.from(this)
            .inflate(R.layout.item_entry_web_bottom_view, pView, false)
        bottomView.id = View.generateViewId()
        pView.addView(bottomView)
        val cs = ConstraintSet()
        cs.clone(pView)
        cs.clear(mWebView.id)
        val pId = ConstraintLayout.LayoutParams.PARENT_ID
        cs.connect(mWebView.id, ConstraintSet.TOP, pId, ConstraintSet.TOP)
        cs.connect(mWebView.id, ConstraintSet.START, pId, ConstraintSet.START)
        cs.connect(mWebView.id, ConstraintSet.END, pId, ConstraintSet.END)
        cs.connect(mWebView.id, ConstraintSet.BOTTOM, bottomView.id, ConstraintSet.TOP)
        cs.applyTo(pView)
    }
}

这是一段在布局底部插入一个自定义xml布局的代码片段。
原始xml的定义

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <WebView
        android:id="@+id/mWebView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

增加代码后的等效XML

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <WebView
        android:id="@+id/mWebView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@+id/botton_view"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <include
        android:id="@+id/botton_view"
        layout="@layout/item_entry_web_bottom_view" />
</androidx.constraintlayout.widget.ConstraintLayout>

3. 什么情况下使用

能修改XML达到需求时尽量使用XML定义的方式进行UI修改,便于后续代码的维护。那什么情况下不得不使用代码控制呢?
1、原本代码已有封装,但未提供可实现需求的扩展,且没有源码无法修改XML定义时。
2、需要使用代码控制的其他情况。

4. 常见的布局约束等效举例

还是以以上举例中的XML为例进行说明

4.1 新建布局约束
val cs = ConstraintSet()
4.2 从已有的XML约束中克隆
cs.clone(pView)

克隆有很多好处,可以省去很多原本已有的约束代码。

4.3 清除特定View已有的XML约束
cs.clear(mWebView.id)

配合克隆使用最佳。

4.4 XML等效代码举例
app:layout_constraintTop_toTopOf="parent"
=>
val pId = ConstraintLayout.LayoutParams.PARENT_ID
cs.connect(mWebView.id, ConstraintSet.TOP, pId, ConstraintSet.TOP)
app:layout_constraintTop_toTopOf="@+id/botton_view"
=>
cs.connect(mWebView.id, ConstraintSet.TOP, bottonView.id, ConstraintSet.TOP)

举一反三,相应的

app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"

也都好理解了, 相应的

cs.connect(mWebView.id, ConstraintSet.START, pId, ConstraintSet.START)
cs.connect(mWebView.id, ConstraintSet.TOP, pId, ConstraintSet.TOP)
cs.connect(mWebView.id, ConstraintSet.END, pId, ConstraintSet.END)
cs.connect(mWebView.id, ConstraintSet.BOTTOM, pId, ConstraintSet.BOTTOM)

只需要更换第二和第四个参数, 就可以实现layout_constraint###_to###Of的所有随机组合。
第一个参数就是你写layout_constraint###_to###Of所在的那个View ID
第三个参数就是layout_constraint###_to###Of等于后面的那个View ID
是不是很简单?是的。但是~
最后别忘了

cs.applyTo(pView)

其中需要特别注意的是: pView必须是ConstraintLayoutconnect()函数传入的ID必须是它包含的子View的ID, 否则设置无效

相关文章

网友评论

    本文标题:ConstraintLayout代码动态控制约束布局

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