如何刷新ConstraintLayout中约束视图的高度

问题描述 投票:3回答:1

我有一个ConstraintLayout,其中我有一个View(称为Bar)和一个RecyclerView约束到Bar的底部,RecyclerView的高度设置为匹配Constraint(0dp),

因此,如果在Android布局编辑器中我向上移动了The Bar,那么,RecyclerView高度增加并始终“锚定”到The Bar,这是有效的,

但这在运行时并不是同样的行为,当我移动Bar(使用onTouchListener)时,RecyclerView高度根本不会改变,并且如果Bar处于相同位置则保持不变。

为了实现这种行为(移动Bar增加/减少RecyclerView高度),我已经想到并尝试了ConstraintLayout解决方案,

所以我设置了一个约束(Top)到Bar的底部,我设置了高度以匹配Constraint,

我也试图用LayoutParam实现这种行为,根据移动的像素改变高度,但是公式不是100%好,并且使用这种方式从视图的底部和顶部改变高度(显然不是使用Constraint解决方案)

<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>标签的内容:

<?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>

android kotlin android-constraintlayout ontouchlistener android-motionlayout
1个回答
0
投票

您正在为视图的translationY属性设置动画。更改此值会移动视图布局布局。换句话说,完成布局然后进行移动。结果,RecyclerView被限制在翻译之前的布局后位置。见setTranslationY(float)

设置此视图相对于其顶部位置的垂直位置。除了对象的布局放置它之外,这有效地定位了布局后的对象。

© www.soinside.com 2019 - 2024. All rights reserved.