2012-03-16 13 views
10

C'è un modo per aggiungere animazioni quando si apre un elenco espandibile in Android? Lo voglio in modo che quando l'utente fa clic sulla lista espandibile, abbia un'animazione/effetto come se stessi aprendo un cassetto scorrevole.Aggiungi animazione a ExpandableListView

Si sposta lentamente finché non è completamente aperto.

+0

[http://stackoverflow.com/a/5582924/420015](http://stackoverflow.com/a/5582924/420015) – adneal

risposta

1

Quindi quello che ho fatto è usare un normale ListView e quindi eseguire l'animazione in onListItemClick. L'animazione è simile a quello che faccio a questo link: Android animate drop down/up view proper

Ma solo per una porzione della vista riga. La vista riga viene implementata nel seguente modo in xml:

<somelayout> 
    <normal> 
    </normal> 
    <expanded> 
    </expanded> 
</somelayout> 

Il normale viene utilizzato senza espandere. Quando l'espansione è attivata, l'espansione è impostata su visibile invece di essere andata. È necessario mantenere il controllo di impostarlo su andato nuovamente quando si chiude (ricordare che questo è impostato per le visualizzazioni di conversione che vengono riciclati).

posso chiarire ulteriormente, se necessario, è solo un bel po 'di codice per mettere in.

+0

Questo è per espandere una cella listView, non per espandere un gruppo in ExpandableListView – havchr

+1

@havchr correct, ma a volte il contenuto di un oggetto espanso può essere inserito in un elemento normale e questa soluzione potrebbe essere utilizzata. – Warpzit

2

Ho avuto questo stesso problema esatto. E l'ho risolto una volta per tutte. L'ho aperto a github. https://github.com/tjerkw/Android-SlideExpandableListView

Fondamentalmente, si include questa dipendenza del progetto con il proprio progetto Android. E poi avvolgere il tuo ListAdapter in un SlideExpandableListAdapter. Il wrapper aggiungerà quindi la funzionalità della diapositiva con l'animazione al tuo ListView.

Spero che ti aiuti, lo sto già utilizzando in due progetti.

+0

Ho iniziato a utilizzare la libreria, ma ho scoperto che una volta che ho iniziato ad aggiungere viste complesse, inizia a diventare piuttosto lento. Penso che potrebbe essere perché stai animando i margini. Qualche suggerimento per aggirare il problema di prestazioni? –

+0

@KentAndersen In realtà era già stata accettata una richiesta pull che dovrebbe risolvere questo problema. Stai usando l'ultima versione? Se hai ancora problemi per favore, spiegalo in dettaglio in un ticket github. – TjerkW

+0

Ma non è stato utilizzato ExpandableListView.Voglio animare le viste secondarie della vista Elenco espandibile non ListView. – anshul

4

Ho passato molto tempo a cercare senza fortuna. Le soluzioni esistenti non sono abbastanza fluide - se il tuo layout è qualcosa di più complesso di solo 2 pulsanti, diventa laggy.

Quindi, ho creato il mio ListAdapter che memorizza l'intera vista in un Bitmap e quindi esegue l'animazione nella vista memorizzata nella cache anziché nella vista stessa. Funziona molto più veloce.

Eccolo: https://github.com/dmitry-zaitsev/ExpandableAdapter

La buona notizia è che non c'è bisogno di riscrivere un mucchio di codice - basta avvolgere la mia ExpandableAdapter intorno al vostro adattatore e fornire l'ID del parere che agirà come una ginocchiera pulsante e l'id della vista che contiene il contenuto del secondo livello:

new ExpandableAdapter(context, yourAdapter, R.id.switch, R.id.holder); 

E questo è tutto.

+0

Soluzione piacevole, ma si tratta di una ListView, non di una ExpandableListView come richiesto dal poster. – havchr

+0

@havchr 'ExpandableListView' è praticamente inutile (a causa della mancanza di capacità di personalizzazione), quindi questa soluzione intendeva sostituire' ExpandableListView' con una serie di 'ListView' +' ExpandableAdapter'. –

+0

cosa è R.id.holder? Cosa dovrei passare? Grazie –

0

Questo è quello che ho fatto in queste situazioni.

ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder (list1, PropertyValuesHolder.ofInt ("basso", currentlistHeight, currentlistHeight * 2));

Che questo sarebbe fare è che l'altezza del listView otterrà raddoppiato e sarebbe animato. Se si imposta l'altezza dell'elenco corrente ZERO. questo si comporterebbe come un cassetto.

2

Ho provato a farlo anche questo. Ho trovato una soluzione che funziona per childViews. Tuttavia, non anima l'effettiva espansione del gruppo, ma anima le celle del bambino mentre riempiono lo spazio lasciato dall'espansione.

Modifica: c'è un bug nel collasso, che renderà nascoste alcune celle che non dovrebbero essere nascoste. Questo è probabilmente correlato a View-recycling in listView. Aggiornerò quando avrò una soluzione a questo.

Animazione con layoutAnimation in setOnGroupClickListener

 mResultList.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() { 
     @Override 
     public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) { 
      if(mResultList.isGroupExpanded(groupPosition)){ 
       mProgAdap.prepareToCollapseGroup(groupPosition); 
       setupLayoutAnimationClose(groupPosition); 
       mResultList.requestLayout(); 
      }else{ 
       boolean autoScrollToExpandedGroup = false; 
       mResultList.expandGroup(groupPosition,autoScrollToExpandedGroup); 
       setupLayoutAnimation(); 
       //*/ 
      } 
      //telling the listView we have handled the group click, and don't want the default actions. 
      return true; 
     } 

     private void setupLayoutAnimation() { 
      AnimationSet set = new AnimationSet(true); 
      Animation animation = new AlphaAnimation(0.0f, 1.0f); 
      animation.setDuration(50); 
      set.addAnimation(animation); 

      animation = new ScaleAnimation(1.0f, 1.0f, 0.0f, 1.0f, 0.5f, 1.0f); 
      animation.setDuration(50); 
      set.addAnimation(animation); 

      LayoutAnimationController controller = new LayoutAnimationController(set, 0.75f); 
      mResultList.setLayoutAnimationListener(null); 
      mResultList.setLayoutAnimation(controller); 
     } 

     private void setupLayoutAnimationClose(final int groupPosition) { 
      AnimationSet set = new AnimationSet(true); 
      Animation animation = new AlphaAnimation(1.0f, 0.0f); 
      animation.setDuration(50); 
      animation.setFillAfter(true); 
      animation.setFillEnabled(true); 
      set.addAnimation(animation); 
      animation = new ScaleAnimation(1.0f, 1.0f, 1.0f, 0.0f, 0.5f, 0.0f); 
      animation.setDuration(50); 
      animation.setFillAfter(true); 
      animation.setFillEnabled(true); 
      set.addAnimation(animation); 
      set.setFillAfter(true); 
      set.setFillEnabled(true); 
      LayoutAnimationController controller = new LayoutAnimationController(set, 0.75f); 
      controller.setOrder(LayoutAnimationController.ORDER_REVERSE); 
      mResultList.setLayoutAnimationListener(new Animation.AnimationListener() { 
       @Override 
       public void onAnimationStart(Animation animation) { 

       } 

       @Override 
       public void onAnimationEnd(Animation animation) { 
        mResultList.collapseGroup(groupPosition); 
       } 

       @Override 
       public void onAnimationRepeat(Animation animation) { 

       } 
      }); 
      mResultList.setLayoutAnimation(controller); 
     } 
    }); 

Abbiamo bisogno di più modifiche per rendere l'animazione si applicano solo ai figli effettivi del gruppo allargato/crollata. Poiché non è possibile sovraccaricare la parte corretta in LayoutAnimationController, è necessario creare una classe ViewGroup speciale. Questa è la stessa tecnica di, "Can LayoutAnimationController animate only specified Views".

In ExpandableListViewAdapter, ora è necessario un po 'di gestione dello stato per consentire o ignorare l'animazione sugli elementi nell'elenco.

@Override 
public void onGroupExpanded(int groupPos){ 
    super.onGroupExpanded(groupPos); 

    int childCount = getChildrenCount(groupPos); 
    Log.d("EXPLIST","setting children to be expanded:" + childCount); 

    for(int j=0; j < getGroupCount(); j++){ 
     for(int k=0; k < getChildrenCount(j); k++){ 
      GoalServiceCell cell = (GoalServiceCell)getChild(j,k); 
      cell.expandAnimState = GoalServiceCell.ExpandAnimState.SHOULD_NOT_ANIMATE; 
     } 
    } 

    for(int i=0; i < childCount; i++){ 
     GoalServiceCell cell = (GoalServiceCell)getChild(groupPos,i); 
     cell.expandAnimState = GoalServiceCell.ExpandAnimState.SHOULD_START_EXPAND; 

    } 

} 

public void prepareToCollapseGroup(int groupPos){ 
    int childCount = getChildrenCount(groupPos); 
    for(int j=0; j < getGroupCount(); j++){ 
     for(int k=0; k < getChildrenCount(j); k++){ 
      GoalServiceCell cell = (GoalServiceCell)getChild(j,k); 
      cell.expandAnimState = GoalServiceCell.ExpandAnimState.SHOULD_NOT_ANIMATE; 
     } 
    } 

    for(int i=0; i < childCount; i++){ 
     GoalServiceCell cell = (GoalServiceCell)getChild(groupPos,i); 
     cell.expandAnimState = GoalServiceCell.ExpandAnimState.SHOULD_START_COLLAPSIN; 

    } 
} 

@Override 
public void onGroupCollapsed(int groupPos){ 
    super.onGroupCollapsed(groupPos); 
    int childCount = getChildrenCount(groupPos); 
    for(int i=0; i < childCount; i++){ 
     GoalServiceCell cell = (GoalServiceCell)getChild(groupPos,i); 
     cell.expandAnimState = GoalServiceCell.ExpandAnimState.SHOULD_NOT_ANIMATE; 
    } 

} 

E nel ViewHolder dei bambini.

 void expandOrCollapse(GoalServiceCell cell,int position){ 

     AnimationAverseRelativeLayout hack = (AnimationAverseRelativeLayout)master; 
     boolean shouldAnim = cell.expandAnimState == GoalServiceCell.ExpandAnimState.SHOULD_START_EXPAND || 
          cell.expandAnimState == GoalServiceCell.ExpandAnimState.SHOULD_START_COLLAPSIN; 
     hack.setIfShouldAnimate(shouldAnim); 

    } 

Le GroupView sono contenute anche in un AnimationAverseRelativeLayout. Dal momento che ho impostato "shouldAnimate" su default su false, non ho bisogno di toccarli.

+0

non funziona affatto ...... mostrando un comportamento strano teppista. –

+0

Ho dovuto disabilitare l'animazione "collapse", perché non l'ho mai fatto funzionare.E 'un teppista quando stai facendo anche l'animazione di espansione? – havchr

+0

sì ... una specie di ... un movimento casuale. –