Сделайте так, чтобы последний элемент RecyclerView заполнял пробелы в RecyclerView (если число данных нечетное)
2 ответа
Мне нужно сделать это Grid как список
Вы можете достичь этого, используя RecyclerView
с GridLayoutManager
, Например,
// Initialize the view
recyclerView=(RecyclerView)findViewById(R.id.recyclerView);
// Here 2 is the number of columns
GridLayoutManager llm = new GridLayoutManager(this, 2);
recyclerView.setLayoutManager(llm);
recyclerView.setHasFixedSize(true);
Мне нужен последний элемент, чтобы заполнить оба пробела, если последний элемент "один"
Чтобы настроить элементы сетки, мы можем использовать ItemDecoration
, И в вашем случае последний элемент, если он один, должен иметь родительскую ширину. Мы можем добиться этого, проверив позицию последнего элемента.
Теперь код:
В деятельности
recyclerView=(RecyclerView)findViewById(R.id.recyclerView);
GridLayoutManager llm = new GridLayoutManager(this, 2);
recyclerView.setLayoutManager(llm);
recyclerView.setHasFixedSize(true);
recyclerView.addItemDecoration(new GridItemDecoration());
// And set adapter
GridItemDecoration.java
public class GridItemDecoration extends RecyclerView.ItemDecoration
{
private int mHorizontalSpacing = 10;
private int mVerticalSpacing = 10;
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state)
{
super.getItemOffsets(outRect, view, parent, state);
// Only handle the vertical situation
int position = parent.getChildPosition(view);
if (parent.getLayoutManager() instanceof GridLayoutManager)
{
GridLayoutManager layoutManager = (GridLayoutManager) parent.getLayoutManager();
int spanCount, column;
// Check the last item and is alone. Then set the parent's width
if (position == parent.getAdapter().getItemCount() - 1 && position % 2 == 0)
{
spanCount = 1;
outRect.left = mHorizontalSpacing;
outRect.right = parent.getWidth() - mHorizontalSpacing;
}
else
{
spanCount = layoutManager.getSpanCount();
column = position % spanCount;
outRect.left = mHorizontalSpacing * (spanCount - column) / spanCount;
outRect.right = mHorizontalSpacing * (column + 1) / spanCount;
}
if (position < spanCount)
{
outRect.top = mVerticalSpacing;
}
outRect.bottom = mVerticalSpacing;
}
}
}
Для установки другого количества диапазонов вы можете использовать
GridLayoutManager
стандартная функция
setSpanSizeLookup
.
Эта реализация в Kotlin для заполнения ширины экрана на последнем элементе:
// Count of columns (I set it in integer resources for screen optimisation)
val spanCount = resources.getInteger(R.integer.column_count)
val layoutManager = GridLayoutManager(context, spanCount)
layoutManager.spanSizeLookup = object : SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
val isLastItem = position == adapter.getItemList().lastIndex
return if (isLastItem) {
/**
* Return this for full width of screen.
* It will be always equal 1, dividing only to avoid numbers in code.
*/
spanCount / spanCount
} else {
// Return this for place item in your column.
spanCount
}
}
}
Также, если у вас сложный адаптер с большим количеством элементов, вы можете использовать эту реализацию, например:
val spanCount = resources.getInteger(R.integer.column_count_profile)
val layoutManager = GridLayoutManager(context, spanCount)
layoutManager.spanSizeLookup = object : SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
val item = adapter.getItemList().getOrNull(position) ?: return spanCount
return when (item) {
is ScreenItem.Header -> spanCount
is ScreenItem.Status -> spanCount
is ScreenItem.Progress -> spanCount
is ScreenItem.Empty -> spanCount
is ScreenItem.Item -> spanCount / spanCount
is ScreenItem.Load -> spanCount / spanCount
}
}
}
Где
ScreenItem
является
sealed class
, внутри которого что-то вроде этого:
sealed class ScreenItem{
object Header : ScreenItem()
data class Status(var content: ContentItem) : ScreenItem()
object Progress : ScreenItem()
object Empty : ScreenItem()
data class Item(val content: AnotherContentItem) : ScreenItem()
object Load : ScreenItem()
}