2015-07-27 24 views
8

Ho un CardView con le seguenti viste:ListView espandere animazione per gli elementi funziona solo dopo secondo clic

- RelativeLayout (view_1) 
    - TextView 
    - TextView 

- RelativeLayout (view_2) 
    - ImageView 
    - ImageView 

quando apro ListView view_2 è impostato su Visible.GONE quindi potete vederlo. Ora ho usato il ExpandAnimation da this blog. Qui si ha il codice:

/** 
* 
*/ 
public class ExpandAnimation extends Animation { 
    /** 
    * 
    */ 
    private AnimationCallback callback = null; 
    /** 
    * 
    */ 
    private View viewToAnimate = null; 
    /** 
    * 
    */ 
    private RelativeLayout.LayoutParams viewToAnimateLayoutParams = null; 
    /** 
    * 
    */ 
    private int marginStart = 0; 
    /** 
    * 
    */ 
    private int marginEnd = 0; 
    /** 
    * 
    */ 
    private boolean isVisibleAfter = false; 
    /** 
    * 
    */ 
    private boolean isEndedAlready = false; 

    /** 
    * 
    * @param callback 
    * @param view 
    * @param duration 
    */ 
    public ExpandAnimation(AnimationCallback callback, View view, int duration) { 
     this.setDuration(duration); 

     this.callback = callback; 

     this.viewToAnimate = view; 
     this.viewToAnimateLayoutParams = (RelativeLayout.LayoutParams) view.getLayoutParams(); 

     this.isVisibleAfter = (view.getVisibility() == View.VISIBLE); 

     this.marginStart = this.viewToAnimateLayoutParams.bottomMargin; 
     this.marginEnd = (this.marginStart == 0 ? (0 - view.getHeight()) : 0); 

     view.setVisibility(View.VISIBLE); 
    } 

    /** 
    * 
    * @param interpolatedTime 
    * @param transformation 
    */ 
    @Override 
    protected void applyTransformation(float interpolatedTime, Transformation transformation) { 
     super.applyTransformation(interpolatedTime, transformation); 

     if (interpolatedTime < 1.0f) { 
      this.viewToAnimateLayoutParams.bottomMargin = this.marginStart + (int) ((this.marginEnd - this.marginStart) * interpolatedTime); 
      this.viewToAnimate.requestLayout(); 
     } else if (!this.isEndedAlready) { 
      this.viewToAnimateLayoutParams.bottomMargin = this.marginEnd; 
      this.viewToAnimate.requestLayout(); 

      if (this.isVisibleAfter) { 
       this.viewToAnimate.setVisibility(View.GONE); 
      } 

      this.isEndedAlready = true; 

      this.callback.onAnimationCompleted(-1); 
     } 
    } 
} 

lo uso nel mio AdapterView:

public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, AnimationCallback { 
    private TextView textViewValue = null; 
    private TextView textViewTime = null; 
    private RelativeLayout relativeLayoutExpand = null; 
    private ImageView imageViewMood = null; 
    private ImageView imageViewMeal = null; 

    public ViewHolder(View itemView) { 
     super(itemView); 

     this.textViewValue = (TextView) itemView.findViewById(R.id.textview_value); 
     this.textViewTime = (TextView) itemView.findViewById(R.id.textview_time); 
     this.relativeLayoutExpand = (RelativeLayout) itemView.findViewById(R.id.list_row_expand); 
     this.imageViewMood = (ImageView) itemView.findViewById(R.id.imageview_mood); 
     this.imageViewMeal = (ImageView) itemView.findViewById(R.id.imageview_meal); 

     itemView.setOnClickListener(this); 
    } 

    @Override 
    public void onClick(View view) { 
     this.animate(this.relativeLayoutExpand); 
    } 

    public void animate(final View view) { 
     ExpandAnimation expand = new ExpandAnimation(this, view, 500); 

     view.startAnimation(expand); 
    } 

    public void onAnimationCompleted(int position) { 
    } 
} 

Ho un solo problema ora: Quando ho espandere un elemento all'interno della mia lista la prima volta che appare istantaneamente senza animazione e dopo di esso la chiusura e l'apertura funzionano senza problemi con l'animazione.

Qualcuno sa perché la prima apertura avviene senza animazione ma ogni clic dopo attiva l'animazione corretta?

Ho anche bisogno dell'animazione per il primo clic.

EDIT

È perché inizialmente la mia vista visibilità è GONE e quindi l'altezza è sconosciuto? Se sì: come potrei risolvere questo?

EDIT 2

No, il mio file di layout XML non imposta la vista GONE:

<?xml version="1.0" encoding="utf-8"?> 
<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:layout_gravity="center" 
    android:layout_marginBottom="10dp"> 

    <RelativeLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content"> 

     <RelativeLayout 
      android:id="@+id/datatransfer_measure_list_row_data" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:paddingEnd="10dp" 
      android:paddingStart="10dp" 
      android:paddingTop="10dp"> 

      <TextView 
       android:id="@+id/datatransfer_measure_list_row_textview_value" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:layout_alignParentStart="true" 
       android:lines="1" 
       android:maxLines="1" 
       android:singleLine="true" 
       android:text="@string/text_value" 
       android:textColor="@color/textcolorprimary" 
       android:textSize="30sp" /> 

      <TextView 
       android:id="@+id/datatransfer_measure_list_row_textview_time" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:layout_below="@+id/datatransfer_measure_list_row_textview_value" 
       android:layout_gravity="center" 
       android:layout_marginBottom="10dp" 
       android:gravity="start" 
       android:lines="1" 
       android:maxLines="1" 
       android:singleLine="true" 
       android:textColor="@color/textcolorprimary" 
       android:textSize="14sp" /> 

      <ImageView 
       android:id="@+id/datatransfer_measure_list_row_imageview_expand" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:layout_alignParentEnd="true" 
       android:layout_alignParentTop="true" 
       android:contentDescription="@string/text_description" 
       android:scaleType="fitCenter" 
       android:src="@drawable/ic_expand_more_black_24dp" /> 
     </RelativeLayout> 

     <RelativeLayout 
      android:id="@+id/datatransfer_measure_list_row_expand" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_below="@+id/datatransfer_measure_list_row_data" 
      android:background="@color/primaryColor" 
      android:paddingBottom="10dp" 
      android:paddingEnd="10dp" 
      android:paddingStart="10dp" 
      android:paddingTop="10dp"> 

      <RelativeLayout 
       android:id="@+id/datatransfer_measure_list_row_mood" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:layout_marginBottom="10dp"> 

       <TextView 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content" 
        android:layout_alignParentStart="true" 
        android:layout_centerVertical="true" 
        android:lines="1" 
        android:maxLines="1" 
        android:singleLine="true" 
        android:text="@string/text_mood" 
        android:textColor="@color/textcolorsecundary" 
        android:textSize="30sp" /> 

       <ImageView 
        android:id="@+id/datatransfer_measure_list_row_imageview_mood" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_alignParentEnd="true" 
        android:contentDescription="@string/text_description" 
        android:scaleType="fitCenter" /> 
      </RelativeLayout> 

      <ImageView 
       android:id="@+id/datatransfer_measure_list_row_imageview_meal" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:layout_below="@+id/datatransfer_measure_list_row_mood" 
       android:layout_centerInParent="true" 
       android:contentDescription="@string/text_description" /> 

     </RelativeLayout> 

    </RelativeLayout> 

</android.support.v7.widget.CardView> 

ho impostato la View.GONE nel mio ListAdapter:

@Override 
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { 
    ... 

    viewHolder.textViewTime.setText(time); 
    viewHolder.textViewValue.setText(value + " " + unitValue); 
    viewHolder.relativeLayoutExpand.setVisibility(View.GONE); // <-- HERE 

    ... 
} 

Edit 3

.210

forse è importante sapere che il contenitore dei miei cardviews è un recyclerview:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <TextView 
     android:id="@+id/datatransfer_measure_list_textview_name" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_alignParentTop="true" 
     android:background="@color/primaryColorDark" 
     android:gravity="center" 
     android:padding="10dp" 
     android:textColor="@color/white" 
     android:textSize="18dp" /> 

    <android.support.design.widget.CoordinatorLayout 
     android:id="@+id/datatransfer_measure_list_content" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_below="@+id/datatransfer_measure_list_textview_name"> 

     <android.support.v4.widget.SwipeRefreshLayout 
      android:id="@+id/datatransfer_measure_list_swipe_refresh_layout" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent"> 

      <android.support.v7.widget.RecyclerView 
       android:id="@+id/datatransfer_measure_list_row_parent" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:clipToPadding="false" 
       android:padding="10dp" 
       android:textColor="@color/textcolorprimary" /> 
     </android.support.v4.widget.SwipeRefreshLayout> 

     <android.support.design.widget.FloatingActionButton 
      android:id="@+id/datatransfer_measure_list_floating_action_button" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_marginBottom="20dp" 
      android:layout_marginEnd="16dp" 
      android:clickable="true" 
      android:src="@drawable/ic_search_white_24dp" 
      app:backgroundTint="@color/primaryColorDark" 
      app:borderWidth="0dp" 
      app:elevation="6dp" 
      app:layout_anchor="@id/datatransfer_measure_list_row_parent" 
      app:layout_anchorGravity="bottom|right|end" 
      app:layout_behavior="de.hof.ime_dc.idia_move.views.buttons.ScrollFABBehaviour" 
      app:rippleColor="@color/accentColor" /> 

    </android.support.design.widget.CoordinatorLayout> 
</RelativeLayout> 

ho davvero bisogno di una soluzione per questo. Sta disturbando molte delle funzionalità necessarie.

Edit 4

ho aggiunto alcune Log-Uscite:

=============================== EXPAND ========================================= 

08-02 12:27:22.471 V/ExpandAnimation﹕ View is visible: 8 (GONE) 
08-02 12:27:22.471 V/ExpandAnimation﹕ marginStart: 0 
08-02 12:27:22.471 V/ExpandAnimation﹕ marginEnd: 0 
08-02 12:27:22.472 V/ExpandAnimation﹕ View is visible: 0 (VISIBLE) 

============================== COLLAPSE ======================================== 

08-02 12:27:51.015 V/ExpandAnimation﹕ View is visible: 0 (VISIBLE) 
08-02 12:27:51.015 V/ExpandAnimation﹕ marginStart: 0 
08-02 12:27:51.015 V/ExpandAnimation﹕ marginEnd: -156 
08-02 12:27:51.015 V/ExpandAnimation﹕ View is visible: 8 (GONE) 

=============================== EXPAND ========================================= 

08-02 12:27:56.007 V/ExpandAnimation﹕ View is visible: 8 (GONE) 
08-02 12:27:56.007 V/ExpandAnimation﹕ marginStart: -156 
08-02 12:27:56.007 V/ExpandAnimation﹕ marginEnd: 0 
08-02 12:27:56.008 V/ExpandAnimation﹕ View is visible: 0 (VISIBLE) 

============================== COLLAPSE ======================================== 

08-02 12:27:51.015 V/ExpandAnimation﹕ View is visible: 0 (VISIBLE) 
08-02 12:27:51.015 V/ExpandAnimation﹕ marginStart: 0 
08-02 12:27:51.015 V/ExpandAnimation﹕ marginEnd: -156 
08-02 12:27:51.015 V/ExpandAnimation﹕ View is visible: 8 (GONE) 

=============================== EXPAND ========================================= 

08-02 12:27:56.007 V/ExpandAnimation﹕ View is visible: 8 (GONE) 
08-02 12:27:56.007 V/ExpandAnimation﹕ marginStart: -156 
08-02 12:27:56.007 V/ExpandAnimation﹕ marginEnd: 0 
08-02 12:27:56.008 V/ExpandAnimation﹕ View is visible: 0 (VISIBLE) 

Come si può vedere la prima marginStart del espandere è 0, ma deve essere -156.

+0

se è correlato al calcolo dell'altezza della vista, puoi renderlo invisibile invece di andare –

+0

Quindi, una volta cliccato, funzionerà tutte le volte dopo? –

+0

Sì, e anche le viste riciclate funzionano all'istante. – Mulgard

risposta

2

Non hai mostrato il tuo XML ma presumo che tu abbia android:visibility="gone" lì. Se è così, dovresti rimuoverlo dal file di layout (quindi è visibile di default). se dovesse essere andato, chiama setVisibility(View.GONE) su di esso dopo l'inflazione. In questo modo otterrete lo stesso risultato, ma la vista sarebbe anche in grado di ottenere le sue dimensioni.

+0

Ho aggiornato il mio post. Non ho impostato la visibilità sul mio file di layout, l'ho impostato sul mio listadapter. – Mulgard

2

Man mano che il codice è valido, legge i valori dei margini come li avete inizializzati, come 0,0.

È necessario impostare la vista su VISIBLE per ottenere i margini, poiché impostato su GONE avrà margini zero.

Così ordinare il vostro codice come questo:

this.viewToAnimate = view; 

view.setVisibility(View.VISIBLE); 

this.viewToAnimateLayoutParams = (RelativeLayout.LayoutParams) view.getLayoutParams(); 

// Now the margins will not be zero. 
this.marginStart = this.viewToAnimateLayoutParams.bottomMargin; 
this.marginEnd = (this.marginStart == 0 ? (0 - view.getHeight()) : 0); 

Non inizializzare queste variabili.

private int marginStart = 0; 
private int marginEnd = 0; 

o anche questo:

private RelativeLayout.LayoutParams viewToAnimateLayoutParams = null; 

Hai solo bisogno di inizializzare quelli che hanno bisogno di un valore iniziale per voi algoritmo. Come valori di bool.

private boolean isVisibleAfter = false; 
private boolean isEndedAlready = false; 

Sto avendo edizione con questa riga di codice:

this.isVisibleAfter = (view.getVisibility() == View.VISIBLE); 

Non capisco il motivo per cui il codice non sta mostrando un po 'di avvertimento o di errore nella logcat con questa linea.

(view.getVisibility() == View.VISIBLE) non restituisce un valore di visibilità.

this.isVisibleAfter = view.getVisibility(); 
// will return the visibility of the view not a bool value. 

if(view.getVisibility() == View.VISIBLE){ 
// will run only if the visibility is set to visible. 
if(view.getVisibility() == View.INVISIBLE) 
if(view.getVisibility() == View.GONE) 

Non è un valore booleano. Può restituire uno dei tre valori.

Suggerisco di cambiarlo a:

if(view.getVisibility() == View.VISIBLE){ 

    this.isVisibleAfter = true; 
} 
else{ 
    this.isVisibleAfter = false; 
} 

Utilizzando GONE sarà solo comprimere la spazio occupato da questo punto di vista. INVISIBLE manterrà lo spazio occupato dalla vista. A meno che tu non voglia mantenere i tuoi elementi di layout forzati in una determinata posizione, preferirei GONE.

Spero che questo aiuti, fammi sapere.

+0

Non ha risolto il problema. Lo stesso comportamento di prima. E btw: '(view.getVisibility() == View.VISIBLE)' restituisce true o false. 'view.getVisibility()' e 'View.VISIBLE' tutti restituiscono valori int. Ma se dici '(1 == 2)' ottieni false. – Mulgard

+0

@ Mulgard mi dispiace non aver aiutato. Facci sapere se lo risolvi. E grazie per il consiglio sulla visibilità. –