首页 > 解决方案 > Android ConstraintLayout Barrier 以编程方式不起作用

问题描述

我正在尝试以编程方式获得ConstraintLayout一个工作。Barrier我正在使用 anko 作为我的代码。一切正常,但是一旦我尝试使用Barrier连接到的视图,它Barrier就会被设置为视图的顶部,而不是我所说的下方。这是代码:

    constraintLayout {
        imageView = imageView {
            id = View.generateViewId()
            backgroundColorResource = R.color.black
            scaleType = ImageView.ScaleType.CENTER_CROP
        }.lparamsMargin(width = matchParent, height = imageHeight)

        val gradientView = view {
            id = View.generateViewId()
            background = getGradient(Color.TRANSPARENT, Color.BLACK, 0.5f)
        }.lparams(width = matchParent, height = gradientHeight) {
            bottomToBottom = imageView.id
        }

        titleTextView = textView {
            id = View.generateViewId()
            typeface = context.font(R.font.value_regular)
            textSize = 40f
            textColor = Color.WHITE
            gravity = Gravity.CENTER
            horizontalPadding = Dimensions.mediumViewPadding
        }.lparams(width = matchParent) {
            topToTop = imageView.id
            bottomToBottom = imageView.id
        }

        dateTextView = textView {
            id = View.generateViewId()
            typeface = context.font(R.font.value_regular)
            textSize = 21f
            textColor = Color.WHITE
            gravity = Gravity.CENTER
            horizontalPadding = Dimensions.mediumViewPadding
        }.lparams(width = matchParent) {
            bottomToTop = titleTextView.id
            bottomMargin = Dimensions.smallViewPadding
        }

        subtitleTextView = textView {
            id = View.generateViewId()
            typeface = context.font(R.font.value_regular)
            textSize = 16f
            textColorResource = R.color.textColorOffWhite
            gravity = Gravity.CENTER
            horizontalPadding = Dimensions.mediumViewPadding
        }.lparams(width = matchParent) {
            topToBottom = titleTextView.id
            topMargin = Dimensions.smallViewPadding
        }

        val textGuideline = guideline {
            id = View.generateViewId()
        }.lparams(width = matchParent) {
            topToTop = gradientView.id
            bottomToBottom = gradientView.id
            verticalBias = 0.7f
        }

        val textBarrier = barrier {
            id = View.generateViewId()
            referencedIds = intArrayOf(subtitleTextView.id, textGuideline.id)
            type = Barrier.BOTTOM
        }.lparams(width = matchParent, height = wrapContent)

        textTextView = textView {
            id = View.generateViewId()
            typeface = context.font(R.font.value_regular)
            textSize = 21f
            textColorResource = R.color.textColorOffWhite
            lineSpacingMult = 1.38f
            gravity = Gravity.CENTER
            horizontalPadding = Dimensions.mediumViewPadding
        }.lparams(width = matchParent, height = wrapContent) {
            topToBottom = textBarrier.id
        }
    }.lparams(width = matchParent, height = wrapContent)

我想要做的是让文本与图像和渐变重叠,除非标题太大并将文本推低。如果我把topToBottom = textGuideline.id它按预期工作,但如果标题太长,我希望它把文本推低。

ConstraintLayout我正在使用的版本是 2.0.0-beta1。

标签: androidandroid-constraintlayoutanko

解决方案


barrierin anko 不起作用,你必须使用createBarrierwhich can be used in applyConstraintSet. 这将修复您的视图位于顶部。但对我来说,它还没有完全奏效。因为我guideline使用 averticalBias这个属性在使用 a 时会被忽略barrier。我注意到的是,不是guideline使用view高度为 1 效果更好,而是将 barrierId 放在 ids.xml 中也效果更好,但现在我不使用 averticalBias并且只是计算视图应该在哪里。这是我现在的代码:

            applyConstraintSet {
                gradientView {
                    connect(ConstraintSetBuilder.Side.BOTTOM to ConstraintSetBuilder.Side.BOTTOM of imageView)
                }

                titleTextView {
                    connect(
                        ConstraintSetBuilder.Side.TOP to ConstraintSetBuilder.Side.TOP of imageView,
                        ConstraintSetBuilder.Side.BOTTOM to ConstraintSetBuilder.Side.BOTTOM of imageView
                    )
                }

                dateTextView {
                    connect(ConstraintSetBuilder.Side.BOTTOM to ConstraintSetBuilder.Side.TOP of titleTextView margin Dimensions.smallViewPadding)
                }

                subtitleTextView {
                    connect(ConstraintSetBuilder.Side.TOP to ConstraintSetBuilder.Side.BOTTOM of titleTextView margin Dimensions.smallViewPadding)
                }

                textGuideline {
                    connect(
                        ConstraintSetBuilder.Side.TOP to ConstraintSetBuilder.Side.TOP of gradientView margin (gradientHeight.toFloat() * 0.7f).toInt()
                    )
                }

                val barrierId = View.generateViewId()
                createBarrier(barrierId, Barrier.BOTTOM, subtitleTextView.id, textGuideline.id)

                textTextView {
                    connect(ConstraintSetBuilder.Side.TOP to ConstraintSetBuilder.Side.BOTTOM of barrierId margin Dimensions.mediumViewPadding)
                }
            }

推荐阅读