2015-07-02 14 views
10

Quindi, sto affrontando uno strano problema mentre implementavo RecyclerView nel mio progetto. Ho un decoratore personalizzato per implementare un riempimento superiore e inferiore coerente e un valore piuttosto diverso di riempimento tra gli elementi. Ogni volta che tocchi l'aggiornamento, ovvero recupero i dati dal back-end e popolino nuovamente RecyclerView, il padding aumenta e continua ad aumentare ad ogni aggiornamento.Decoratore RecyclerView che aggiunge imbottitura aggiuntiva all'aggiornamento

This is the correct way

Quando mi ha colpito aggiornare (causando AsyncTask per eseguire di nuovo), lo spazio tra gli elementi aumentano. E continua ad aumentare con ogni aggiornamento.

Padding between items increasing

Ho un RecyclerView tipico come questo

<android.support.v7.widget.RecyclerView 
    android:id="@+id/recyclerview" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:clickable="false" 
    android:focusableInTouchMode="false"> 
</android.support.v7.widget.RecyclerView> 

popolamento contenuto all'interno RecyclerView è CardView con la seguente disposizione:

<android.support.v7.widget.CardView 
xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="wrap_content" 
android:id="@+id/cv" 
android:layout_marginLeft="9dp" 
android:layout_marginRight="9dp" 
> 

    <RelativeLayout 
     android:id="@+id/itemLinearTop" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:orientation="horizontal" 
     android:paddingTop="17dp" 
     android:paddingRight="10dp" 
     android:paddingLeft="10dp"> 

     <TextView 
      android:id="@+id/tv1" 
      android:textColor="@color/logo_black" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:textAppearance="?android:attr/textAppearanceMedium" /> 


     <TextView 
      android:id="@+id/tv2" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_alignBaseline="@+id/tv1" 
      android:textColor="@color/logo_black" 
      android:layout_alignParentRight="true" 
      android:textAppearance="?android:attr/textAppearanceMedium" /> 

     <!-- More elements --> 
    </RelativeLayout> 
</android.support.v7.widget.CardView> 

sto inizializzazione e popolando RecyclerView in questo modo:

// In PostExecute of AsyncTask 
RecyclerView rv = (RecyclerView) rootView.findViewById(R.id.recyclerview); 
RecycleViewAdapter adapter = new FuelPricesRecycleViewAdapter(data); 
rv.setAdapter(adapter); 
rv.addItemDecoration(new RecyclerViewItemDecoration(30, item_count - 1)); 

E questo è ciò che la mia classe RecyclerViewItemDecoration assomiglia:

public class RecyclerViewItemDecoration extends RecyclerView.ItemDecoration { 
    private int space = 0; 
    private int item_count = 0; 
    private int ADDITIONAL_PADDING = 20; 

    public RecyclerViewItemDecoration(int space, int item_count) { 
     this.space = space; 
     this.item_count = item_count; 
    } 

    @Override 
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { 
     if(parent.getChildPosition(view) != item_count) 
      outRect.bottom = space; 

     // Add top margin only for the first item to avoid double space between items 
     if(parent.getChildPosition(view) == 0) 
      outRect.top = space + ADDITIONAL_PADDING; 
     if(parent.getChildPosition(view) == item_count) 
      outRect.bottom = space + ADDITIONAL_PADDING; 
    } 
} 

Grazie per il vostro aiuto!

+0

qualcosa che hai trovato? – codevscolor

+0

Quasi un anno dopo, sto affrontando lo stesso problema, si chiama RecyclerView.scrollToPosition() dopo l'aggiornamento? – Fraid

+0

Ehi, hai trovato una soluzione? Attualmente sto chiamando 'adapter.notifyItemRangeChanged (0, adapter.getItemCount(), emptyList());' come soluzione alternativa.Ciò invaliderà tutti gli elementi senza riconciliare le viste perché c'è un payload. (il carico utile può essere qualsiasi oggetto non nullo). Mi piacerebbe ancora trovare un modo migliore. –

risposta

4

Si aggiunge Decoration ogni volta che viene riciclato il panorama di riciclaggio.

Utilizzare una bandiera invece:

private flagDecoration = false; 

if(!flagDecoration) 
{ 
    rv.addItemDecoration(new RecyclerViewItemDecoration(30, item_count - 1)); 
    flagDecoration = true;  
} 
+0

No, non ha funzionato. –

+0

Ho usato questo file di decorazione: https://gist.github.com/alexfu/0f464fc3742f134ccd1e – codevscolor

5

è necessario rimuovere la decorazione elemento prima di resettare i nuovi dati.

rv.removeItemDecoration(yourDecorator)

Fammi sapere se funziona!

+0

Questo ha risolto il mio problema, grazie ^^ – devchimp

0

stavo affrontando lo stesso problema, la soluzione migliore è quella di rendere la vostra decorazione elemento mentre vostro stanno inizializzazione del gestore di layout nel supporto vista, questo risolve il problema che si trovano ad affrontare esempio

public class GridViewHolder extends ViewHolder { 

    RecyclerView grid_list; 

    public GridViewHolder(View v) { 
     super(v); 
     this.grid_list = (RecyclerView) v.findViewById(R.id.home_screen_item_grid_recycler_view); 
     if (grid_list.getLayoutManager() == null) { 
      RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(context, 4); 
      grid_list.setLayoutManager(mLayoutManager); 
      grid_list.addItemDecoration(new GridSpacingItemDecoration(4, 3, false)); 
     } 
    } 
} 
1

Di fronte alla stesso problema e risolto posizionando

mLayoutManager = new LinearLayoutManager(current_activity); 
recyclerView.setLayoutManager(mLayoutManager); 

in onPreExecute() metodo.

Basta fare un tentativo se funziona

0

mi trovo di fronte lo stesso problema. Risolvilo con if check

if (recyclerView.getItemDecorationAt(0) == null) { // check decoration here 
     FlexboxItemDecoration agentDividerItemDecoration = new FlexboxItemDecoration(rv.getContext()); 
     agentDividerItemDecoration.setDrawable(recyclerView.getContext().getResources().getDrawable(R.drawable.shape_divider_flex_normal)); 
     recyclerView.addItemDecoration(agentDividerItemDecoration); 
    } else { 
     Log.i(TAG, "initTagsView: ItemDecoration not null"); 
    }