Horizontally Center First Item Of Recyclerview
Solution 1:
You can implement this with an RecyclerView.ItemDecoration
in getItemOffsets()
, to offset the first and last item appropriately.
Retrieve any offsets for the given item. Each field of
outRect
specifies the number of pixels that the item view should be inset by, similar to padding or margin. The default implementation sets the bounds of outRect to 0 and returns.If you need to access Adapter for additional data, you can call
getChildAdapterPosition(View)
to get the adapter position of the View.
You might need to use the messured size of the item and the RecyclerView
as well. But these information is available to be used anyhow.
Solution 2:
The problem with this solution is that the first and the last item will never be horizontally centered as selection.
This is probably because your RecycleView is responsible for showing, within its layout bounds, exactly the number of items that are inside of your data set.
In the example image you provided, you can achieve that effect by adding a "placeholder" item in the first and last position of your dataset. This way, you can have an invisible item taking up the first slot, thus offsetting the item you want to be centered.
This placeholder item should not respond to touch events and should not interfere with handling of click events on other items (specifically, the position handling).
You will have to modify your adapters getItemCount
and perhaps getItemType
.
Solution 3:
Just add padding on RecyclerView
and add clipToPadding=false
and it'll only affect the items on the ends.
Solution 4:
I ended up with this implementation in my project. You can pass different dimension in constructor to set the spacing between the items. As I wrote in the class' KDoc, it will add (total parent space - child width) / 2
to the left of first and to the right of last item in order to center first and last items.
import android.graphics.Rect
import android.view.View
import androidx.annotation.DimenRes
import androidx.recyclerview.widget.OrientationHelper
import androidx.recyclerview.widget.RecyclerView
/**
* Adds (total parent space - child width) / 2 to the left of first and to the right of last item (in order to center first and last items),
* and [spacing] between items.
*/internalclassOffsetItemDecorationconstructor(
@DimenResprivateval spacing: Int,
) : RecyclerView.ItemDecoration() {
overridefungetItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State,
) {
val itemPosition: Int = parent.getChildAdapterPosition(view)
if (itemPosition == RecyclerView.NO_POSITION) returnval spacingPixelSize: Int = parent.context.resources.getDimensionPixelSize(spacing)
when (itemPosition) {
0 ->
outRect.set(getOffsetPixelSize(parent, view), 0, spacingPixelSize / 2, 0)
parent.adapter!!.itemCount - 1 ->
outRect.set(spacingPixelSize / 2, 0, getOffsetPixelSize(parent, view), 0)
else ->
outRect.set(spacingPixelSize / 2, 0, spacingPixelSize / 2, 0)
}
}
privatefungetOffsetPixelSize(parent: RecyclerView, view: View): Int {
val orientationHelper = OrientationHelper.createHorizontalHelper(parent.layoutManager)
return (orientationHelper.totalSpace - view.layoutParams.width) / 2
}
}
Solution 5:
An improvement on @I.S answer which works 100% of the time and is very easy to implement without any glitchy animation. First we have to use PagerSnapHelper()
to have view pager like scroll. To center the items you need to add a large padding on the recyclerView and then clip to the padding. Then use a customized LinearSmoothScroller
to smoothly center your item. To center the item on load, just use smooth scroll to position 0. Below is the code
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_selection"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:paddingLeft="150dp"
android:paddingRight="150dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_selection_alert"
app:layout_constraintBottom_toBottomOf="@+id/guideline_1"
android:clipToPadding="false"
android:background="@drawable/bg_stat"/>
And in Code (in C#)
RecyclerView.LayoutManager lm = newLinearLayoutManager(Context, LinearLayoutManager.Horizontal, false);
recycler_selection = view.FindViewById<RecyclerView>(Resource.Id.recycler_selection);
recycler_selection.SetLayoutManager(newLinearLayoutManager(Context, LinearLayoutManager.Horizontal, false));
// <Set Adapter to the Recycler>
RecyclerView.SmoothScroller smoothScroller = newCenterScroller(recycler_selection.Context);
SnapHelper helper = newPagerSnapHelper();
helper.AttachToRecyclerView(recycler_selection);
smoothScroller.TargetPosition = 0;
lm.StartSmoothScroll(smoothScroller);
publicclassCenterScroller : LinearSmoothScroller
{
float MILLISECONDS_PER_INCH = 350f;
publicCenterScroller(Context context) : base(context)
{
}
publicoverrideintCalculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference){
return (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2);
}
protectedoverridefloatCalculateSpeedPerPixel(DisplayMetrics displayMetrics){
return MILLISECONDS_PER_INCH / displayMetrics.Xdpi;
}
}
Post a Comment for "Horizontally Center First Item Of Recyclerview"