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: -
Quel Android rendu est comme l'image ci-dessous: -
Existe-t-il un moyen de pousser les éléments dans RecyclerView vers le centre? Donc, cela ressemblera à ceci: -
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);
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
définissez recyclerview sur:
Android:layout_width="wrap_content"
Android:layout_gravity="center_horizontal"
réparé pour moi
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);
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.
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>
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>
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)
}
}
}
}