Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/208.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 装饰RecyclerView(使用GridLayoutManager)以显示项目之间的分隔符_Android_Android Recyclerview - Fatal编程技术网

Android 装饰RecyclerView(使用GridLayoutManager)以显示项目之间的分隔符

Android 装饰RecyclerView(使用GridLayoutManager)以显示项目之间的分隔符,android,android-recyclerview,Android,Android Recyclerview,什么是装饰RecyclerView的最好和最简单的方法,使其具有这样的外观和感觉 这里的主要挑战是仅在项目之间使用分隔符,而不是在项目和屏幕左/右边框之间使用分隔符 有什么想法吗?我不知道你为什么需要它,但是这个UI很容易用RecyclerView decorator实现 <!--Integer Value that number of column in RecyclerView--> <integer name="photo_list_preview_columns"&g

什么是装饰RecyclerView的最好和最简单的方法,使其具有这样的外观和感觉

这里的主要挑战是仅在项目之间使用分隔符,而不是在项目和屏幕左/右边框之间使用分隔符


有什么想法吗?

我不知道你为什么需要它,但是这个UI很容易用RecyclerView decorator实现

<!--Integer Value that number of column in RecyclerView-->
<integer name="photo_list_preview_columns">3</integer>

<!-- inter spacing between RecyclerView's Item-->
<dimen name="photos_list_spacing">10dp</dimen>
和装饰器(需要重新装饰)

导入android.graphics.Rect;
导入android.support.v7.widget.RecyclerView;
导入android.view.view;
公共类ItemDecorationAlbumColumns扩展了RecyclerView.ItemDecoration{
私有int mSizeGridSpacingPx;
私有int-mgridize;
私有布尔值mNeedLeftSpacing=false;
公共项decorationalBumColumns(int-gridSpacingPx,int-gridSize){
mSizeGridSpacingPx=gridSpacingPx;
mGridSize=gridSize;
}
@凌驾
public void getItemOffsets(Rect outRect、View View、RecyclerView父级、RecyclerView.State){
int frameWidth=(int)((parent.getWidth()-(float)mSizeGridSpacingPx*(mGridSize-1))/mGridSize);
int padding=parent.getWidth()/mGridSize-frameWidth;
int itemPosition=((RecyclerView.LayoutParams)view.getLayoutParams()).getViewAdapterPosition();
if(itemPosition

您可能已经得到了答案,但我仍在发布我的解决方案,以帮助其他人。这可以通过传递方向来用于垂直、水平列表或栅格视图

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;

public class DividerItemDecoration extends RecyclerView.ItemDecoration {

    private static final int[] ATTRS = new int[]{
            android.R.attr.listDivider
    };

    public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
    public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
    public static final int GRID = 2;

    private Drawable mDivider;

    private int mOrientation;

    public DividerItemDecoration(Context context, int orientation) {
        final TypedArray a = context.obtainStyledAttributes(ATTRS);
        mDivider = a.getDrawable(0);
        a.recycle();
        setOrientation(orientation);
    }

    public void setOrientation(int orientation) {
        if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST && orientation != GRID) {
            throw new IllegalArgumentException("invalid orientation");
        }
        mOrientation = orientation;
    }

    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        if (mOrientation == VERTICAL_LIST) {
            drawVertical(c, parent);
        } else if(mOrientation == HORIZONTAL_LIST){
            drawHorizontal(c, parent);
        } else {
            drawVertical(c, parent);
            drawHorizontal(c, parent);
        }
    }

    public void drawVertical(Canvas c, RecyclerView parent) {
        if (parent.getChildCount() == 0) return;

        final int left = parent.getPaddingLeft();
        final int right = parent.getWidth() - parent.getPaddingRight();

        final View child = parent.getChildAt(0);
        if (child.getHeight() == 0) return;

        final RecyclerView.LayoutParams params =
                (RecyclerView.LayoutParams) child.getLayoutParams();
        int top = child.getBottom() + params.bottomMargin + mDivider.getIntrinsicHeight();
        int bottom = top + mDivider.getIntrinsicHeight();

        final int parentBottom = parent.getHeight() - parent.getPaddingBottom();
        while (bottom < parentBottom) {
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);

            top += mDivider.getIntrinsicHeight() + params.topMargin + child.getHeight() + params.bottomMargin + mDivider.getIntrinsicHeight();
            bottom = top + mDivider.getIntrinsicHeight();
        }
    }

    public void drawHorizontal(Canvas c, RecyclerView parent) {
        final int top = parent.getPaddingTop();
        final int bottom = parent.getHeight() - parent.getPaddingBottom();

        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params =
                    (RecyclerView.LayoutParams) child.getLayoutParams();
            final int left = child.getRight() + params.rightMargin + mDivider.getIntrinsicHeight();
            final int right = left + mDivider.getIntrinsicWidth();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        if (mOrientation == VERTICAL_LIST) {
            outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
        } else if(mOrientation == HORIZONTAL_LIST) {
            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
        } else {
            outRect.set(0, 0, mDivider.getIntrinsicWidth(), mDivider.getIntrinsicHeight());
        }
    }
}
导入android.content.Context;
导入android.content.res.TypedArray;
导入android.graphics.Canvas;
导入android.graphics.Rect;
导入android.graphics.drawable.drawable;
导入android.support.v7.widget.LinearLayoutManager;
导入android.support.v7.widget.RecyclerView;
导入android.view.view;
公共类DividerItemDecoration扩展了RecyclerView.ItemDecoration{
私有静态最终整数[]属性=新整数[]{
android.R.attr.listDivider
};
public static final int HORIZONTAL_LIST=LinearLayoutManager.HORIZONTAL;
public static final int VERTICAL_LIST=LinearLayoutManager.VERTICAL;
公共静态最终整数网格=2;
专用可抽出式mDivider;
私人托管;
公共DividerItemDecoration(上下文,int方向){
最终类型Darray a=上下文。获取样式属性(属性);
mDivider=a.getDrawable(0);
a、 回收();
定向(定向);
}
公共方向(整数方向){
如果(方向!=水平列表和方向!=垂直列表和方向!=网格){
抛出新的IllegalArgumentException(“无效方向”);
}
朝气=方向;
}
@凌驾
公共void onDrawOver(画布c、RecyclerView父级、RecyclerView.State){
if(morentation==垂直列表){
(c)父母;
}else if(Morentation==水平列表){
水平拉伸(c,母材);
}否则{
(c)父母;
水平拉伸(c,母材);
}
}
公共void drawVertical(画布c、回收视图父对象){
如果(parent.getChildCount()==0)返回;
final int left=parent.getPaddingLeft();
final int right=parent.getWidth()-parent.getPaddingRight();
最终视图子对象=父对象。getChildAt(0);
如果(child.getHeight()==0)返回;
最终RecyclerView.LayoutParams参数=
(RecyclerView.LayoutParams)child.getLayoutParams();
int top=child.getBottom()+params.bottomMargin+mDivider.getIntrinsicHeight();
int bottom=top+mDivider.getIntrinsicHeight();
final int parentBottom=parent.getHeight()-parent.getPaddingBottom();
while(底部<底部){
mDivider.setBounds(左、上、右、下);
mDivider.draw(c);
top+=mDivider.getIntrinsicHeight()+params.topMargin+child.getHeight()+params.bottomMargin+mDivider.getIntrinsicHeight();
bottom=top+mDivider.getIntrinsicHeight();
}
}
公共void drawHorizontal(画布c,回收视图父对象){
final int top=parent.getPaddingTop();
final int bottom=parent.getHeight()-parent.getPaddingBottom();
final int childCount=parent.getChildCount();
for(int i=0;iimport android.graphics.Rect;
import android.support.v7.widget.RecyclerView;
import android.view.View;

public class ItemDecorationAlbumColumns extends RecyclerView.ItemDecoration {

    private int mSizeGridSpacingPx;
    private int mGridSize;

    private boolean mNeedLeftSpacing = false;

    public ItemDecorationAlbumColumns(int gridSpacingPx, int gridSize) {
        mSizeGridSpacingPx = gridSpacingPx;
        mGridSize = gridSize;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        int frameWidth = (int) ((parent.getWidth() - (float) mSizeGridSpacingPx * (mGridSize - 1)) / mGridSize);
        int padding = parent.getWidth() / mGridSize - frameWidth;
        int itemPosition = ((RecyclerView.LayoutParams) view.getLayoutParams()).getViewAdapterPosition();
        if (itemPosition < mGridSize) {
            outRect.top = 0;
        } else {
            outRect.top = mSizeGridSpacingPx;
        }
        if (itemPosition % mGridSize == 0) {
            outRect.left = 0;
            outRect.right = padding;
            mNeedLeftSpacing = true;
        } else if ((itemPosition + 1) % mGridSize == 0) {
            mNeedLeftSpacing = false;
            outRect.right = 0;
            outRect.left = padding;
        } else if (mNeedLeftSpacing) {
            mNeedLeftSpacing = false;
            outRect.left = mSizeGridSpacingPx - padding;
            if ((itemPosition + 2) % mGridSize == 0) {
                outRect.right = mSizeGridSpacingPx - padding;
            } else {
                outRect.right = mSizeGridSpacingPx / 2;
            }
        } else if ((itemPosition + 2) % mGridSize == 0) {
            mNeedLeftSpacing = false;
            outRect.left = mSizeGridSpacingPx / 2;
            outRect.right = mSizeGridSpacingPx - padding;
        } else {
            mNeedLeftSpacing = false;
            outRect.left = mSizeGridSpacingPx / 2;
            outRect.right = mSizeGridSpacingPx / 2;
        }
        outRect.bottom = 0;
    }
}
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;

public class DividerItemDecoration extends RecyclerView.ItemDecoration {

    private static final int[] ATTRS = new int[]{
            android.R.attr.listDivider
    };

    public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
    public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
    public static final int GRID = 2;

    private Drawable mDivider;

    private int mOrientation;

    public DividerItemDecoration(Context context, int orientation) {
        final TypedArray a = context.obtainStyledAttributes(ATTRS);
        mDivider = a.getDrawable(0);
        a.recycle();
        setOrientation(orientation);
    }

    public void setOrientation(int orientation) {
        if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST && orientation != GRID) {
            throw new IllegalArgumentException("invalid orientation");
        }
        mOrientation = orientation;
    }

    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        if (mOrientation == VERTICAL_LIST) {
            drawVertical(c, parent);
        } else if(mOrientation == HORIZONTAL_LIST){
            drawHorizontal(c, parent);
        } else {
            drawVertical(c, parent);
            drawHorizontal(c, parent);
        }
    }

    public void drawVertical(Canvas c, RecyclerView parent) {
        if (parent.getChildCount() == 0) return;

        final int left = parent.getPaddingLeft();
        final int right = parent.getWidth() - parent.getPaddingRight();

        final View child = parent.getChildAt(0);
        if (child.getHeight() == 0) return;

        final RecyclerView.LayoutParams params =
                (RecyclerView.LayoutParams) child.getLayoutParams();
        int top = child.getBottom() + params.bottomMargin + mDivider.getIntrinsicHeight();
        int bottom = top + mDivider.getIntrinsicHeight();

        final int parentBottom = parent.getHeight() - parent.getPaddingBottom();
        while (bottom < parentBottom) {
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);

            top += mDivider.getIntrinsicHeight() + params.topMargin + child.getHeight() + params.bottomMargin + mDivider.getIntrinsicHeight();
            bottom = top + mDivider.getIntrinsicHeight();
        }
    }

    public void drawHorizontal(Canvas c, RecyclerView parent) {
        final int top = parent.getPaddingTop();
        final int bottom = parent.getHeight() - parent.getPaddingBottom();

        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params =
                    (RecyclerView.LayoutParams) child.getLayoutParams();
            final int left = child.getRight() + params.rightMargin + mDivider.getIntrinsicHeight();
            final int right = left + mDivider.getIntrinsicWidth();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        if (mOrientation == VERTICAL_LIST) {
            outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
        } else if(mOrientation == HORIZONTAL_LIST) {
            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
        } else {
            outRect.set(0, 0, mDivider.getIntrinsicWidth(), mDivider.getIntrinsicHeight());
        }
    }
}
  @BindingAdapter({"bind:adapter"})
    public static void bind(RecyclerView view, RecyclerView.Adapter<BaseViewHolder> adapter) {
        view.setLayoutManager(new GridLayoutManager(view.getContext(), 3));
        view.addItemDecoration(new SpacesItemDecorationGrid(view.getContext(), 4, 3));
        view.setItemAnimator(new DefaultItemAnimator());
        view.setAdapter(adapter);
    }


public class SpacesItemDecorationGrid extends RecyclerView.ItemDecoration {

    private int mSizeGridSpacingPx;
    private int mGridSize;
    private boolean mNeedLeftSpacing = false;

    /**
     * @param gridSpacingPx
     * @param gridSize
     */
    SpacesItemDecorationGrid(Context context, int gridSpacingPx, int gridSize) {
        mSizeGridSpacingPx = (int) Util.convertDpToPixel(gridSpacingPx, context);
        mGridSize = gridSize;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        int frameWidth = (int) ((parent.getWidth() - (float) mSizeGridSpacingPx * (mGridSize - 1)) / mGridSize);
        int padding = parent.getWidth() / mGridSize - frameWidth;
        int itemPosition = ((RecyclerView.LayoutParams) view.getLayoutParams()).getViewAdapterPosition();
        int itemCount = parent.getAdapter().getItemCount() - mGridSize;


   /*     if (itemPosition < mGridSize) {
            outRect.top = mSizeGridSpacingPx;
        } else {
                   outRect.top = mSizeGridSpacingPx;
        }*/
        outRect.top = mSizeGridSpacingPx;
        if (itemPosition % mGridSize == 0) {
            outRect.left = mSizeGridSpacingPx;
            outRect.right = padding;
            mNeedLeftSpacing = true;
        } else if ((itemPosition + 1) % mGridSize == 0) {
            mNeedLeftSpacing = false;
            outRect.right = mSizeGridSpacingPx;
            outRect.left = padding;
        } else if (mNeedLeftSpacing) {
            mNeedLeftSpacing = false;
            outRect.left = mSizeGridSpacingPx - padding;
            if ((itemPosition + 2) % mGridSize == 0) {
                outRect.right = mSizeGridSpacingPx - padding;
            } else {
                outRect.right = mSizeGridSpacingPx / 2;
            }
        } else if ((itemPosition + 2) % mGridSize == 0) {
            mNeedLeftSpacing = false;
            outRect.left = mSizeGridSpacingPx / 2;
            outRect.right = mSizeGridSpacingPx - padding;
        } else {
            mNeedLeftSpacing = false;
            outRect.left = mSizeGridSpacingPx / 2;
            outRect.right = mSizeGridSpacingPx / 2;
        }
        if (itemPosition > itemCount) {
            outRect.bottom = mSizeGridSpacingPx;
        } else {
            outRect.bottom = 0;
        }

    }

}
class GridItemDecorator(val context: Context, private val spacingDp: Int, private val mGridSize: Int) : RecyclerView.ItemDecoration() {

    override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {

        val resources = context.resources
        val spacingPx = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, spacingDp.toFloat(), resources.displayMetrics)

        val bit = if (spacingPx > mGridSize) Math.round(spacingPx / mGridSize) else 1
        val itemPosition = (view.layoutParams as RecyclerView.LayoutParams).viewAdapterPosition

        outRect.top = if (itemPosition < mGridSize) 0 else  bit * mGridSize
        outRect.bottom = 0

        val rowPosition = itemPosition % mGridSize
        outRect.left = rowPosition * bit
        outRect.right = (mGridSize - rowPosition - 1) * bit

    }
}
public class MediaSpaceDecoration extends RecyclerView.ItemDecoration {
    private final int spacing;
    private final List<Integer> allowedViewTypes = Arrays.asList(
            R.layout.item_image,
            R.layout.item_blur);

    public MediaSpaceDecoration(int spacing) {
        this.spacing = spacing;
    }

    @Override
    public void getItemOffsets(Rect outRect,
                               View view,
                               RecyclerView parent,
                               RecyclerView.State state) {
        final int position = parent.getChildAdapterPosition(view);
        if (!isMedia(parent, position)) {
            return;
        }

        final int totalSpanCount = getTotalSpanCount(parent);
        int spanSize = getItemSpanSize(parent, position);
        if (totalSpanCount == spanSize) {
            return;
        }

        outRect.top = isInTheFirstRow(position, totalSpanCount) ? 0 : spacing;
        outRect.left = isFirstInRow(position, totalSpanCount) ? 0 : spacing / 2;
        outRect.right = isLastInRow(position, totalSpanCount) ? 0 : spacing / 2;
        outRect.bottom = 0; // don't need
    }

    private boolean isInTheFirstRow(int position, int spanCount) {
        return position < spanCount;
    }

    private boolean isFirstInRow(int position, int spanCount) {
        return position % spanCount == 0;
    }

    private boolean isLastInRow(int position, int spanCount) {
        return isFirstInRow(position + 1, spanCount);
    }

    private int getTotalSpanCount(RecyclerView parent) {
        final RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        return layoutManager instanceof GridLayoutManager
            ? ((GridLayoutManager) layoutManager).getSpanCount()
            : 1;
    }

    private int getItemSpanSize(RecyclerView parent, int position) {
        final RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        return layoutManager instanceof GridLayoutManager
            ? ((GridLayoutManager) layoutManager).getSpanSizeLookup().getSpanSize(position)
            : 1;
    }

    private boolean isMedia(RecyclerView parent, int viewPosition) {
        final RecyclerView.Adapter adapter = parent.getAdapter();
        final int viewType = adapter.getItemViewType(viewPosition);
        return allowedViewTypes.contains(viewType);
    }
}
import android.graphics.Rect
import android.view.View
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView

class GridDividerItemDecoration(private val spacing: Int) : RecyclerView.ItemDecoration() {

    override fun getItemOffsets(
        outRect: Rect,
        view: View,
        parent: RecyclerView,
        state: RecyclerView.State
    ) {
        val position = parent.getChildAdapterPosition(view)

        val totalSpanCount = getTotalSpanCount(parent)
        val spanSize = getItemSpanSize(parent, position)

        outRect.top = if (isInTheFirstRow(position, totalSpanCount)) 0 else spacing
        outRect.left = if (isFirstInRow(position, totalSpanCount, spanSize)) 0 else spacing / 2
        outRect.right = if (isLastInRow(position, totalSpanCount, spanSize)) 0 else spacing / 2
        outRect.bottom = 0
    }

    private fun isInTheFirstRow(position: Int, totalSpanCount: Int): Boolean =
        position < totalSpanCount

    private fun isFirstInRow(position: Int, totalSpanCount: Int, spanSize: Int): Boolean =
        if (totalSpanCount != spanSize) {
            position % totalSpanCount == 0
        } else true

    private fun isLastInRow(position: Int, totalSpanCount: Int, spanSize: Int): Boolean =
        isFirstInRow(position + 1, totalSpanCount, spanSize)

    private fun getTotalSpanCount(parent: RecyclerView): Int =
        (parent.layoutManager as? GridLayoutManager)?.spanCount ?: 1

    private fun getItemSpanSize(parent: RecyclerView, position: Int): Int =
        (parent.layoutManager as? GridLayoutManager)?.spanSizeLookup?.getSpanSize(position) ?: 1
}
class GridItemOffsetDecoration(private val spanCount: Int, private var mItemOffset: Int) : ItemDecoration() {

override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView,
                            state: RecyclerView.State) {
    val position = parent.getChildAdapterPosition(view)

    if (position < spanCount) {
        if (position % 2 == 0) { // left grid
            outRect.set(0, mItemOffset, mItemOffset / 2, mItemOffset / 2)
        } else { // right grid
            outRect.set(mItemOffset / 2, mItemOffset, 0, mItemOffset / 2)
        }

    } else if (position % 2 == 0) { // left grid
        outRect.set(0, mItemOffset / 2, mItemOffset, mItemOffset / 2)

    } else if (position % 2 == 1) { // right grid
        outRect.set(mItemOffset / 2, mItemOffset / 2, 0, mItemOffset / 2)

    } else {
        if (position % 2 == 0) { // left grid
            outRect.set(0, mItemOffset / 2, mItemOffset, mItemOffset)
        } else { // right grid
            outRect.set(mItemOffset / 2, mItemOffset / 2, 0, mItemOffset)
        }
    }
}
/*spanCount is the number of grids, for instance, (2 = 2*2 grid, 3 = 3*3)*/
binding.rvActiveChallenges.addItemDecoration(GridItemOffsetDecoration(2, resources.getDimensionPixelSize(R.dimen._10dp)))