2015-03-07 13 views
12

Utilizzo RecyclerView con StaggeredGridLayoutManager per creare un elenco a due colonne. Ma come impostare un margine destro tra la colonna di sinistra e la colonna di destra. Ho usato questo codice per creare il margine destro dall'alto, ma come risolvere il doppio spazio tra le colonne.Come evitare il doppio spazio tra gli elementi quando si utilizza RecyclerView con StaggeredGridLayoutManager?

public class SpacesItemDecoration extends RecyclerView.ItemDecoration { 
    private int space; 

    public SpacesItemDecoration(int space) { 
     this.space = space; 
    } 

    @Override 
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { 
     outRect.left = space; 
     outRect.right = space; 
     outRect.bottom = space; 

     // Add top margin only for the first or second item to avoid double space between items 
     // Add top margin only for the first or second item to avoid double space between items 
     if((parent.getChildCount() > 0 && parent.getChildPosition(view) == 0) 
      || (parent.getChildCount() > 1 && parent.getChildPosition(view) == 1)) 
     outRect.top = space; 
} 

E in attività:

recyclerView.addItemDecoration(new SpacesItemDecoration(20)); 

Ho cercato di usare view.getX(), si ritorna sempre 0.

Qualcuno mi può aiutare? Grazie molto!

risposta

3

Ho risolto io stesso impostando il margine dell'articolo e il riempimento di RecyclerView. Sia il margine che il riempimento sono la metà dello spazio previsto, quindi il problema è scomparso.

6

Il codice seguente gestirà StaggeredGridLayoutManager, GridLayoutManager e LinearLayoutManager.

public class SpacesItemDecoration extends RecyclerView.ItemDecoration { 

    private int halfSpace; 

    public SpacesItemDecoration(int space) { 
     this.halfSpace = space/2; 
    } 

    @Override 
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { 

     if (parent.getPaddingLeft() != halfSpace) { 
      parent.setPadding(halfSpace, halfSpace, halfSpace, halfSpace); 
      parent.setClipToPadding(false); 
     } 

     outRect.top = halfSpace; 
     outRect.bottom = halfSpace; 
     outRect.left = halfSpace; 
     outRect.right = halfSpace; 
    } 
} 
7

Nel tuo caso è possibile impostare il margine sia al RecyclerView .Ma nel mio caso c'è un'immagine corrisponde alla larghezza dello schermo nella RecyclerView, e io uso l'ItemDecoration per risolvere il problema.

class ViewItemDecoration extends RecyclerView.ItemDecoration { 

    public ViewItemDecoration() { 
    } 

    @Override 
    public void getItemOffsets(Rect outRect, final View view, final RecyclerView parent, RecyclerView.State state) { 
     super.getItemOffsets(outRect, view, parent, state); 
     int position = parent.getChildAdapterPosition(view); 
     int spanIndex = ((StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams()).getSpanIndex(); 
     int type = adapter.getItemViewType(position); 
     switch(type){ 
      case YOUR_ITEMS: 
       if (spanIndex == 0) { 
        outRect.left = 10; 
        outRect.right = 5; 
       } else {//if you just have 2 span . Or you can use (staggeredGridLayoutManager.getSpanCount()-1) as last span 
        outRect.left = 5; 
        outRect.right = 10; 
       } 
     } 
    } 

} 
0

avrei un po 'cambiare e modificare sia la risposta per la domanda relativa

public class SpacesItemDecoration extends RecyclerView.ItemDecoration { 
    private final int mSpace; 

    public SpacesItemDecoration(int space) { 
     this.mSpace = space; 
    } 

    @Override 
    public void getItemOffsets(Rect outRect, final View view, final RecyclerView parent, RecyclerView.State state) { 
     super.getItemOffsets(outRect, view, parent, state); 
     int position = parent.getChildAdapterPosition(view); 
     int spanIndex = ((StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams()).getSpanIndex(); 
     if (spanIndex == 0) { 
      outRect.left = 30; 
      outRect.right = 15; 
     } else {//if you just have 2 span . Or you can use (staggeredGridLayoutManager.getSpanCount()-1) as last span 
      outRect.left = 15; 
      outRect.right = 30; 
     } 
     outRect.bottom = 30; 
     // Add top margin only for the first item to avoid double space between items 
     if (parent.getChildAdapterPosition(view) == 0) { 
      outRect.top = 30; 
      outRect.right = 30; 
     } 
    } 
} 
0

Impostare sinistra/giusto spazio diverso in ItemDecoration secondo lo spanindex funziona bene solo per la vista oggetto è fissata dimensioni. Se la vista oggetto contiene vista immagine imposta wrap_content in altezza, la vista oggetto può cambiare la posizione di span, ma l'indice di span non aggiornato come si desidera, il margine sarà un disastro.

Il mio modo è, utilizzando lo spazio simmetrico sinistra/destra per visualizzare l'elemento.

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    // init 
    recyclerView = (RecyclerView) rv.findViewById(R.id.img_waterfall); 
    layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); 
    recyclerView.setLayoutManager(layoutManager); 
    recyclerView.setAdapter(new MyAdapter(getContext())); 
    recyclerView.addItemDecoration(new SpacesItemDecoration(
     getResources().getDimensionPixelSize(R.dimen.space))); 
} 


private static class SpacesItemDecoration extends RecyclerView.ItemDecoration { 
    private final int space; 
    public SpacesItemDecoration(int space) { 
     this.space = space; 
    } 
    @Override 
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, 
           RecyclerView.State state) { 
     outRect.bottom = 2 * space; 
     int pos = parent.getChildAdapterPosition(view); 
     outRect.left = space; 
     outRect.right = space; 
     if (pos < 2) 
      outRect.top = 2 * space; 
    } 
} 

quindi impostare la stessa imbottitura per RecylerView (sinistra/destra) android: paddingLeft = "@ dimen/spazio" android: paddingRight = "@ dimen/spazio"

<android.support.v7.widget.RecyclerView 
     android:id="@+id/img_waterfall" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:paddingLeft="@dimen/space" 
     android:paddingRight="@dimen/space"/> 
0
public class EqualGapItemDecoration extends RecyclerView.ItemDecoration { 

    private int spanCount; 
    private int spacing; 

    public EqualGapItemDecoration(int spanCount, int spacing) { 
     this.spanCount = spanCount; 
     this.spacing = spacing; 
    } 

    @Override 
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { 

     StaggeredGridLayoutManager.LayoutParams layoutParams = (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams(); 

     if (layoutParams.isFullSpan()) { 
      outRect.set(0, 0, 0, 0); 
     } else { 
      int spanIndex = layoutParams.getSpanIndex(); 
      int layoutPosition = layoutParams.getViewLayoutPosition(); 
      int itemCount = parent.getAdapter().getItemCount(); 

      boolean leftEdge = spanIndex == 0; 
      boolean rightEdge = spanIndex == (spanCount - 1); 

      boolean topEdge = spanIndex < spanCount; 
      boolean bottomEdge = layoutPosition >= (itemCount - spanCount); 

      int halfSpacing = spacing/2; 

      outRect.set(
        leftEdge ? spacing : halfSpacing, 
        topEdge ? spacing : halfSpacing, 
        rightEdge ? spacing : halfSpacing, 
        bottomEdge ? spacing : 0 
      ); 
     } 
    } 
}