I have three TextViews (Rating, VotesRating and Votes) in one line but only one of them can be visible at the same time. That's why I added a Barrier
with ids of those TextViews movie_rating,movie_votes,movie_rating_votes
. And then I use that Barrier
to add another TextView
below it (with description of a movie). But as you can see in the screenshot the description text can be above that Barrier
. This is such a buggy library...
For most ViewHolders it works ok, this is crazy
implementation "androidx.constraintlayout:constraintlayout:2.1.2"
Full layout
<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>
dimensions
<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>
bindings
@JvmStatic
@BindingAdapter("visible")
fun visible(view: View, visible: Boolean?) {
view.isVisible = visible == true
}
RecyclerView and ViewHolder classes
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
}
}