[英]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_horizontal。 並在RelativeLayout下設置Recylerview center_horizontal的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>
使所選項目位於屏幕中央的最佳方法是應用
paddingHorizontal
到recyclerView
。 提供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.