如何以编程方式在Kotlin中使用约束布局创建树布局?

时间:2019-05-22 14:33:57

标签: android kotlin android-constraintlayout

我想使用约束布局动态创建树形布局。

类似的东西:

enter image description here

在运行时检索树子节点。

规格:
1.所有节点最多可以有三个子节点。
2.必须以编程方式创建整个布局。
3.如果节点没有子节点,则在数据中传递Null。

我尝试过的事情:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    createTree(treeNode)
}

private fun createTree(treeNode: TreeNode) {

    val rootView: ConstraintLayout = dataBinding.root as ConstraintLayout
    val treeView = createLayout(treeNode, 0)

    if (treeView != null) {
        val mainViewConstraintSet = ConstraintSet()
        mainViewConstraintSet.clone(treeView)
        mainViewConstraintSet.connect(
                rootView.id,
                ConstraintSet.START,
                treeView.id,
                ConstraintSet.START
        )
        mainViewConstraintSet.connect(
                rootView.id,
                ConstraintSet.END,
                treeView.id,
                ConstraintSet.END
        )
        mainViewConstraintSet.applyTo(treeView)
        rootView.addView(treeView)
        Log.e("Log", "Added Root View")
    }
}

private fun createLayout(treeNode: TreeNode?, depth: Int): ConstraintLayout? {

    if (depth > 1) {
        return null
    }

    if (treeNode == null) {
        return null
    }

    val layoutView = ConstraintLayout(context)

    val layoutViewLayoutParams = ConstraintLayout.LayoutParams(
            ConstraintLayout.LayoutParams.WRAP_CONTENT,
            ConstraintLayout.LayoutParams.WRAP_CONTENT
    )
    layoutViewLayoutParams.topMargin = 16
    layoutViewLayoutParams.leftMargin = 16
    layoutViewLayoutParams.rightMargin = 16
    layoutViewLayoutParams.bottomMargin = 16
    layoutView.layoutParams = layoutViewLayoutParams
    layoutView.setBackgroundColor(Color.CYAN)
    layoutView.id = ViewCompat.generateViewId()

    val layoutNode = createNode(treeNode.user)
    Log.e("Log", "Created node for " + treeNode.user.name)

    val leftChildLayout = createLayout(treeNode.left, depth + 1)
    val middleChildLayout = createLayout(treeNode.middle, depth + 1)
    val rightChildLayout = createLayout(treeNode.right, depth + 1)

    val mainViewConstraintSet = ConstraintSet()

    mainViewConstraintSet.connect(
            layoutNode.id,
            ConstraintSet.TOP,
            layoutView.id,
            ConstraintSet.TOP,
            16
    )
    mainViewConstraintSet.connect(
            layoutNode.id,
            ConstraintSet.BOTTOM,
            layoutView.id,
            ConstraintSet.BOTTOM,
            16
    )
    mainViewConstraintSet.connect(
            layoutNode.id,
            ConstraintSet.START,
            layoutView.id,
            ConstraintSet.START,
            16
    )
    mainViewConstraintSet.connect(
            layoutNode.id,
            ConstraintSet.END,
            layoutView.id,
            ConstraintSet.END,
            16
    )

    if (leftChildLayout != null) {
        mainViewConstraintSet.connect(
            layoutNode.id,
            ConstraintSet.BOTTOM,
            leftChildLayout.id,
            ConstraintSet.TOP,
            16
        )
    }

    if (middleChildLayout != null) {
        mainViewConstraintSet.connect(
            layoutNode.id,
            ConstraintSet.BOTTOM,
            middleChildLayout.id,
            ConstraintSet.TOP,
            16
        )
    }

    if (rightChildLayout != null) {
        mainViewConstraintSet.connect(
            layoutNode.id,
            ConstraintSet.BOTTOM,
            rightChildLayout.id,
            ConstraintSet.TOP,
            16
        )
    }

    if (leftChildLayout != null && middleChildLayout != null) {
        mainViewConstraintSet.connect(
            leftChildLayout.id,
            ConstraintSet.END,
            middleChildLayout.id,
            ConstraintSet.START,
            16
        )
        mainViewConstraintSet.connect(
            middleChildLayout.id,
            ConstraintSet.END,
            leftChildLayout.id,
            ConstraintSet.START,
            16
        )
    }

    if (rightChildLayout != null && middleChildLayout != null) {
        mainViewConstraintSet.connect(
            middleChildLayout.id,
            ConstraintSet.END,
            rightChildLayout.id,
            ConstraintSet.START,
            16
        )
        mainViewConstraintSet.connect(
            rightChildLayout.id,
            ConstraintSet.END,
            middleChildLayout.id,
            ConstraintSet.START,
            16
        )
    }

    mainViewConstraintSet.applyTo(layoutView)
    // layoutView.setConstraintSet(mainViewConstraintSet)



    if (leftChildLayout != null) {
        layoutView.addView(leftChildLayout)
    }
    if (middleChildLayout != null) {
        layoutView.addView(middleChildLayout)
    }
    if (rightChildLayout != null) {
        layoutView.addView(rightChildLayout)
    }

    layoutView.addView(layoutNode)

    return layoutView
}

private fun createNode(user: User): ConstraintLayout {

    val node = ConstraintLayout(context)
    node.id = ViewCompat.generateViewId()

    val nodeTextView = TextView(context)
    nodeTextView.id = ViewCompat.generateViewId()

    nodeTextView.text = user.name
    nodeTextView.textSize = 18f
    nodeTextView.setTextColor(Color.BLACK)
    nodeTextView.setTypeface(null, Typeface.BOLD)
    val layoutParams = ConstraintLayout.LayoutParams(
            ConstraintLayout.LayoutParams.WRAP_CONTENT, ConstraintLayout.LayoutParams.WRAP_CONTENT
    )
    nodeTextView.layoutParams = layoutParams
    nodeTextView.setBackgroundColor(Color.GREEN)

    val constraintSet = ConstraintSet()
    constraintSet.clone(node)
    constraintSet.connect(nodeTextView.id, ConstraintSet.TOP, node.id, ConstraintSet.TOP, 16)
    constraintSet.connect(nodeTextView.id, ConstraintSet.LEFT, node.id, ConstraintSet.LEFT, 16)
    constraintSet.applyTo(node)

    node.addView(nodeTextView)
    node.setBackgroundColor(Color.RED)

    return node
}

树数据模型:

data class TreeNode( val user: User, var parent: TreeNode?,  
var left: TreeNode?, var middle: TreeNode?, var right: TreeNode?) { }

0 个答案:

没有答案