在Android中动态添加到容器中的视图高度不正确:权重、线性和约束布局

3

介绍

我正在从API获取数据并将其添加到线性布局中,因此数据是动态的。这是一个加密货币应用程序,因此对于每个下载的加密货币,它会在新的布局中绘制一条新线路,最终动态添加。

容器:ConstraintLayout和内部LinearLayout

我使用ContraintLayout作为第一个容器。在其中设置了一个LinearContainer,其中包含动态添加的视图。

<android.support.constraint.ConstraintLayout
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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/coinMarketActivity"
android:background="#131A24"
tools:context="coinmarket.CoinMarket">

<include
    android:id="@+id/include"
    layout="@layout/top_bar"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<LinearLayout
    android:id="@+id/coinMarketCapTitleLinearLayout"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginEnd="8dp"
    android:layout_marginStart="8dp"
    android:layout_marginTop="8dp"
    android:gravity="center_vertical"
    android:orientation="horizontal"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/include">

    <TextView
        android:id="@+id/coinMarketCapTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="0"
        android:text="COIN MARKET CAP"
        android:textColor="#F89D1E"
        android:textSize="24sp"
        android:textStyle="bold" />

    <LinearLayout
        android:id="@+id/coinMarketCapLine"
        android:layout_width="wrap_content"
        android:layout_height="2dp"
        android:layout_marginStart="15dp"
        android:layout_weight="1"
        android:background="@drawable/borders"
        android:orientation="horizontal" />

</LinearLayout>

<LinearLayout
    android:id="@+id/coinDataContainer"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:layout_marginBottom="16dp"
    android:layout_marginEnd="8dp"
    android:layout_marginStart="8dp"
    android:layout_marginTop="16dp"
    android:gravity="center_vertical"
    android:orientation="vertical"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/coinMarketCapTitleLinearLayout">
</LinearLayout>

</android.support.constraint.ConstraintLayout>

动态视图所在的容器是android:id="@+id/coinDataContainer"

动态视图

这个视图是从布局文件夹中的xml文件中膨胀而来。然后我将从API获取的数据添加到上面部分的coinDataContainer中。由于它是一个大型的XML布局,因此我只会复制根元素:

<LinearLayout 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="0dp"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="6dp"
android:layout_weight="0.1">

如您所见,我在使用android:layout_weight="0.1",以便让所有添加的视图在屏幕上具有相同的高度,并使所有空间在它们之间分配。我还设置了android:layout_height="0dp"和android:layout_height="wrap_content",得到了相同的结果。

问题

只有第一个动态添加的子元素被绘制在屏幕上。然而,如果我添加以下代码,当所有子元素都已添加时,会定期执行该代码,我会得到它有10个子元素,而不是1个:

var children = _mDataRootView!!.childCount
Log.e("number of children", children.toString())
var firstchild = _mDataRootView!!.getChildAt(0)
Log.e("height of first child", firstchild.measuredHeight.toString())
Log.e("width of first child", firstchild.measuredWidth.toString())
_mDataRootView!!.invalidate() // called to try to redraw without success

这是打印日志的内容:
08-11 22:43:25.276 4575-4575/app.manu.test E/number of children: 10
08-11 22:43:25.277 4575-4575/app.manu.test E/height of first child: 1013
08-11 22:43:25.277 4575-4575/app.manu.test E/width of first child: 2504

以下是其在屏幕上的绘制方式:

只有一个硬币正在被绘制

你有任何想法是我做错了什么吗?

更多信息

如果我将内部充气布局的代码复制到容器中,无论我要复制多少次,所有空间都会正确分配给视图,并且它们的高度都相同。


你能试着将layout_gravity设置为center吗? - Epig
@Epig 在哪个布局中? - manu
在 LinearLayout 中添加 View 的想法。 - Epig
谢谢@Epig,我尝试了但没有成功。 - manu
你应该使用LinearLayout.LayoutParams添加View,并在这个LayoutParams中将gravity设置为center。这在我之前的一些项目中有效。但我认为你不应该使用LinearLayout,而是应该使用RecyclerView来解决这个问题。 - Epig
@Epig 我会尝试,但是让我问一个问题:除了将重力设置为中心,我应该在LayoutParams中添加一些layout_weight吗? - manu
1个回答

1
我已经解决了!!! 感谢@Epig给了我关键线索。
这是我如何展开子视图的方式:
val coin_martket_item_view = LayoutInflater.from(this).inflate(R.layout.coin_market_item, null)

接着我尝试获取布局参数,正如 @Epig 告诉我的那样设置适当的 LayoutParam 属性。

val current_params = coin_martket_item_view.layoutParams

当前参数始终返回null

然后我将inflate命令更改为

val coin_martket_item_view = LayoutInflater.from(this).inflate(R.layout.coin_market_item, _mDataRootView, false)

提供这种方式,可以为它们将要被填充的ViewGroup。突然,layoutParams开始出现在current_params值中,它开始绘制10个硬币而不是1个,因此问题得到解决。

再次感谢StackOverflow!


让我感到高兴的是我能够提供帮助。只有一点,我认为你不需要使用layout_weight,只需设置为wrap_content即可。 :) - Epig

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接