Decorare RecyclerView (con GridLayoutManager) per visualizzare il divisore tra gli elementi

Qual è il modo migliore e più semplice per decorare RecyclerView per avere un aspetto simile?

immettere qui la descrizione dell'immagine

  • Come utilizzare il caricatore di immagini universale nella cache offline?
  • Come faccio a visualizzare DrawerLayout sotto la barra degli strumenti?
  • Come posso assicurarmi che la mia app sostenga la versione minima di Google Play Services 4.1?
  • Errore di progettazione su SAAgent.class
  • Android - i parametri HttpURLConnection da Map <String, Object> tramite il metodo POST
  • Sincronizzazione di foto nella galleria Android
  • La principale sfida qui è avere divisori solo tra gli elementi, ma non tra gli elementi ei bordi sinistro / destro dello schermo.

    Qualche idea?

  • Come get la posizione esatta in Android senza connessione a Internet?
  • Problemi di debug (Android Eclipse)
  • Come posso registrare la mia applicazione su Android per gestire un "tipo" di codice QR?
  • ndk-build: undefined riferimento a .. errori quando si legano staticamente a libxml.a
  • WebView WebRTC non funziona
  • Vista di ViewPager + RecyclerView in android
  • 4 Solutions collect form web for “Decorare RecyclerView (con GridLayoutManager) per visualizzare il divisore tra gli elementi”

    Non so perché lo abbiate bisogno, ma questo UI è molto semplice da implementare con il decoratore di RecyclerView.

    mRecylerView.addItemDecoration(new ItemDecorationAlbumColumns( getResources().getDimensionPixelSize(R.dimen.photos_list_spacing), getResources().getInteger(R.integer.photo_list_preview_columns))); 

    e decoratore (ha bisogno di qualche rifacimento)

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

    immettere qui la descrizione dell'immagineimmettere qui la descrizione dell'immagine

    Puoi get la tua risposta, ma sto ancora pubblicando la mia soluzione che può aiutare gli altri. Questo può essere utilizzato per liste verticali, orizzontali o griglia, passando l'orientamento.

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

    Una soluzione più semplice che ha funzionato per me. Spero che possa essere utile.

     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 } } 
    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.