Androidの初心者です。私はRecyclerViewでアイテムを中央に配置できない理由がわかりません。
私が欲しいのは以下の画像のようなものです:-
Android renderは以下の画像のようです:-
RecyclerViewのアイテムを中央にプッシュする方法はありますか?したがって、次のようになります。
以下のようにレイアウトファイルも提供します。
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>
および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);
私は、この投稿に出くわしたときにあなたが尋ねているのと同じことだと思うことをしようとしていました。私が最終的に使用したソリューションは次のとおりです。
LinearLayoutManagerの独自のサブクラスを作成し、同様にgetPaddingLeft()およびgetPaddingRight()をオーバーライドします。
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
はRecyclerView
の幅、itemWidth
はそれぞれの子ビューの幅(両方ともピクセル)でなければなりません。明らかに、これはすべての子ビューが同じ幅になることがわかっている場合にのみ機能します。
次に、RecyclerView
でこのレイアウトマネージャーを使用します
recyclerviewを次のように設定します。
Android:layout_width="wrap_content"
Android:layout_gravity="center_horizontal"
私のためにそれを修正しました
サポートライブラリに新しいクラスを追加するだけで、パイのように簡単にAndroid.support.v7.widget.LinearSnapHelper
インスタンスを作成し、以下のようにrecyclerViewに添付するだけです。
LinearSnapHelper snapHelper = new LinearSnapHelper();
snapHelper.attachToRecyclerView(recyclerView);
@majormajorsの回答は近いものでしたが、リストにある最初のアイテムを中央に配置し、画像に示されているように(全体として)アイテムを中央に配置しません。アイテムの合計幅を確認するには、追加の計算が必要です。 @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();
}
}
この場合、アイテムはrecyclerviewの幅を超えない場合にのみ中央に配置されます。それ以外の場合は、通常どおりに機能します。
これは私のために働いた:
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とelementMarginは、xmlレイアウトで使用するdimens.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>
アイテムビューのルートにAndroid:orientation="vertical"
を追加しました。試してみよう。
<?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>
リサイクルビューにデコレータを追加します。
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)
}
}
}
}