web-dev-qa-db-fra.com

Android Élément de centrage dans RecyclerView

Im un débutant dans Android. Je ne sais pas pourquoi je ne peux pas centrer mon article dans RecyclerView.

Ce que je veux, c'est comme ci-dessous l'image: -

Actual

Quel Android rendu est comme l'image ci-dessous: -

Reality

Existe-t-il un moyen de pousser les éléments dans RecyclerView vers le centre? Donc, cela ressemblera à ceci: -

i want like this

Je fournis également les fichiers de mise en page comme ci-dessous: -

recycler_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="wrap_content" Android:layout_height="wrap_content"
    Android:id="@+id/calendar_itemContainer">

    <TextView
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:text="April"
        Android:id="@+id/calendar_txtMonth"
        Android:layout_alignParentTop="true"
        Android:layout_alignParentLeft="true"
        Android:layout_alignParentStart="true"
        Android:layout_alignParentRight="true"
        Android:layout_alignParentEnd="true"
        Android:textColor="#ff58636d"
        Android:textSize="16sp"
        Android:gravity="center|center_vertical|center_horizontal"
        Android:paddingTop="8dp"
        Android:paddingLeft="12dp"
        Android:paddingRight="12dp" />

    <TextView
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:text="21"
        Android:id="@+id/calendar_txtDay"
        Android:layout_alignParentLeft="true"
        Android:layout_alignParentStart="true"
        Android:layout_below="@+id/calendar_txtMonth"
        Android:layout_alignParentRight="true"
        Android:layout_alignParentEnd="true"
        Android:textColor="#ff58636d"
        Android:textSize="40sp"
        Android:layout_marginTop="-10dp"
        Android:paddingLeft="10dp"
        Android:paddingRight="10dp"
        Android:paddingBottom="5dp"
        Android:gravity="center|center_vertical|center_horizontal" />
</RelativeLayout>

fragment_calendar.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">

    <Android.support.v7.widget.RecyclerView
        Android:id="@+id/calendar_recycler_view"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:scrollbars="horizontal"
        Android:background="#ff2c3e50" />
</RelativeLayout>

et les codes Java: -

CalendarAdapter mAdapter = new CalendarAdapter(mDataset);
mLayoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
mRecyclerView.setLayoutManager(mLayoutManager);
mAdapter.setCalendarCallbacks(this);
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
selectItem(mCurrentSelectedPosition);
27
skycrew

J'essayais de faire ce que je pense être la même chose que vous demandez quand je suis tombé sur ce post. Voici la solution que j'ai finalement utilisée.

Créez votre propre sous-classe de LinearLayoutManager et remplacez getPaddingLeft () et getPaddingRight () comme ceci.

public class CustomLayoutManager extends LinearLayoutManager {
    private int mParentWidth;
    private int mItemWidth;

    public CustomLayoutManager(Context context, int parentWidth, int itemWidth) {
        super(context);
        mParentWidth = parentWidth;
        mItemWidth = itemWidth;
    }

    @Override
    public int getPaddingLeft() {
        return Math.round(mParentWidth / 2f - mItemWidth / 2f);
    }

    @Override
    public int getPaddingRight() {
        return getPaddingLeft();
    }
}

parentWidth doit être la largeur de RecyclerView et itemWidth doit être la largeur de chacune de vos vues enfant, toutes deux en pixels. Évidemment, cela ne fonctionne que si vous savez que toutes les vues de vos enfants auront la même largeur.

Ensuite, utilisez simplement ce gestionnaire de disposition avec votre RecyclerView

20
majormajors

définissez recyclerview sur:

Android:layout_width="wrap_content"
Android:layout_gravity="center_horizontal"

réparé pour moi

16
Maxi

Simple comme bonjour avec la nouvelle classe ajoutée à la bibliothèque de support- Android.support.v7.widget.LinearSnapHelper

Créez simplement une instance et attachez-la au recyclerView comme ci-dessous-

LinearSnapHelper snapHelper  = new LinearSnapHelper();
snapHelper.attachToRecyclerView(recyclerView);
4
Jishin Dev

La réponse de @majormajors était proche, mais commencera par centrer le premier élément de la liste et non par centrer les éléments (dans leur ensemble) comme indiqué dans les images. Un calcul supplémentaire doit être effectué pour vérifier la largeur totale de l'article. J'ai modifié le code publié par @majormajors.

public class CenterItemLayoutManager extends LinearLayoutManager {
  private final int parentWidth;
  private final int itemWidth;
  private final int numItems;

  public CenterItemLayoutManager(
      final Context context,
      final int orientation,
      final int parentWidth,
      final int itemWidth,
      final int numItems) {
    super(context, orientation, false);
    this.parentWidth = parentWidth;
    this.itemWidth = itemWidth;
    this.numItems = numItems;
  }

  @Override
  public int getPaddingLeft() {
    final int totalItemWidth = itemWidth * numItems;
    if (totalItemWidth >= parentWidth) {
      return super.getPaddingLeft(); // do nothing
    } else {
      return Math.round(parentWidth / 2f - totalItemWidth / 2f);
    }
  }

  @Override
  public int getPaddingRight() {
    return getPaddingLeft();
  }
}

Dans ce cas, les articles ne seront centrés que s'ils ne dépassent pas la largeur de la vue de recyclage ... sinon, ils agiront comme d'habitude.

4
IZI_Shadow_IZI

Cela a fonctionné pour moi:

    LinearSnapHelper snapHelper = new LinearSnapHelper();
    snapHelper.attachToRecyclerView(mRecyclerView);

    //This is used to center first and last item on screen
    mRecyclerView.addItemDecoration(new RecyclerView.ItemDecoration() {
        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
            int position = parent.getChildViewHolder(view).getAdapterPosition();

            if (position == 0 || position == state.getItemCount() - 1) {

                int elementWidth = (int)getResources().getDimension(R.dimen.list_element_width);
                int elementMargin = (int)getResources().getDimension(R.dimen.list_element_margin);

                int padding = Resources.getSystem().getDisplayMetrics().widthPixels / 2 - elementWidth - elementMargin/2;

                if (position == 0) {
                    outRect.left = padding;

                } else {
                    outRect.right = padding;
                }
            }
        }
    });

Mind elementWidth et elementMargin sont des valeurs fixes dans mon fichier dimens.xml que j'utilise dans ma disposition xml:

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="@dimen/list_element_margin"
    Android:layout_height="match_parent"
    Android:orientation="vertical"
    Android:layout_margin="@dimen/list_element_width">
    <TextView
        Android:id="@+id/day_text"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"/>
</LinearLayout>
2
manuel

Vient d'ajouter Android:orientation="vertical" à la racine de la vue de l'élément. Essayons.

<?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
                  Android:layout_width="match_parent"
                  Android:layout_height="180dp"
                  Android:orientation="vertical"
                  Android:padding="4dp">

        <ImageView
            Android:id="@+id/movie_column_photo"
            Android:layout_width="80dp"
            Android:layout_height="120dp"
            Android:layout_gravity="center_horizontal"/>

        <TextView
            Android:id="@+id/movie_column_title"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:gravity="center"/>
    </LinearLayout>
1
sonida

Ajoutez le décorateur ci-dessous à la vue du recycleur;

class CenterAlignDecorator : RecyclerView.ItemDecoration() {
    override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
        parent.adapter?.let {
            if (parent.getChildAdapterPosition(view) == 0 && view.width > 0) {
                val itemSize = view.width + view.paddingStart + view.paddingEnd
                val itemLimit = (parent.width / itemSize) + 1
                if (state.itemCount <= itemLimit) {
                    val padding = (parent.width - (it.itemCount * itemSize)) / 2
                    outRect.set(padding, 0, 0, 0)
                }
            } else {
                outRect.set(0, 0, 0, 0)
            }
        }
    }
}
0
Zahid Rasheed