Last Updated
Viewed 19 Times

I want to have a horizontal RecyclerView that I can insert or remove items from. The items should be aligned to the center when the RV width is smaller than the screen's.

Note: I cannot use android:layout_width=wrap_content, as suggested in other questions, since a change in the RV size will cause misbehaving animations (i.e items sliding in from "outside the RV" on item removal).

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/my_recycler_view"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"/>

layoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false);        
recyclerView.setLayoutManager(layoutManager);

...

Any ideas?

I am using RecyclerView with Cardview items inside it. I set the GridLayoutManager to show 2 items at each row and I want it to be centered on all phones like this :

expected result

expected result

But I have currently these :

Actual result

actual result

I tried different poor solutions (paddingLeft...) but it works on phones with bigger screens and doesn't work on smaller phones.

content_main.xml looks like this :

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:card_view="http://schemas.android.com/tools">

    <SearchView
        android:id="@+id/searchView"
        android:layout_width="match_parent"
        android:queryHint="Rechercher un film"
        android:iconifiedByDefault="false"
        android:layout_marginTop="65dp"
        android:layout_marginBottom="10dp"
        android:layout_height="30dp" />

    <android.support.v7.widget.RecyclerView
        android:id="@+id/movies_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_below="@+id/searchView"
        android:scrollbars="vertical"
        card_view:cardCornerRadius="5dp"
        card_view:cardElevation="5dp"
        card_view:cardUseCompatPadding="true" />


</RelativeLayout>

movie_card.xml :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">

<android.support.v7.widget.CardView
    android:id="@+id/cardView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <RelativeLayout
        android:layout_width="170dip"
        android:layout_height="wrap_content">

        <ImageView
            android:id="@+id/item_movie_poster"
            android:layout_width="170dip"
            android:layout_height="256dip"
            android:layout_centerHorizontal="true"
            android:contentDescription="@string/movie_image_description"
            android:scaleType="centerCrop" />

        <TextView
            android:id="@+id/item_movie_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/item_movie_poster"
            android:layout_centerHorizontal="true"
            android:layout_marginBottom="10dip"
            android:layout_marginTop="5dip"
            android:textSize="15sp"
            android:textAlignment="center"
            android:singleLine="true"
            android:ellipsize="marquee"
            android:textStyle="bold" />

    </RelativeLayout>
</android.support.v7.widget.CardView>
</LinearLayout>

And app_bar_main.xml which includes the content_main.xml :

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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"
    tools:context=".MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_main" />

</android.support.design.widget.CoordinatorLayout>

I need to center elements in each row so they will be like in this mockup. I've been searching if there is any layout that works that way without look. items are centered in their rows.

mockup

This is how it looks now in my code.enter image description here

I am planing a little app with recyclerviews in it. Sometimes I have to load only 4 items to it and sometimes over 200. Now I don't get it, how to center the custom recyclerviews items!

I have a custom recyclerview (grid) and I want to have 4 (2x2) items in it beeing centered.

What I have:

enter image description here

What I want:

enter image description here

So where is my mistake in following code?

fragment_single_pokemon.xml

<?xml version="1.0" encoding="utf-8"?>
<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"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context=".MainActivity">


    <android.support.constraint.ConstraintLayout
        android:id="@+id/cLayTypOne"
        android:layout_width="50dp"
        android:layout_height="25dp"
        android:layout_marginBottom="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:background="@drawable/customborder_typ"
        app:layout_constraintBottom_toTopOf="@+id/cLayTypTwo"
        app:layout_constraintEnd_toStartOf="@+id/civSprite"
        app:layout_constraintStart_toStartOf="parent">

        <TextView
            android:id="@+id/txtTypOne"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="TextView"
            android:textColor="#FFFFFF"
            android:textSize="8sp"
            android:textStyle="bold"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    </android.support.constraint.ConstraintLayout>

    <View
        android:id="@+id/vLine2"
        android:layout_width="50dp"
        android:layout_height="1dp"
        android:layout_marginBottom="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:background="#000000"
        app:layout_constraintBottom_toBottomOf="@+id/civSprite"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/civSprite"
        app:layout_constraintTop_toTopOf="@+id/civSprite">

    </View>

    <TextView
        android:id="@+id/txtPokemonName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:text="Pokéball"
        android:textAlignment="center"
        android:textSize="24sp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/civSprite"
        android:layout_width="148dp"
        android:layout_height="148dp"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="16dp"
        android:src="@mipmap/ic_launcher"
        app:civ_border_width="2dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/txtPokemonName" />

    <View
        android:id="@+id/vLine"
        android:layout_width="50dp"
        android:layout_height="1dp"
        android:layout_marginBottom="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:background="#000000"
        app:layout_constraintBottom_toBottomOf="@+id/civSprite"
        app:layout_constraintEnd_toStartOf="@+id/civSprite"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/civSprite">

    </View>

    <ImageView
        android:id="@+id/imgIsRaidBoss"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_marginBottom="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        app:layout_constraintBottom_toTopOf="@+id/vLine2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/civSprite"
        app:srcCompat="@drawable/raid_sprite" />

    <ImageView
        android:id="@+id/imgShinyExists"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_marginBottom="4dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        app:layout_constraintBottom_toTopOf="@+id/imgIsRaidBoss"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/civSprite"
        app:srcCompat="@drawable/ic_shiny" />

    <android.support.constraint.ConstraintLayout
        android:id="@+id/cLayTypTwo"
        android:layout_width="50dp"
        android:layout_height="25dp"
        android:layout_marginBottom="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:background="@drawable/customborder_typ"
        app:layout_constraintBottom_toTopOf="@+id/vLine"
        app:layout_constraintEnd_toStartOf="@+id/civSprite"
        app:layout_constraintStart_toStartOf="parent">

        <TextView
            android:id="@+id/txtTypTwo"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="TextView"
            android:textColor="#FFFFFF"
            android:textSize="8sp"
            android:textStyle="bold"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    </android.support.constraint.ConstraintLayout>

    <Button
        android:id="@+id/btnPokeDexEnty"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginEnd="48dp"
        android:layout_marginStart="48dp"
        android:layout_marginTop="16dp"
        android:background="@drawable/boarder_shape"
        android:text="Pokédex Eintrag"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/civSprite" />

    <TextView
        android:id="@+id/txtPokeDexEntry"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:text="TextView"
        android:textAlignment="center"
        android:visibility="gone"
        app:layout_constraintEnd_toEndOf="@+id/btnPokeDexEnty"
        app:layout_constraintStart_toStartOf="@+id/btnPokeDexEnty"
        app:layout_constraintTop_toBottomOf="@+id/btnPokeDexEnty" />

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rViewPokeInfo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="16dp"
        android:foregroundGravity="center_vertical"
        android:orientation="vertical"
        android:textAlignment="center"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/txtPokeDexEntry" />


</android.support.constraint.ConstraintLayout>

gridview_pokedex_pokeinfo.xml

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/rLayMainContainer"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginBottom="8dp"
    android:layout_marginEnd="8dp"
    android:layout_marginStart="8dp"
    android:layout_marginTop="8dp"
    android:gravity="center"
    android:orientation="vertical">

    <TextView
        android:id="@+id/txtPokeInfoTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:text="TextView"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/txtPokeInfoText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/txtPokeInfoTitle"
        android:layout_centerHorizontal="true"
        android:text="TextView" />
</RelativeLayout>

recyclerview code

RecyclerView recyclerViewPokeInfo = (RecyclerView)rLayout_mainFragment.findViewById(R.id.rViewPokeInfo);
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getActivity(),2);
recyclerViewPokeInfo.setLayoutManager(layoutManager);

CustomRecyclerAdapterPokeInfoGrid adapter = new CustomRecyclerAdapterPokeInfoGrid(getActivity(), db.getPokeInfo(intPokemonID));
recyclerViewPokeInfo.setAdapter(adapter);

recyclerview adapter

package com.spicysoftware.goexpert;

import android.content.Context;
import android.support.constraint.ConstraintLayout;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.ArrayList;

public class CustomRecyclerAdapterPokeInfoGrid extends RecyclerView.Adapter<CustomRecyclerAdapterPokeInfoGrid.ViewHolder> {
    private final ArrayList<String> strPokeInfo;
    private Context context;
    MySQLiteHelper db;
    int locationSpriteNo;
    String strCatchRate = "";
    String strEscapeRate = "";
    String strInEggs = "";
    String strKmAsFriend = "";

    public CustomRecyclerAdapterPokeInfoGrid(Context context, ArrayList<String> strPokeInfo) {
        this.strPokeInfo = strPokeInfo;
        this.context = context;
    }


    @Override
    public CustomRecyclerAdapterPokeInfoGrid.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.gridview_pokedex_pokeinfo, viewGroup, false);

        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(final CustomRecyclerAdapterPokeInfoGrid.ViewHolder viewHolder, final int i) {


        viewHolder.setClickListener(new ItemClickListener() {
            @Override
            public void onClick(View view, int position, boolean isLongClick) {

            }
        });

        // load image
        try {
            db = new MySQLiteHelper(context);

            String currentString = strPokeInfo.get(i);

            if(i == 0){
                viewHolder.txtPokeInfoTitle.setText("Fangchance");
            }else if(i == 1){
                viewHolder.txtPokeInfoTitle.setText("Fluchtchance");
            }else if(i == 2){
                viewHolder.txtPokeInfoTitle.setText("In Eiern");
            }else if(i == 3){
                viewHolder.txtPokeInfoTitle.setText("Distanz als Kumpel");
            }

            viewHolder.txtPokeInfoText.setText(currentString);


        }
        catch(Exception ex) {
            Log.v("Error: ", "-> "+ex);
        }

    }

    @Override
    public int getItemCount() {
        return strPokeInfo.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener{
        private TextView txtPokeInfoTitle,txtPokeInfoText;
        private ItemClickListener clickListener;
        private ConstraintLayout cLayoutSingleItem;

        public ViewHolder(View view) {
            super(view);

            txtPokeInfoTitle = (TextView)view.findViewById(R.id.txtPokeInfoTitle);
            txtPokeInfoText = (TextView)view.findViewById(R.id.txtPokeInfoText);


            cLayoutSingleItem = (ConstraintLayout)view.findViewById(R.id.cLayoutSingleItem);
            itemView.setOnClickListener(this);
            itemView.setOnLongClickListener(this);

        }

        public void setClickListener(ItemClickListener itemClickListener) {
            this.clickListener = itemClickListener;
        }

        @Override
        public void onClick(View view) {
            clickListener.onClick(view, getPosition(), false);
        }

        @Override
        public boolean onLongClick(View view) {
            clickListener.onClick(view, getPosition(), true);
            return true;
        }
    }
}

Similar Question 6 (1 solutions) : How center items in recyclerview when scrolling

Similar Question 7 (1 solutions) : Horizontal RecyclerView items in center

Similar Question 8 (1 solutions) : android recyclerview center horizontal items

cc