2016-10-28 13 views
11

dodałem Obrazy zobaczyć dynamicznie do mojego układu liniowego,Zobacz Animacje Collapse Android/Rozwiń widoków w LinearLayout

chcę osiągnąć

enter image description here

Oto przykładowy kod, co mam zrobić

główną działalność

package ksp.com.animationssample; 

import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.view.View; 
import android.view.animation.AccelerateInterpolator; 
import android.view.animation.Animation; 
import android.view.animation.TranslateAnimation; 
import android.widget.Button; 
import android.widget.ImageView; 
import android.widget.LinearLayout; 

public class MainActivity extends AppCompatActivity { 

    private Button btn_expand; 
    private Button btn_collapse; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     btn_expand = (Button) findViewById(R.id.btn_expand); 
     btn_collapse = (Button) findViewById(R.id.btn_collapse); 
     LinearLayout.LayoutParams vp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); 
     final LinearLayout layout = (LinearLayout) findViewById(R.id.imageLayout); 


     for (int i = 0; i < 3; i++) { 
      final ImageView image = new ImageView(MainActivity.this); 
      image.setLayoutParams(vp); 
      if (i == 0) 
       image.setImageDrawable(getResources().getDrawable(R.drawable.item_image1)); 
      else image.setImageDrawable(getResources().getDrawable(R.drawable.item_image2)); 
      if (i == 2) 
       image.setVisibility(View.VISIBLE); 
      else 
       image.setVisibility(View.GONE); 
      layout.addView(image); 
     } 


     btn_expand.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       expandOrCollapse(layout.getChildAt(2), true, layout.getChildAt(0).getHeight() + layout.getChildAt(1).getHeight()); 
       expandOrCollapse(layout.getChildAt(1), true, layout.getChildAt(0).getHeight()); 
       expandOrCollapse(layout.getChildAt(0), true, 0); 


      } 
     }); 
     btn_collapse.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 

       expandOrCollapse(layout.getChildAt(0), false, 0); 
       expandOrCollapse(layout.getChildAt(1), false, layout.getChildAt(0).getHeight()); 
       expandOrCollapse(layout.getChildAt(2), false, layout.getChildAt(0).getHeight() + layout.getChildAt(1).getHeight()); 
      } 
     }); 


    } 


    public void expandOrCollapse(final View v, boolean is_expand, final int animheight) { 
     TranslateAnimation anim = null; 
     if (is_expand) { 
      anim = new TranslateAnimation(0.0f, 0.0f, -animheight, 0.0f); 
      v.setVisibility(View.VISIBLE); 
      Animation.AnimationListener expandedlistener = new Animation.AnimationListener() { 
       @Override 
       public void onAnimationStart(Animation animation) { 
       } 

       @Override 
       public void onAnimationRepeat(Animation animation) { 
       } 

       @Override 
       public void onAnimationEnd(Animation animation) { 


       } 
      }; 

      anim.setAnimationListener(expandedlistener); 
     } else { 
      anim = new TranslateAnimation(0.0f, 0.0f, 0.0f, -animheight); 
      Animation.AnimationListener collapselistener = new Animation.AnimationListener() { 
       @Override 
       public void onAnimationStart(Animation animation) { 
       } 

       @Override 
       public void onAnimationRepeat(Animation animation) { 
       } 

       @Override 
       public void onAnimationEnd(Animation animation) { 
        v.setVisibility(View.GONE); 
       } 
      }; 

      anim.setAnimationListener(collapselistener); 
     } 

     anim.setDuration(1500); 
     anim.setInterpolator(new AccelerateInterpolator(0.5f)); 
     v.startAnimation(anim); 
    } 
} 

activity_mainn.xml

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/activity_main" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    android:orientation="vertical" 
    android:background="@android:color/holo_blue_dark" 
    tools:context="ksp.com.animationssample.MainActivity"> 

    <Button 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_centerHorizontal="true" 
     android:id="@+id/btn_expand" 
     android:text="Expand" 
     /> 
    <Button 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:id="@+id/btn_collapse" 
     android:text="Collopse"/> 
<ScrollView 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:scrollbars="vertical"> 

    <LinearLayout 
     android:layout_width="match_parent" 
     android:id="@+id/imageLayout" 
     android:gravity="center" 

     android:orientation="vertical" 
     android:layout_height="wrap_content"> 
    </LinearLayout> 
    <!--android:animateLayoutChanges="true"--> 
</ScrollView> 


</RelativeLayout> 

po kliknięciu poszerzyć przycisk na pierwszy raz nie pokazuje animację z po raz drugi, że to działa.

umożliwić Widoczny element po kliknięciu na upadku przycisku.

Co dalej: Kiedy wybrano żadnego widoku element musi pokazać wybierz animację następnie zwinąć animacji, po upadku musi pojawić się jako górny widok jak wspominam w obrazek powyżej. Obecnie jestem twardym kodem liczby wyświetleń i napisałem statyczne animacje dla każdego widoku ze statycznymi wysokościami animacji, tj. (expandOrCollapse(view, height_of_view))

Poszukuję trochę czasu, ale bez powodzenia.

Podążam za Vie expand/collapse i smooth expand/collapse, ale nie mogą mi pomóc rozwinąć wszystkich widoków w układzie liniowym.

Czy możemy to zrobić Widok listy to widok recyklingu czy coś takiego?

dla oszczędności Dodałem moje próbki do koncentratora git czasie można spróbować Animation Sample Github

zasugerować mi, proszę.

+0

Wystarczy jednoznacznie rozwiązać problem - chcesz, aby dolna karta kredytowa pozostała widoczna po zwinięciu?Czy jest inny problem? –

+0

Zakładam, że gdy kliknę drugą kartę, musi ona pojawić się na górze po zwinięciu. – Kathi

+1

CardStackView jest dobrą biblioteką. Rozważ skorzystanie z tej możliwości tylko raz, https://github.com/loopeer/CardStackView –

Odpowiedz

1

starać się nie ukrywać swój pogląd docelowego (teraz ustawić widoczność Gone dla wszystkich widoków po zwiniętym końcu animacji) i to zrobić:

targetView.bringToFront(); 
targetView.invalidate(); 
targetView.getParent().requestLayout(); 
+0

Dzięki za metody "v.bringToFront()" Mam zamiar zaktualizować moje repo z tą zmianą, ale jak możemy sobie poradzić, jeśli widok jest dynamiczny, to jest liczony z serwera. Tutaj napisałem animację dla każdego widoku osobno to nie jest prawda? Czy możesz zaproponować mi lepszy sposób na obsługę tego typu animacji dla wielu widoków? Możesz także zobaczyć, że powinna być wybrana animacja dla widoku wyboru na liście. Jak sobie z tym poradzić? doceń swoją pomoc – Kathi

+0

Przypuszczam, że możesz zastosować animację w pętli for. Dla wybranej animacji - o jakiej animacji mówisz? W wywołaniu zwrotnym onClick dostajemy widok celu i możemy zastosować dowolny typ animacji, a nawet ustawić animację w układzie xml. Przypuszczam, że nie masz zbyt wielu elementów do animacji, więc wystarczy użyć FrameLayout jako kontenera (nie ListView). –

+0

@kathi możesz dołączyć kod do celu nauki :). Naprawdę nie mogę podać, jak radzisz sobie z problemem :( – udayatom

5

zrobiłem oddzielne klasy dla niego. Sprawdź, czy to działa:

public class DropDownAnim extends Animation { 
    private final int sourceHeight; 
    private final int targetHeight; 
    private final View view; 
    private final boolean down; 

    public DropDownAnim(View view, int sourceHeight, int targetHeight, boolean down) { 
     this.view = view; 
     this.sourceHeight = sourceHeight; 
     this.targetHeight = targetHeight; 
     this.down = down; 
    } 

    @Override 
    protected void applyTransformation(float interpolatedTime, Transformation t) { 
     int newHeight; 
     if (down) { 
      newHeight = sourceHeight + (int) (targetHeight * interpolatedTime); 
     } else { 
      newHeight = sourceHeight + targetHeight - (int) (targetHeight * interpolatedTime);//(int) (targetHeight * (1 - interpolatedTime)); 
     } 
     view.getLayoutParams().height = newHeight; 
     view.requestLayout(); 
     view.setVisibility(down ? View.VISIBLE : View.GONE); 
    } 

    @Override 
    public void initialize(int width, int height, int parentWidth, 
      int parentHeight) { 
     super.initialize(width, height, parentWidth, parentHeight); 
    } 

    @Override 
    public boolean willChangeBounds() { 
     return true; 
    } 
} 

Podczas pracy z tym. Dla poszerzyć

public void expand(final View v) { 
     final int sourceHeight = v.getLayoutParams().height; 
     final int targetHeight = getResources().getDimensionPixelSize(R.dimen.notification_height);//v.getMeasuredHeight(); 
     DropDownAnim a = new DropDownAnim(v,targetHeight,true); 
     a.setDuration((int) (targetHeight/v.getContext().getResources().getDisplayMetrics().density)); 
     a.setAnimationListener(new Animation.AnimationListener() { 
      @Override 
      public void onAnimationStart(Animation animation) { 

      } 

      @Override 
      public void onAnimationEnd(Animation animation) { 
       // Your code on end of animation 
      } 

      @Override 
      public void onAnimationRepeat(Animation animation) { 

      } 
     }); 
     v.setVisibility(View.INVISIBLE); 
     v.startAnimation(a); 
    } 

do upadku:

public void collapse(final View v) { 
     final int sourceHeight = v.getLayoutParams().height; 
     final int targetHeight = v.getMeasuredHeight(); 
     DropDownAnim a = new DropDownAnim(v, targetHeight, false); 
     a.setDuration((int) (targetHeight/v.getContext().getResources().getDisplayMetrics().density)); 
     a.setAnimationListener(new Animation.AnimationListener() { 
      @Override 
      public void onAnimationStart(Animation animation) { 

      } 

      @Override 
      public void onAnimationEnd(Animation animation) { 
       // Your code on end of animation 
      } 

      @Override 
      public void onAnimationRepeat(Animation animation) { 

      } 
     }); 
     v.startAnimation(a); 
    } 

Aktualizacja:
sourceHeight dodany do zapobieżenia widok migać.

+0

Dzięki za całą pracę, zastosowałem te metody do mojego Widoki takie jak 'expand (layout.getChildAt (2)); expand (layout.getChildAt (1)); expand (layout.getChildAt (0)); "wydaje się, że działa. Jak ten kod działa dla dynamicznie dodawanych układów? czy możemy użyć pętli? – Kathi

+0

Tak, możesz użyć pętli –

+0

Po zbadaniu Twojego kodu umieściłem kod w moim projekcie, ale moje widoki migają i znikają. Czy możesz pomóc trochę więcej, jak działa ten kod. Złożyłem wniosek o każdy widok w moim układzie liniowym. Również Jak rozpoznaje wysokość animacji? – Kathi