如何在ConstraintLayout中刷新约束视图的高度 [英] How to refresh height of a Constrained View in ConstraintLayout
问题描述
我有一个ConstraintLayout,其中有一个View(称为Bar)和一个RecyclerView,约束到Bar的底部,RecyclerView的高度设置为与Constraint(0dp)匹配,
I have a ConstraintLayout in which i have a View(called Bar) and a RecyclerView Constrained to The Bottom of The Bar, The RecyclerView has it's height set to match Constraint(0dp),
例如,如果我在Android布局编辑器中将Bar向上移动,则RecyclerView高度增加并且始终锚定"到Bar,这是可行的,
So if in The Android Layout Editor i move up The Bar for example, The RecyclerView height increase and is always "anchored" To The Bar, it's work,
但是在运行时,这是不一样的行为,当我移动Bar(使用onTouchListener)时,RecyclerView的高度根本不会改变,就像Bar在同一位置一样.
But This is Not the same behavior at runtime, when i move the Bar(with an onTouchListener), The RecyclerView height does not change at all and stay like if the Bar was at the same position..
要实现此行为(将Bar增加/减少RecyclerView的高度),我已经考虑并尝试了ConstraintLayout解决方案,
To achieve this Behavior(move the Bar increase/decrease the RecyclerView height), i have thinked and tried to The ConstraintLayout Solution,
所以我在Bar的底部设置了一个Constraint(Top),并且我将高度设置为与Constraint相匹配,
So i have set a constraint(Top) to the Bottom of the Bar and i have set the height to match the Constraint,
我也尝试使用LayoutParam实现此行为,根据移动的像素更改高度,但是公式不是100%好的,并且使用这种方式从视图的底部和顶部更改高度(显然不是通过约束解)
I have also tried to achieve this behavior with the LayoutParam, changing the height based on pixels moved, But the formula is not 100% good and using this way change height from both bottom and top of the view(apparently not with the Constraint solution)
<ConstraintLayout>
...
<!-- Removed all Constraint to the Bar to let it freely move on Touch on it's Y Axis, also tried to constraint start, end, top to the parent, but same behavior -->
<include layout="@layout/theBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/theBarWhoMove"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerViewConstrainedToTheBar"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="2dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="2dp"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="2dp"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@+id/theBarWhoMove"/>
...
</ConstraintLayout>
barWhoMove.setOnTouchListener { v, event ->
when(event.actionMasked) {
MotionEvent.ACTION_DOWN -> {
barWhoMoveDY = v.y - event.rawY
return@setOnTouchListener true
}
MotionEvent.ACTION_MOVE -> {
////We move the Bar
v.animate().translationY(barWhoMoveDY +
event.rawY).setDuration(0).start()
/* To try to relayout and resize based on match Constrain taking in consideration the new barWhoMove position*/
recyclerViewConstrainedToTheBar.invalidate()
recyclerViewConstrainedToTheBar.requestLayout()
recyclerViewConstrainedToTheBar.forceLayout()
////Tried Also
constraintSet.constrainHeight(recyclerViewConstrainedToTheBar.id,
ConstraintSet.MATCH_CONSTRAINT)
constraintSet.applyTo(rootConstraintLayout)
////Tried Also
rootConstraintLayout.invalidate()
rootConstraintLayout.requestLayout()
rootConstraintLayout.forceLayout()
if(v.y < oldDY) {
/*#Solution 2 increase with LayoutParam but The formula is not 100% correct and it change height from both bottom and top, When View is moving Up or Down(it's work for detecting this)*/
....
oldDy = v.y
}
else {
....
oldDy = v.y
}
return@setOnTouchListener true
}
MotionEvent.ACTION_UP -> {
}
}
return@setOnTouchListener false
}
这是布局1中<include>
标记的内容:
This is the content of The <include>
tag in the layout 1 :
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:showIn="@layout/fragment_layout_main">
<data>
<variable name="variable" type="com.demo.ourClass" />
</data>
<android.support.v7.widget.CardView
android:id="@+id/card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textViewTitle"
android:layout_marginTop="8dp"
app:cardElevation="6dp">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@mipmap/ic_launcher_round"
android:id="@+id/imageViewA"
android:layout_marginTop="8dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="8dp"/>
<TextView
android:text="@{variable.name}"
tools:text="TextView"
android:textAppearance="@style/TextAppearance.AppCompat.Light.SearchResult.Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textViewA"
app:layout_constraintStart_toEndOf="@+id/imageViewA"
app:layout_constraintBottom_toBottomOf="@id/imageViewA"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintTop_toTopOf="parent"/>
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>
推荐答案
您正在为视图的translationY
属性设置动画.更改此值将移动视图帖子布局.换句话说,先完成布局,然后进行移动.结果,RecyclerView
被限制在平移之前的布局后位置.参见 setTranslationY(float):
You are animating the translationY
property of the view. Changing this value moved the view post layout. In other words, the layout is completed then the move is made. As a result, the RecyclerView
is constrained to the post-layout position before the translation. See setTranslationY(float):
设置此视图相对于其顶部位置的垂直位置.除了将对象的布局放置在任何位置之外,这还可以有效地放置对象在布局后的位置.
Sets the vertical location of this view relative to its top position. This effectively positions the object post-layout, in addition to wherever the object's layout placed it.
这篇关于如何在ConstraintLayout中刷新约束视图的高度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!