Добавить место до конца RecyclerView

У меня есть recyclerview с gridlayout. Я хочу, когда пользователь прокручивается до конца списка (см. Мой плохой макет), должно быть пустое пространство с высотой 50 дп, что не является" t те же размеры, что и моя сетка.

Обратите внимание, что это пространство отображается только в самом конце, так как я не хочу менять макет. Я мог бы сделать так, чтобы у recycerview было поле с датой 50dp, но я не хочу этого делать.

<?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>

Ответы

Ответ 1

Это лучше всего достигается с помощью украшения элемента.

Вот пример, который работает с LinearLayoutManager - вам нужно будет настроить его для макета сетки. То, что он делает, проверяет каждый элемент, чтобы увидеть, последний ли он, и если он добавляет смещение к нижней части. Для макета сетки сложная часть выясняет, находится ли ваша позиция позиции в последней строке или нет.

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

    }
}

Для GridLayoutManager, внутри метода getItemOffsets вы можете сделать что-то похожее на это, чтобы выяснить, является ли это последней строкой:

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

Ответ 2

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

Ответ 3

Вы можете попробовать приведенный ниже код, помните "я не тестирую этот код"

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

и в макете:

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

Ответ 4

android: clipToPadding = "false" сэкономит много и много времени без какой-либо строки кода!

<android.support.v7.widget.RecyclerView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:paddingBottom="72dp"
                android:clipToPadding="false"
                android:paddingTop="@dimen/generalPadding"
                android:scrollbars="vertical" />