web-dev-qa-db-ja.com

Android RecyclerViewのアイテムのセンタリング

Androidの初心者です。私はRecyclerViewでアイテムを中央に配置できない理由がわかりません。

私が欲しいのは以下の画像のようなものです:-

Actual

Android renderは以下の画像のようです:-

Reality

RecyclerViewのアイテムを中央にプッシュする方法はありますか?したがって、次のようになります。

i want like this

以下のようにレイアウトファイルも提供します。

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);
27
skycrew

私は、この投稿に出くわしたときにあなたが尋ねているのと同じことだと思うことをしようとしていました。私が最終的に使用したソリューションは次のとおりです。

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();
    }
}

parentWidthRecyclerViewの幅、itemWidthはそれぞれの子ビューの幅(両方ともピクセル)でなければなりません。明らかに、これはすべての子ビューが同じ幅になることがわかっている場合にのみ機能します。

次に、RecyclerViewでこのレイアウトマネージャーを使用します

20
majormajors

recyclerviewを次のように設定します。

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

私のためにそれを修正しました

16
Maxi

サポートライブラリに新しいクラスを追加するだけで、パイのように簡単にAndroid.support.v7.widget.LinearSnapHelper

インスタンスを作成し、以下のようにrecyclerViewに添付するだけです。

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

@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の幅を超えない場合にのみ中央に配置されます。それ以外の場合は、通常どおりに機能します。

4
IZI_Shadow_IZI

これは私のために働いた:

    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>
2
manuel

アイテムビューのルートに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>
1
sonida

リサイクルビューにデコレータを追加します。

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