Android, setvisibility ile basit animasyonlar ekliyor (view.Gone)


237

Basit bir düzen tasarladım. Tasarımı animasyon olmadan bitirdim, ancak şimdi textview click olayı sırasında animasyonlar eklemek istiyorum ve nasıl kullanılacağını bilmiyorum. Xml tasarımım iyi görünüyor mu değil mi? Herhangi bir öneriniz takdir edilecektir.

XML'im

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:longClickable="false"
    android:orientation="vertical"
    android:weightSum="16" >

<LinearLayout 
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#00DDA0"
    android:layout_weight="3" >
</LinearLayout>
 <TextView
        android:id="@+id/Information1"
        android:layout_width="match_parent"
        android:layout_height="1dp" 
        android:text="Child Information" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>

 <LinearLayout
     android:id="@+id/layout1"
     android:layout_width="fill_parent"
     android:layout_height="0dp"
     android:layout_weight="8.5"
     android:background="#BBBBBB"
     android:orientation="vertical" >

     <TextView
         android:id="@+id/textView1"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" />
 </LinearLayout>

  <TextView
        android:id="@+id/Information2"
        android:layout_width="match_parent"
        android:layout_height="0dp" 
        android:text="Parent Information" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>
  <LinearLayout 
          android:id="@+id/layout2"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#BBBBBB"
    android:layout_weight="8.5" >
     <TextView
         android:id="@+id/textView2"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" />
      </LinearLayout>
   <TextView
        android:id="@+id/Information3"
        android:layout_width="match_parent"
        android:layout_height="0dp" 
        android:text="Siblings" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>
   <LinearLayout 
          android:id="@+id/layout3"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#BBBBBB"
    android:layout_weight="8.5" >
     <TextView
         android:id="@+id/textView3"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" />
      </LinearLayout>
    <TextView
        android:id="@+id/Information4"
        android:layout_width="match_parent"
        android:layout_height="0dp" 
        android:text="Teacher Information" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>
    <LinearLayout 
          android:id="@+id/layout4"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#BBBBBB"
    android:layout_weight="8.5" >
     <TextView
         android:id="@+id/textView4"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" />
      </LinearLayout>
     <TextView
        android:id="@+id/Information5"
        android:layout_width="match_parent"
        android:layout_height="0dp" 
        android:text="Grade Information" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>
     <LinearLayout 
          android:id="@+id/layout5"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#BBBBBB"
    android:layout_weight="8.5" >
     <TextView
         android:id="@+id/textView5"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" />
      </LinearLayout>
      <TextView
        android:id="@+id/Information6"
        android:layout_width="match_parent"
        android:layout_height="0dp" 
        android:text="Health Information" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>
      <LinearLayout 
          android:id="@+id/layout6"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#BBBBBB"
    android:layout_weight="8.5" >
    <TextView
         android:id="@+id/textView5"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" 
         android:layout_weight="8.5" />
      </LinearLayout>

</LinearLayout>

Benim java

public class Certify_Info extends Activity {

    private static TextView tv2,tv3,tv5,tv6,tv4,tv1;
    private static LinearLayout l1,l2,l3,l4,l5,l6;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_certify__info);

        tv1=(TextView) findViewById(R.id.Information1);
        tv2=(TextView) findViewById(R.id.Information2);
        tv3=(TextView) findViewById(R.id.Information3);
        tv4=(TextView) findViewById(R.id.Information4);
        tv5=(TextView) findViewById(R.id.Information5);
        tv6=(TextView) findViewById(R.id.Information6); 

        l1=(LinearLayout) findViewById(R.id.layout1);
        l2=(LinearLayout) findViewById(R.id.layout2);
        l3=(LinearLayout) findViewById(R.id.layout3);
        l4=(LinearLayout) findViewById(R.id.layout4);
        l5=(LinearLayout) findViewById(R.id.layout5);
        l6=(LinearLayout) findViewById(R.id.layout6); 

        l2.setVisibility(View.GONE);
        l3.setVisibility(View.GONE); 
        l4.setVisibility(View.GONE); 
        l5.setVisibility(View.GONE);
        l6.setVisibility(View.GONE);

        tv1.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l2.setVisibility(View.GONE);
                l3.setVisibility(View.GONE); 
                l4.setVisibility(View.GONE); 
                l5.setVisibility(View.GONE);
                l6.setVisibility(View.GONE);
                l1.setVisibility(View.VISIBLE);
            }
        });
        tv2.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l1.setVisibility(View.GONE);
                l3.setVisibility(View.GONE); 
                l4.setVisibility(View.GONE); 
                l5.setVisibility(View.GONE);
                l6.setVisibility(View.GONE);
                l2.setVisibility(View.VISIBLE);
            }
        });
        tv3.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l1.setVisibility(View.GONE);
                l2.setVisibility(View.GONE);
                l4.setVisibility(View.GONE); 
                l5.setVisibility(View.GONE);
                l6.setVisibility(View.GONE);
                l3.setVisibility(View.VISIBLE);

            }
        });
        tv4.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l1.setVisibility(View.GONE);
                l2.setVisibility(View.GONE);
                l3.setVisibility(View.GONE); 
                l4.setVisibility(View.GONE); 
                l5.setVisibility(View.GONE);
                l6.setVisibility(View.GONE);
                l4.setVisibility(View.VISIBLE); 
            }
        });
        tv5.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l1.setVisibility(View.GONE);
                l2.setVisibility(View.GONE);
                l3.setVisibility(View.GONE); 
                l4.setVisibility(View.GONE); 
                l6.setVisibility(View.GONE);
                l5.setVisibility(View.VISIBLE); 
            }
        });
        tv6.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l1.setVisibility(View.GONE);
                l2.setVisibility(View.GONE);
                l3.setVisibility(View.GONE); 
                l4.setVisibility(View.GONE); 
                l5.setVisibility(View.GONE);
                l6.setVisibility(View.VISIBLE);
            }
        });

    }
}

Yanıtlar:


706

Animasyon eklemek için iki şey yapabilirsiniz, önce android'in düzen değişikliklerini sizin için canlandırmasına izin verebilirsiniz. Bu şekilde, görünümün görünürlüğünü değiştirmek veya görünüm konumlarını değiştirmek gibi düzendeki her şeyi değiştirdiğinizde android otomatik olarak solmaya / geçiş animasyonlarına neden olur. Bu seti kullanmak için

android:animateLayoutChanges="true"

düzeninizdeki kök düğümde.

İkinci seçeneğiniz manuel olarak animasyon eklemek olacaktır. Bunun için Android 3.0'da (Honeycomb) tanıtılan yeni animasyon API'sını kullanmanızı öneririm. Size birkaç örnek verebilirim:

Bu kaybolur View:

view.animate().alpha(0.0f);

Bu onu geri döndürür:

view.animate().alpha(1.0f);

Bu View, yüksekliğine göre aşağı doğru hareket eder :

view.animate().translationY(view.getHeight());

Bu, Viewbaşka bir yere taşındıktan sonra konumunu başlangıç ​​konumuna döndürür :

view.animate().translationY(0);

setDuration()Animasyonun süresini ayarlamak için de kullanabilirsiniz . Örneğin, bu View2 saniyelik bir süre içinde kaybolur :

view.animate().alpha(0.0f).setDuration(2000);

Ve istediğiniz kadar animasyonu birleştirebilirsiniz, örneğin bu bir soluklaşır Viewve 0.3 saniyelik bir süre boyunca aynı anda aşağı doğru hareket ettirir:

view.animate()
        .translationY(view.getHeight())
        .alpha(0.0f)
        .setDuration(300);

Ayrıca animasyona bir dinleyici atayabilir ve her türlü olaya tepki verebilirsiniz. Animasyon başladığında, bittiği veya tekrarlandığı vb. Gibi. Soyut sınıfı kullanarak, AnimatorListenerAdaptertüm geri çağrıları bir AnimatorListenerkerede uygulamak zorunda değilsiniz, sadece ihtiyacınız olanları. Bu, kodu daha okunabilir hale getirir. Örneğin, aşağıdaki kod View, 0,3 saniyelik bir süre (300 milisaniye) boyunca yüksekliği ile aşağı doğru kaybolur ve animasyon tamamlandığında görünürlüğü ayarlanır View.GONE.

view.animate()
        .translationY(view.getHeight())
        .alpha(0.0f)
        .setDuration(300)
        .setListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                view.setVisibility(View.GONE);
            }
        });

6
@Natix Bu süper çağrıyı gereksiz olarak adlandırmazdım. Yanlış bir şey olmadığı için yüzeysel düzenlemeler yapmayın.
Xaver Kapeller

5
İyi ama tersi neden düzgün çalışmıyor? view.setVisibility (View.VISIBLE); Alfa (1.0f) İLE, 100 dolgu üstü ile görünür ...
Mart'ta

15
Görünürlüğü ayarlamadan önce animasyonu netleştirmeniz gerekir >> view.clearAnimation(); view.setVisibility(View.GONE);aksi takdirde düzen görünmez kalır ve gitmez.
Eftekhari

2
@Eftekhari Hiç kaynak yoğun değiller. Ve güncel bir Android sürümünüz varsa, ancak muhtemelen düşük bellek veya kötü bir grafik yongası olan eski bir telefona sahip olduğunuzdan daha fazla gecikme yaşıyorsanız. Ve yeni bir kütüphane hakkında konuşmuyorum. Animatörler yerli. Bunlar Android Framework'ün bir parçasıdır. 5 yıl önce piyasaya sürüldü ve bugün tüm cihazların% 97,9'u onları destekliyor. Animators'ı kullanmamanız veya en azından ViewCompat.animate()destek kitaplığının bir parçası olan ve Animators'ı daha yeni sürümlerde ve Animasyonları Android 3.0 ve önceki sürümlerde kullanmamanız için hiçbir neden yoktur .
Xaver Kapeller

1
Ancak, tüm cihazların% 97,9'u Android 4.0 ve üstü olduğunda, bir kullanım alanı kalmadı ViewCompat.animate().
Xaver Kapeller

70

VisibilityDeğişiklikleri canlandırmanın en kolay yolu Transition API, destek (androidx) paketinde bulunanları kullanmaktır . Sadece TransitionManager.beginDelayedTransitionyöntemi çağırın ve görünümün görünürlüğünü değiştirin. Fade, Gibi birkaç varsayılan geçiş vardır Slide.

import androidx.transition.TransitionManager;
import androidx.transition.Transition;
import androidx.transition.Fade;

private void toggle() {
    Transition transition = new Fade();
    transition.setDuration(600);
    transition.addTarget(R.id.image);

    TransitionManager.beginDelayedTransition(parent, transition);
    image.setVisibility(show ? View.VISIBLE : View.GONE);
}

Animasyonlu görünümün parentüstü nerede ViewGroup. Sonuç:

resim açıklamasını buraya girin

İşte Slidegeçiş ile sonuç :

import androidx.transition.Slide;

Transition transition = new Slide(Gravity.BOTTOM);

resim açıklamasını buraya girin

Farklı bir şeye ihtiyacınız varsa özel geçiş yazmak kolaydır. İşte başka bir cevaptaCircularRevealTransition yazdığım örnek . CircularReveal animasyonuyla görünümü gösterir ve gizler.

Transition transition = new CircularRevealTransition();

resim açıklamasını buraya girin

android:animateLayoutChanges="true"seçeneği aynı şeyi yaparsa , geçiş olarak AutoTransition'ı kullanır .


@TouhidulIslam no. Bu sınıflar androidx paketinde mevcuttur. Her şey geriye dönük olarak uyumludur
ashakirov

2
Bir görünüm grubunu genişletmeye / daraltmaya ne dersiniz?
TheRealChx101

Birden fazla beginDelayedTransitions yapabilir misin ?
Jeongbebs

26

Lütfen bu bağlantıyı kontrol edin . Bu, L2R, R2L, T2B, B2T animasyonları gibi animasyonlara izin verecektir.

Bu kod soldan sağa animasyon gösterir

TranslateAnimation animate = new TranslateAnimation(0,view.getWidth(),0,0);
animate.setDuration(500);
animate.setFillAfter(true);
view.startAnimation(animate);
view.setVisibility(View.GONE);

R2L'den yapmak istiyorsanız

TranslateAnimation animate = new TranslateAnimation(0,-view.getWidth(),0,0);

yukarıdan aşağıya

TranslateAnimation animate = new TranslateAnimation(0,0,0,view.getHeight());

ve tam tersi ...


8
Bu, görünümü orijinal konumundan uzaklaştırır.
Relm

24

Bu satırı xml üst düzenine eklemeyi deneyin

 android:animateLayoutChanges="true"

Düzeniniz şöyle görünecek

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:animateLayoutChanges="true"
    android:longClickable="false"
    android:orientation="vertical"
    android:weightSum="16">

    .......other code here

    </LinearLayout>

bu benim için çalıştı. Kurulumum kök görünüm olarak bir kısıt düzeni kullanıyor. Görünüm View.VISIBLE olarak ayarlandığında animasyon gösterilir
EdgeDev

çok basit ve zarif bir çözüm
Naveed Ahmad

11

@Xaver Kapeller'in cevabına dayanarak, ekranda yeni görünümler göründüğünde (ve bunları gizlemek için animasyon) kaydırma animasyonu oluşturmanın bir yolunu buldum.

Bu durumdan gider:

  • Buton
  • Son Düğme

için

  • Buton
  • Buton 1
  • Düğme 2
  • Düğme 3
  • Düğme 4
  • Son Düğme

ve viceversa.

Böylece, kullanıcı ilk düğmeyi tıklattığında, solma animasyonu kullanılarak "Düğme 1", "Düğme 2", "Düğme 3" ve "Düğme 4" öğeleri görünecek ve "Son Düğme" öğesi sonuna kadar aşağı hareket edecektir. Düzenin yüksekliği de kaydırma görüntüsünün doğru kullanılmasına izin verecek şekilde değişecektir.

Animasyonlu öğeleri gösteren kod:

private void showElements() {
    // Precondition
    if (areElementsVisible()) {
        Log.w(TAG, "The view is already visible. Nothing to do here");
        return;
    }

    // Animate the hidden linear layout as visible and set
    // the alpha as 0.0. Otherwise the animation won't be shown
    mHiddenLinearLayout.setVisibility(View.VISIBLE);
    mHiddenLinearLayout.setAlpha(0.0f);
    mHiddenLinearLayout
            .animate()
            .setDuration(ANIMATION_TRANSITION_TIME)
            .alpha(1.0f)
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
                    updateShowElementsButton();
                    mHiddenLinearLayout.animate().setListener(null);
                }
            })
    ;

    mLastButton
            .animate()
            .setDuration(ANIMATION_TRANSITION_TIME)
            .translationY(mHiddenLinearLayoutHeight);

    // Update the high of all the elements relativeLayout
    LayoutParams layoutParams = mAllElementsRelativeLayout.getLayoutParams();

    // TODO: Add vertical margins
    layoutParams.height = mLastButton.getHeight() + mHiddenLinearLayoutHeight;
}

ve bu, animasyonun öğelerini gizleme kodudur:

private void hideElements() {
    // Precondition
    if (!areElementsVisible()) {
        Log.w(TAG, "The view is already non-visible. Nothing to do here");
        return;
    }

    // Animate the hidden linear layout as visible and set
    mHiddenLinearLayout
            .animate()
            .setDuration(ANIMATION_TRANSITION_TIME)
            .alpha(0.0f)
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    Log.v(TAG, "Animation ended. Set the view as gone");
                    super.onAnimationEnd(animation);
                    mHiddenLinearLayout.setVisibility(View.GONE);
                    // Hack: Remove the listener. So it won't be executed when
                    // any other animation on this view is executed
                    mHiddenLinearLayout.animate().setListener(null);
                    updateShowElementsButton();
                }
            })
    ;

    mLastButton
            .animate()
            .setDuration(ANIMATION_TRANSITION_TIME)
            .translationY(0);

    // Update the high of all the elements relativeLayout
    LayoutParams layoutParams = mAllElementsRelativeLayout.getLayoutParams();

    // TODO: Add vertical margins
    layoutParams.height = mLastButton.getHeight();
}

Animasyonu gizleme yönteminde basit bir saldırı olduğunu unutmayın. Animasyon dinleyicisi mHiddenLinearLayout'ta, dinleyicinin kendisini kullanarak:

mHiddenLinearLayout.animate().setListener(null);

Bunun nedeni, görünüme bir animasyon dinleyicisi eklendikten sonra, bu görünümde bir sonraki animasyon yürütüldüğünde dinleyicinin de yürütülmesi olacaktır. Bu, animasyon dinleyicisindeki bir hata olabilir.

Projenin kaynak kodu GitHub'da: https://github.com/jiahaoliuliu/ViewsAnimated

Mutlu kodlama!

Güncelleme : Görünümlere eklenen tüm dinleyiciler için, animasyon sona erdikten sonra kaldırılmalıdır. Bu kullanılarak yapılır

view.animate().setListener(null);

Bu en iyi cevaptır
Naveen Kumar M

1
view.animate().setListener(null);İfadesi benim günü kurtardı. Bu kesinlikle bir hata gibi görünüyor.
Michal Vician

@MichalVician Memnun oldum!
jiahao

8

Bir menüyü şu şekilde göstermeyi / gizlemeyi başardım:

MenuView.java (FrameLayout öğesini genişletir)

private final int ANIMATION_DURATION = 500;

public void showMenu()
{
    setVisibility(View.VISIBLE);
    animate()
            .alpha(1f)
            .setDuration(ANIMATION_DURATION)
            .setListener(null);
}

private void hideMenu()
{
    animate()
            .alpha(0f)
            .setDuration(ANIMATION_DURATION)
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    setVisibility(View.GONE);
                }
            });
}

Kaynak

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.