Search code examples
androidandroid-recyclerviewandroid-gridlayout

Wrong dimension on recyclerview grid first row


I am trying to list items on my recycler view using the grid layout manager with two columns.

However, the first row of the grid seems to be having width issues.

first row showing different width than the others

When I scroll down until the first row is invisible, then scrolled back up, it will fix itself and show the correct width.

correct arrangement of the grid

My items are retrieved from themoviedb API,

adapter.setMovieWrapper(body); // body contains data from the API    
recyclerView.setLayoutManager(new GridLayoutManager(this, 2));
recyclerView.setAdapter(adapter);

Here is the layout code for the grid item:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:padding="2dp"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/movie_thumbnail"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerInside"
        android:contentDescription="@string/movie_thumbnail_description"/>

    <TextView
        android:background="@drawable/bg_shade"
        android:id="@+id/movie_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:textColor="#FFF"
        android:ellipsize="end"
        android:padding="8dp"/>
</FrameLayout>

Here is the adapter code:

public class MovieGridAdapter extends RecyclerView.Adapter<MovieGridItemViewHolder> {
    MovieWrapper movieWrapper;
    private Context context;

    public MovieGridAdapter(Context context) {
        this.context = context;
    }

    public MovieWrapper getMovieWrapper() {
        return movieWrapper;
    }

    public void setMovieWrapper(MovieWrapper movieWrapper) {
        this.movieWrapper = movieWrapper;
        this.notifyDataSetChanged();
    }

    @Override
    public MovieGridItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new MovieGridItemViewHolder(
                LayoutInflater.from(context)
                        .inflate(R.layout.movie_grid_item, parent, false)
        );
    }

    @Override
    public void onBindViewHolder(MovieGridItemViewHolder holder, int position) {
        Movie movie = movieWrapper.getResults().get(position);
        Uri uri = Uri.parse("https://image.tmdb.org/t/p/w185");
        uri = uri.buildUpon().appendEncodedPath(movie.getPosterPath()).build();

        Picasso.with(context)
                .load(uri)
                .into(holder.getThumbnail());

        holder.getTitle().setText(movie.getTitle());
    }

    @Override
    public int getItemCount() {
        if (movieWrapper != null && movieWrapper.getResults() != null) {
            return movieWrapper.getResults().size();
        }
        return 0;
    }
}

and here is the activity that host the recycler view XML layout:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.adityapurwa.popularmovies.MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/movie_grid"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></android.support.v7.widget.RecyclerView>

</android.support.constraint.ConstraintLayout>

Anyone know what is causing this issue and how to resolve it? Thanks!


Solution

  • There seems to be an issue with my ConstraintLayout hosting the RecyclerView, I changed it to FrameLayout and the issue disappeared. Even though the layout and the RecyclerView both have its dimension set to match_parent, somehow it fails to detect the dimension.

    Note: Changing the dimension to be absolute (e.g 100dp) also solved the problem, however it makes the layout unresponsive.