2016-01-29 14 views
6

Desidero animare la modifica del mio RecyclerView s GridLayoutManager. I defaulty mostrano un elenco di elementi in una griglia con 3 colonne e l'utente può selezionare di mostrare più o meno colonne.RecyclerView - modifica animata delle colonne del gestore della griglia

Vorrei lo views nello RecyclerView per spostarlo/ridimensionarlo nelle loro nuove posizioni, ma non ho idea di come ciò possa essere fatto.

Quello che voglio alla fine

  • permettono di scalare la griglia tramite un espandere/contratto di tocco gesto => So come fare
  • animare il cambiamento del LayoutManager

Qualcuno sa come posso animare il cambio di LayoutManager?

+0

si poteva guardare in un simile [domanda] (http://stackoverflow.com/questions/26539663/how-do-i-use-a-gridlayoutanimation-in-a-recyclerview) e il relativo [ gist] (https://gist.github.com/Musenkishi/8df1ab549857756098ba) – Droidekas

+0

Quindi chiamare 'setSpanCount' seguito da' notifyDatasetChanged() '? – Droidekas

+0

un altro modo in cui posso vedere che si sta facendo presuppone un conteggio di span molto elevato (circa 100) e sul gesto degli oggetti, è possibile modificare la dimensione di span per tutti gli articoli – Droidekas

risposta

11

La fonte di ispirazione qui sarebbe l'app Google, lo stock Galleria Sony app

Ci sono fondamentalmente due approcci si può andare con:

  1. Si modifica lo spancount del GridLayoutManager utilizzando setSpanCount(int)

  2. È possibile impostare un conteggio di span molto alto (~ 100) utilizzando lo SpanSizeLookUp per modificare l'elemento per spanSize al volo.

    • Ho usato il Gist fornito da Musenkishi, per this answer per fornire un animatore animare i cambiamenti nel layout griglia cambia
    • Ho usato questo approccio in sample GitHub project attuazione della stessa.
    • Avvertenze:
      • ho attualmente utilizzato il clic ascoltatore a mantenere la modifica delle dimensioni delle arco sguardo up.This potrebbe essere modificato a un ItemGestureListener per acquisire gli eventi di zoom pinch e cambiare di conseguenza.
      • è necessario determinare un modo per scegliere un conteggio arco in modo che tutti gli elementi in fila occupare l'intera larghezza dello schermo (e quindi non si vede uno spazio vuoto)
      • Si chiama notifyItemRangeChanged utilizzando un post eseguibile ritardata dal non è possibile chiamare i metodi notifyChanged da bindView/createView ecc.
      • Dopo aver modificato la dimensione arco, è necessario notifyItemRangeChanged con una gamma appropriata in modo che tutti gli elementi attualmente visualizzati sullo schermo sono spostati accordingly.I hanno utilizzato (codice in basso)

Questa non è una soluzione completa ma una soluzione di 2 ore per lo stesso.È ovviamente possibile migliorare su tutti i punti menzionati :). Spero di continuare ad aggiornare il campione poiché questo tipo di visualizzazioni mi ha sempre affascinato. Non considerarlo come la soluzione finale ma solo un modo particolare per raggiungere questo approccio. Se invece dovessi utilizzare StaggerredLayoutManager, potresti facilmente evitare spazi vuoti tra gli elementi.

public int calculateRange() { 
    int start = ((GridLayoutManager)  grv.getLayoutManager()).findFirstVisibleItemPosition(); 
    int end = ((GridLayoutManager) grv.getLayoutManager()).findLastVisibleItemPosition(); 
    if (start < 0) 
     start = 0; 
    if (end < 0) 
     end = getItemCount(); 
    return end - start; 
    } 
+1

Grazie per questa soluzione (molto più facile di quanto pensassi). Cambiare il conteggio dello span (avrei potuto pensarci anch'io) è la strada da percorrere per IMHO. Si anima abbastanza bene. E dopo averlo modificato, basta chiamare gli adattatori 'notifyItemRangeChanged' per avviare correttamente l'animazione ... L'unico svantaggio è (ma non ho chiesto di più nella mia domanda), devi solo usare' GridLayoutManager' e non puoi passare diversi 'LayoutManager' ... Anche se, se lo si desidera,' GridLayoutManager' supporta anche 1 colonna e quindi può essere almeno utilizzato come 'LinearLayoutManager' ... – prom85

+1

Se si desidera veramente attenuare il animazioni di più e migliorare le prestazioni per i layout a colonna singola, consiglierei di lavorare sulla costruzione del proprio gestore di layout: [This] (http://wiresareobsolete.com/2014/09/building-a-recyclerview-layoutmanager-part-1/) la guida è abbastanza buona. – Droidekas

+0

@Droidekas puoi aiutarmi a creare quell'animazione su Android 7 impostazioni rapide? (succede alle tessere rapide quando espandi la sfumatura - si trovano in una singola riga di elementi e quindi si espandono in una griglia di 3x3.) –

1

Ho a che fare con lo stesso problema, e finora non ho trovato una buona soluzione.

Il semplice cambio di numero di colonne in GridLayoutManager sembra strano quindi per ora uso l'animazione per dissolvenza in apertura/in tutto il layout. Qualcosa di simile a questo:

private void animateRecyclerLayoutChange(final int layoutSpanCount) { 
    Animation fadeOut = new AlphaAnimation(1, 0); 
    fadeOut.setInterpolator(new DecelerateInterpolator()); 
    fadeOut.setDuration(400); 
    fadeOut.setAnimationListener(new Animation.AnimationListener() { 
     @Override 
     public void onAnimationStart(Animation animation) { 
     } 

     @Override 
     public void onAnimationRepeat(Animation animation) { 
     } 

     @Override 
     public void onAnimationEnd(Animation animation) { 
      productsRecyclerLayoutManager.setSpanCount(layoutSpanCount); 
      productsRecyclerLayoutManager.requestLayout(); 
      Animation fadeIn = new AlphaAnimation(0, 1); 
      fadeIn.setInterpolator(new AccelerateInterpolator()); 
      fadeIn.setDuration(400); 
      productsRecycler.startAnimation(fadeIn); 
     } 
    }); 
    productsRecycler.startAnimation(fadeOut); 
} 

Se si combinano fade out/in animazione con scalatura ogni elemento visibile, Sarà un'animazione decente per modifiche GridLayoutManager.

+0

Attualmente ho una soluzione simile ... Rimozione di tutti gli elementi, modifica il gestore del layout e l'aggiunta di tutti gli elementi produrrà anche un'animazione, ma non è perfetta neanche ... Grazie per questa alternativa però. – prom85

1

Si può fare questo con "rivelatore gesto" vedere il tutorial di esempio qui http://wiki.workassis.com/pinch-zoom-in-recycler-view/ In questo tutorial prendere le immagini dalla galleria e mostrare loro in un layout di griglia in vista riciclatore. Sarai in grado di cambiare il layout sul gesto di pizzicare. Di seguito sono riportate le schermate di diversi layout.

mScaleGestureDetector = new ScaleGestureDetector(this, new ScaleGestureDetector.SimpleOnScaleGestureListener() { 
       @Override 
       public boolean onScale(ScaleGestureDetector detector) { 
        if (detector.getCurrentSpan() > 200 && detector.getTimeDelta() > 200) { 
         if (detector.getCurrentSpan() - detector.getPreviousSpan() < -1) { 
          if (mCurrentLayoutManager == mGridLayoutManager1) { 
           mCurrentLayoutManager = mGridLayoutManager2; 
           mRvPhotos.setLayoutManager(mGridLayoutManager2); 
           return true; 
          } else if (mCurrentLayoutManager == mGridLayoutManager2) { 
           mCurrentLayoutManager = mGridLayoutManager3; 
           mRvPhotos.setLayoutManager(mGridLayoutManager3); 
           return true; 
          } 
         } else if(detector.getCurrentSpan() - detector.getPreviousSpan() > 1) { 
          if (mCurrentLayoutManager == mGridLayoutManager3) { 
           mCurrentLayoutManager = mGridLayoutManager2; 
           mRvPhotos.setLayoutManager(mGridLayoutManager2); 
           return true; 
          } else if (mCurrentLayoutManager == mGridLayoutManager2) { 
           mCurrentLayoutManager = mGridLayoutManager1; 
           mRvPhotos.setLayoutManager(mGridLayoutManager1); 
           return true; 
          } 
         } 
        } 
        return false; 
       } 
      }); 
Problemi correlati