Voeg spatie toe aan het einde van de RecyclerView

Ik heb een recyclerview met een gridlayout. Wat ik wil is dat wanneer de gebruiker naar het einde van de lijst scrolt (zie mijn slechte mockup), er een lege ruimte met een hoogte van 50 dp, wat niet dezelfde afmetingen heeft als mijn raster.

Houd er rekening mee dat deze ruimte alleen helemaal aan het einde zichtbaar is, omdat ik de lay-out niet wil veranderen. Ik zou het zo kunnen maken dat de recycerview een marge heeft van 50 dp, maar dat wil ik niet.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:fab="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <android.support.v7.widget.RecyclerView
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity"
        android:scrollbars="vertical"
        />
</RelativeLayout>

Antwoord 1, autoriteit 100%

<RecyclerView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="50dp"
    android:clipToPadding="false"
    />

Antwoord 2, autoriteit 27%

Dit wordt het best bereikt met een itemdecoratie.

Hier is een voorbeeld dat werkt met een LinearLayoutManager– u moet het aanpassen aan uw rasterlay-out. Wat het doet, is elk item controleren om te zien of het het laatste is, en als dat het geval is, wordt de offset onderaan toegevoegd. Voor een rasterlay-out is het moeilijk om uit te zoeken of uw itempositie in de laatste rij staat of niet.

// After setting layout manager, adapter, etc...
float offsetPx = getResources().getDimension(R.dimen.bottom_offset_dp);
BottomOffsetDecoration bottomOffsetDecoration = new BottomOffsetDecoration((int) offsetPx);
mRecyclerView.addItemDecoration(bottomOffsetDecoration);
...
static class BottomOffsetDecoration extends RecyclerView.ItemDecoration {
    private int mBottomOffset;
    public BottomOffsetDecoration(int bottomOffset) {
        mBottomOffset = bottomOffset;
    }
    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        int dataSize = state.getItemCount();
        int position = parent.getChildAdapterPosition(view);
        if (dataSize > 0 && position == dataSize - 1) {
            outRect.set(0, 0, 0, mBottomOffset);
        } else {
            outRect.set(0, 0, 0, 0);
        }
    }
}

Voor een GridLayoutManagerkunt u binnen de methode getItemOffsetsiets soortgelijks doen om erachter te komen of dit de laatste rij is:

GridLayoutManager grid = (GridLayoutManager)parent.getLayoutManager();
if ((dataSize - position) <= grid.getSpanCount()) {
    outRect.set(0, 0, 0, mBottomOffset);
} else {
    outRect.set(0, 0, 0, 0);
}

Antwoord 3, autoriteit 4%

Ik had hetzelfde probleem. Na het lezen van alle andere antwoorden en ik ontdekte dat de wijzigingen in lay-out xml voor recyclerview voor mijn recyclerview werkten zoals verwacht:

       android:paddingBottom="127px"
        android:clipToPadding="false"
        android:scrollbarStyle="outsideOverlay"  

De volledige lay-out ziet er als volgt uit:

<android.support.v7.widget.RecyclerView
        android:id="@+id/library_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="160px"
        android:layout_marginEnd="160px"
        tools:listitem="@layout/library_list_item" />  

Voor het effect van voor en na zie de link op androidblog.us:
Ruimte toevoegen aan einde van Android Recylerview
Laat me weten hoe het voor jou werkt.

David


Antwoord 4

U kunt de onderstaande code proberen, onthoud “Ik test deze code niet”

public class MyRecyclerView extends RecyclerView {
    private Context context;
    public MyRecyclerView(Context context) {
        super(context);
        this.context = context;
    }
    public MyRecyclerView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
    }
    public MyRecyclerView(Context context, AttributeSet attrs, int defStyle)     {
        super(context, attrs, defStyle);
        this.context = context;
    }
    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        View view = (View) getChildAt(getChildCount()-1);
        int diff = (view.getBottom()-(getHeight()+getScrollY()+view.getTop()));
        if( diff == 0 ){  // if diff is zero, then the bottom has been reached
            TextView tv = new TextView(context);
            tv.setHeight(dpToPx(50));
            addView(tv,getChildCount());//update --> add to last
            requestLayout();
        }
        super.onScrollChanged(l, t, oldl, oldt);
    }
    public int dpToPx(int dp) {
        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
        int px = Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
        return px;
    }
}

en in lay-out:

<your_packagae.MyRecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbars="vertical"
    />

Antwoord 5

Maak een klassenaam met BottomOffsetDecoration

public class BottomOffsetDecoration extends RecyclerView.ItemDecoration {
        private int mBottomOffset;
        public BottomOffsetDecoration(int bottomOffset) {
            mBottomOffset = bottomOffset;
        }
        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
            super.getItemOffsets(outRect, view, parent, state);
            int dataSize = state.getItemCount();
            int position = parent.getChildAdapterPosition(view);
            if (dataSize > 0 && position == dataSize - 1) {
                outRect.set(0, 0, 0, mBottomOffset);
            } else {
                outRect.set(0, 0, 0, 0);
            }
        }
    }

Voeg vervolgens deze regel toe na het toevoegen van adapter en layoutmanager aan recyclerview

float offsetPx = getResources().getDimension(R.dimen.bottom_offset_dp);
        BottomOffsetDecoration bottomOffsetDecoration = new BottomOffsetDecoration((int) offsetPx);
        rv.addItemDecoration(bottomOffsetDecoration);

en voor GridLayout Voeg deze regels toe na het toewijzen van recyclerview layout manager

GridLayoutManager grid = (GridLayoutManager)parent.getLayoutManager();
if ((dataSize - position) <= grid.getSpanCount()) {
    outRect.set(0, 0, 0, mBottomOffset);
} else {
    outRect.set(0, 0, 0, 0);
}

Other episodes