【发布时间】:2022-01-11 13:34:13
【问题描述】:
我在一行中有三个 TextView(Rating、VotesRating 和 Votes),但只能同时看到其中一个。这就是为什么我添加了一个Barrier 和那些TextViews movie_rating,movie_votes,movie_rating_votes 的ID。然后我使用Barrier 在它下面添加另一个TextView(带有电影描述)。但正如您在屏幕截图中看到的那样,描述文本可以在Barrier 的上方。这是一个非常有问题的库......
对于大多数 ViewHolders 来说都可以,这太疯狂了
implementation "androidx.constraintlayout:constraintlayout:2.1.2"
完整布局
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/margin_0_5x"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:onClick="@{(v) -> holder.onMovieClicked.invoke(movie)}"
android:paddingHorizontal="@dimen/margin_2x"
app:cardBackgroundColor="#2a2a2a">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/movie_image"
android:layout_width="72dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
app:imageUrl="@{movie.imageUrl}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="67:98"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0"
tools:background="@drawable/placeholder_movie" />
<TextView
android:id="@+id/movie_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/margin_1x"
android:layout_marginTop="@dimen/margin_0_25x"
android:text="@{String.format(@string/movie_title, movie.number, movie.title, movie.year)}"
android:textColor="@color/colorTextLight"
android:textSize="16sp"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toEndOf="@id/movie_image"
app:layout_constraintTop_toTopOf="parent"
tools:text="1. Red Notice (2021)" />
<TextView
android:id="@+id/movie_certificate_runtime_genre_rating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/margin_1x"
android:layout_marginTop="@dimen/margin_0_25x"
android:text="@{movie.certificateRuntimeGenrerating}"
android:textColor="#c9c9c9"
android:textSize="12sp"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toEndOf="@id/movie_image"
app:layout_constraintTop_toBottomOf="@id/movie_title"
app:visible="@{movie.certificateRuntimeGenrerating != null}"
tools:text="PG-13 | 118 min | Action, Comedy, Crime" />
<TextView
android:id="@+id/movie_rating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_1x"
android:layout_marginTop="@dimen/margin_0_25x"
android:layout_marginEnd="@dimen/margin_1x"
android:drawablePadding="@dimen/margin_0_5x"
android:gravity="bottom"
android:text="@{movie.rating}"
android:textColor="@color/colorTextLight"
android:textSize="12sp"
app:drawableStartCompat="@drawable/ic_star_rate"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toEndOf="@id/movie_image"
app:layout_constraintTop_toBottomOf="@id/movie_certificate_runtime_genre_rating"
app:visible="@{movie.rating != null && movie.votes == null}"
tools:text="7.7" />
<TextView
android:id="@+id/movie_rating_votes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_1x"
android:layout_marginTop="@dimen/margin_0_25x"
android:layout_marginEnd="@dimen/margin_1x"
android:drawablePadding="@dimen/margin_0_5x"
android:gravity="bottom"
android:text="@{String.format(@string/ph_3_spaced, movie.rating, @string/text_separator, movie.votes)}"
android:textColor="@color/colorTextLight"
android:textSize="12sp"
app:drawableStartCompat="@drawable/ic_star_rate"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toEndOf="@id/movie_rating"
app:layout_constraintTop_toBottomOf="@id/movie_certificate_runtime_genre_rating"
app:visible="@{movie.rating != null && movie.rating != null}"
tools:text="7.7 | Votes: 20,215" />
<TextView
android:id="@+id/movie_votes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_1x"
android:layout_marginTop="@dimen/margin_0_5x"
android:layout_marginEnd="@dimen/margin_1x"
android:text="@{movie.votes}"
android:textColor="@color/colorTextLight"
android:textSize="12sp"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toEndOf="@id/movie_rating_votes"
app:layout_constraintTop_toBottomOf="@id/movie_certificate_runtime_genre_rating"
app:visible="@{movie.votes != null && movie.rating == null}"
tools:text="Votes: 20,215" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/movie_rating_votes_bottom_barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:constraint_referenced_ids="movie_rating,movie_rating_votes,movie_votes" />
<TextView
android:id="@+id/movie_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/margin_1x"
android:layout_marginTop="@dimen/margin_0_25x"
android:text="@{movie.description}"
android:textColor="@color/colorTextDescLight"
android:textSize="12sp"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toEndOf="@id/movie_image"
app:layout_constraintTop_toBottomOf="@id/movie_rating_votes_bottom_barrier"
app:visible="@{movie.description != null}"
tools:text="When a single mom and her two kids arrive in a small town, they begin to discover their connection to the original Ghostbusters and the secret legacy their grandfather left behind." />
<Space
android:id="@+id/movie_bottom_space"
android:layout_width="wrap_content"
android:layout_height="@dimen/margin_0_5x"
app:layout_constraintTop_toBottomOf="@id/movie_desc"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
尺寸
<dimen name="margin_1x">8dp</dimen>
<dimen name="margin_0_25x">2dp</dimen>
<dimen name="margin_0_5x">4dp</dimen>
<dimen name="margin_0_75x">6dp</dimen>
<dimen name="margin_1_5x">12dp</dimen>
<dimen name="margin_2x">16dp</dimen>
<dimen name="margin_2_5x">20dp</dimen>
<dimen name="margin_3x">24dp</dimen>
<dimen name="margin_4x">32dp</dimen>
<dimen name="margin_5x">40dp</dimen>
<dimen name="margin_6x">48dp</dimen>
绑定
@JvmStatic
@BindingAdapter("visible")
fun visible(view: View, visible: Boolean?) {
view.isVisible = visible == true
}
RecyclerView 和 ViewHolder 类
class MoviesAdapter(
private val onMovieClicked: (movie: Movie) -> Unit
) : PagingDataAdapter<Movie, MoviesAdapter.MovieViewHolder>(MovieComparator) {
override fun onBindViewHolder(holder: MovieViewHolder, position: Int) {
getItem(position)?.let {
holder.bind(it, position)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MovieViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
return MovieViewHolder(
LayoutItemMovieBinding.inflate(layoutInflater, parent, false),
onMovieClicked
)
}
inner class MovieViewHolder(
binding: LayoutItemMovieBinding,
val onMovieClicked: (movie: Movie) -> Unit
) : BaseViewHolder<LayoutItemMovieBinding, Movie>(binding) {
init {
binding.holder = this
}
override fun bind(data: Movie, position: Int) {
binding.movie = data
}
}
private object MovieComparator : DiffUtil.ItemCallback<Movie>() {
override fun areItemsTheSame(oldItem: Movie, newItem: Movie) = oldItem.id == newItem.id
override fun areContentsTheSame(oldItem: Movie, newItem: Movie) = oldItem == newItem
}
}
【问题讨论】:
-
将
app:barrierAllowsGoneWidgets="true"添加到屏障有帮助吗?发布适配器的相关部分怎么样?这似乎发生在 RecyclerView 内部,重新绑定是如何发生的?您是否将其他视图设置为“消失”或“不可见”?这究竟是什么时候发生的?您能否提供一个简单的示例项目来复制它?你不可能发布一个 CL 问题,发布一个充满自定义内容(尺寸、颜色、资产)的布局,并期望 SO 用户找出问题所在,同时诅咒一个库有问题。 -
您可能还应该添加
app:layout_constrainedWidth="true"和所有 3 个 TextView 对应的高度,因为当您使用其中一个或另一个时,它们可能会消失。 (你为什么使用三个小部件对我来说也有点神秘),如果这是一个演示问题,我认为不应该将决定放在 viewHolder 中来决定要做什么,并添加更多 约束(不是双关语)视图系统试图在不到 60 毫秒的时间内实时测量和布置列表。如果有的话,请使用自定义视图并封装所有内容。但那是另一回事。 -
最后,如果屏障无法发挥作用,很可能您在布局已经测量/布局(或正在布局的过程中)时隐藏/显示了 textView,因此假定屏障所有三个引用的 Id 都消失了,因此以这种方式完成了它的工作。当你决定展示一个并设定它的价值时,已经太晚了。这也是未知的,因为我们既没有看到您的适配器,也没有看到您设置/获取此数据的时间。
-
@MartinMarconcini 你现在可以看到整个代码
-
@MartinMarconcini
app:layout_constrainedWidth="true",是的,我忘了添加两个文本视图,已修复,但仍然与此问题无关
标签: android android-recyclerview android-constraintlayout android-viewholder constraintlayout-barrier