簡體   English   中英

Android 在 RecyclerView 中居中項目

[英]Android Centering Item in RecyclerView

我是 android 的新手。 我不知道為什么我不能在 RecyclerView 中將我的項目居中。

我想要的如下圖所示:-

實際的

android 渲染如下圖:-

現實

有沒有辦法將 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>

片段日歷.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);

將 recyclerview 設置為:

android:layout_width="wrap_content"
android:layout_gravity="center_horizontal"

為我修好了

當我看到這篇文章時,我正在嘗試做我認為與您所問的相同的事情。 這是我最終使用的解決方案。

創建您自己的 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

添加到支持庫中的新類 - android.support.v7.widget.LinearSnapHelper

只需創建一個實例並將其附加到 recyclerView 如下-

LinearSnapHelper snapHelper  = new LinearSnapHelper();
snapHelper.attachToRecyclerView(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;
                }
            }
        }
    });

注意 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>

@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 的寬度時,項目才會居中……否則它將像往常一樣運作。

剛剛將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>

您需要將父Relativelayout Gravity 設置為center_horizo​​ntal。 並在RelativeLayout下設置Recylerview center_horizo​​ntal的layout_gravity。 像這樣:

<RelativeLayout
   android:layout_width="match_parent"
   android:gravity="center_horizontal"
   android:id="@+id/centre_lay"
   android:layout_height="wrap_content">
      <androidx.recyclerview.widget.RecyclerView
         android:id="@+id/list"
         android:background="@color/white"
         android:layout_width="wrap_content"
         android:layout_gravity="center_horizontal"
         android:layout_height="wrap_content">

    </androidx.recyclerview.widget.RecyclerView>
</RelativeLayout>

使所選項目位於屏幕中央的最佳方法是應用

paddingHorizontalrecyclerView 提供paddingHorizontal值,使您的項目居中,然后添加clipToPadding = false

之后,當您選擇recyclerView項目時,請使用recyclerView.smoothScrollToPosition(pos) 它會將您的項目滾動到該位置

現在您選擇的項目在屏幕中央可見!

  • 在這種情況下,首先我們需要知道 recyclerview 項目的大小。 此外,我們需要知道在 recyclerview 寬度中可以放置多少可見項目。 然后我們可以計算我們需要多少填充。

     public class CenterLinearLayoutManager extends LinearLayoutManager { private int mParentWidth; private int mItemWidth; private boolean needMargin = false; private int mItemSize = 0; public CenterLinearLayoutManager(Context context, int parentWidth, int itemWidth, int itemSize) { super(context); mParentWidth = parentWidth; mItemWidth = itemWidth; mItemSize = itemSize; this.setOrientation(RecyclerView.HORIZONTAL); int myCount = (mParentWidth / mItemWidth); if (itemSize < myCount) { needMargin = true; } } @Override public int getPaddingLeft() { if (needMargin) { return Math.round((mParentWidth - mItemWidth * mItemSize) / 2f); } else { return super.getPaddingLeft(); } } @Override public int getPaddingRight() { if (needMargin) { return Math.round((mParentWidth - mItemWidth * mItemSize) / 2f); } else { return super.getPaddingLeft(); } }

    }

  • 不要忘記在項目寬度中計算項目填充

將下面的裝飾器添加到回收器視圖中;

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM