视图中错误的高度动态添加到 Android 中的容器:权重、线性和约束布局
Wrong height in view added Dynamically to a container in Android: weight, Linear and Constraint Layouts
简介
我将我从 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" 以在屏幕中添加相同高度的所有视图,让所有 space 分布在他们。我还设置了 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
这是它在屏幕上的绘制方式:
知道我做错了什么吗?
更多信息
如果我将膨胀的内部布局的代码粘贴到容器中,任意多次,所有 space 都在视图之间正确分布,并且所有视图都具有相同的高度
我修好了!!!
感谢@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
current_params 总是返回 null
然后我将充气命令更改为
val coin_martket_item_view = LayoutInflater.from(this).inflate(R.layout.coin_market_item, _mDataRootView, false)
以这种方式提供他们将要在其中膨胀的视图组。突然 current_params val 开始出现 layoutParams,它开始绘制 10 个硬币而不是 1 个,所以问题解决了。
再次感谢 Whosebug!
简介
我将我从 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" 以在屏幕中添加相同高度的所有视图,让所有 space 分布在他们。我还设置了 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
这是它在屏幕上的绘制方式:
知道我做错了什么吗?
更多信息
如果我将膨胀的内部布局的代码粘贴到容器中,任意多次,所有 space 都在视图之间正确分布,并且所有视图都具有相同的高度
我修好了!!! 感谢@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
current_params 总是返回 null
然后我将充气命令更改为
val coin_martket_item_view = LayoutInflater.from(this).inflate(R.layout.coin_market_item, _mDataRootView, false)
以这种方式提供他们将要在其中膨胀的视图组。突然 current_params val 开始出现 layoutParams,它开始绘制 10 个硬币而不是 1 个,所以问题解决了。
再次感谢 Whosebug!