Android menambahkan animasi sederhana saat setvisibilitas (view.Gone)

237

Saya telah mendesain tata letak yang sederhana. Saya telah menyelesaikan desain tanpa animasi, tetapi sekarang saya ingin menambahkan animasi ketika acara klik tampilan teks dan saya tidak tahu bagaimana menggunakannya. Apakah desain xml saya terlihat bagus atau tidak? Setiap saran akan dihargai.

XML saya

<?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>

Java saya

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);
            }
        });

    }
}
arun
sumber

Jawaban:

706

Anda dapat melakukan dua hal untuk menambahkan animasi, pertama-tama Anda dapat membiarkan perubahan animasi layout Android untuk Anda. Dengan begitu setiap kali Anda mengubah sesuatu di tata letak seperti mengubah visibilitas tampilan atau melihat posisi android akan secara otomatis membuat animasi fade / transisi. Untuk menggunakan set itu

android:animateLayoutChanges="true"

pada simpul root di tata letak Anda.

Opsi kedua Anda adalah menambahkan animasi secara manual. Untuk ini saya sarankan Anda menggunakan API animasi baru yang diperkenalkan di Android 3.0 (Honeycomb). Saya dapat memberi Anda beberapa contoh:

Ini memudar View:

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

Ini memudar kembali:

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

Ini bergerak Viewke bawah dengan ketinggiannya:

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

Ini mengembalikan Viewke posisi awal setelah dipindahkan ke tempat lain:

view.animate().translationY(0);

Anda juga dapat menggunakan setDuration()untuk mengatur durasi animasi. Misalnya ini memudar Viewselama 2 detik:

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

Dan Anda dapat menggabungkan sebanyak mungkin animasi yang Anda inginkan, misalnya ini memudar a Viewdan memindahkannya ke bawah pada waktu yang sama selama periode 0,3 detik:

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

Dan Anda juga dapat menetapkan pendengar untuk animasi dan bereaksi terhadap semua jenis acara. Seperti ketika animasi dimulai, ketika itu berakhir atau berulang dll. Dengan menggunakan kelas abstrak AnimatorListenerAdapterAnda tidak harus menerapkan semua panggilan balik AnimatorListenersekaligus tetapi hanya yang Anda butuhkan. Ini membuat kode lebih mudah dibaca. Sebagai contoh, kode berikut memudar Viewpergerakannya dengan ketinggiannya selama periode 0,3 detik (300 milidetik) dan ketika animasi selesai, visibilitasnya diatur ke 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);
            }
        });
Xaver Kapeller
sumber
6
@ Natix Saya tidak akan menyebut panggilan super itu berlebihan. Jangan lakukan pengeditan superfisial karena tidak ada yang salah.
Xaver Kapeller
5
Apakah bagus tetapi kebalikannya tidak berfungsi dengan benar mengapa? view.setVisibility (View.VISIBLE); DENGAN alpha (1.0f), muncul dengan 100 padding top ...
delive
15
Harus menghapus animasi sebelum mengatur visibilitas >> view.clearAnimation(); view.setVisibility(View.GONE);jika tidak, tata letak akan tetap tidak terlihat dan tidak hilang.
Eftekhari
2
@Eftekhari Mereka sama sekali tidak intensif sumber daya. Dan jika Anda memiliki versi Android terbaru, tetapi masih mengalami kelambatan daripada Anda mungkin memiliki ponsel yang lebih tua dengan memori rendah atau chip grafis yang buruk. Dan saya tidak berbicara tentang perpustakaan baru. Animator adalah asli. Mereka adalah bagian dari Kerangka Android. Mereka telah dirilis 5 tahun yang lalu dan hari ini 97,9% dari semua perangkat mendukungnya. Tidak ada alasan untuk tidak menggunakan Animator atau setidaknya ViewCompat.animate()yang merupakan bagian dari perpustakaan dukungan dan menggunakan Animator pada versi yang lebih baru dan Lihat Animasi pada Android 3.0 dan di bawahnya.
Xaver Kapeller
1
Tetapi ketika 97,9% dari semua perangkat adalah Android 4.0 dan di atasnya tidak ada banyak usecase tersisa untuk ViewCompat.animate().
Xaver Kapeller
70

Cara termudah untuk menghidupkan Visibilityperubahan adalah penggunaan Transition APIyang tersedia dalam paket dukungan (androidx). Cukup panggil TransitionManager.beginDelayedTransitionmetode lalu ubah visibilitas tampilan. Ada beberapa transisi standar seperti Fade, 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);
}

Di mana parentinduk ViewGrouptampilan animasi. Hasil:

masukkan deskripsi gambar di sini

Inilah hasil dengan Slidetransisi:

import androidx.transition.Slide;

Transition transition = new Slide(Gravity.BOTTOM);

masukkan deskripsi gambar di sini

Sangat mudah untuk menulis transisi khusus jika Anda memerlukan sesuatu yang berbeda. Berikut adalah contoh CircularRevealTransitionyang saya tulis dalam jawaban lain . Ini menunjukkan dan menyembunyikan tampilan dengan animasi CircularReveal.

Transition transition = new CircularRevealTransition();

masukkan deskripsi gambar di sini

android:animateLayoutChanges="true"Opsi melakukan hal yang sama, hanya menggunakan AutoTransition sebagai transisi.

ashakirov
sumber
@TouhidulIslam no. Kelas-kelas ini tersedia dalam paket androidx. Semuanya kompatibel ke belakang
ashakirov
2
Bagaimana dengan memperluas / menciutkan grup tampilan?
TheRealChx101
Bisakah Anda melakukan banyak beginDelayedTransition?
Jeongbebs
26

Silakan periksa tautan ini . Yang akan memungkinkan animasi seperti animasi L2R, R2L, T2B, B2T.

Kode ini menunjukkan animasi dari kiri ke kanan

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

jika Anda ingin melakukannya dari R2L kemudian gunakan

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

untuk atas ke bawah sebagai

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

dan sebaliknya ...

NullPointerException
sumber
8
Ini menggeser tampilan dari posisi aslinya.
Relm
24

Coba tambahkan baris ini ke tata letak induk xml

 android:animateLayoutChanges="true"

Tata letak Anda akan terlihat seperti ini

<?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>
Ricardo Romo
sumber
ini berhasil untuk saya. Setup saya menggunakan tata letak kendala sebagai tampilan root. Ketika tampilan diatur ke Lihat. SUDAH animasi ditampilkan
EdgeDev
solusi yang sangat sederhana dan elegan
Naveed Ahmad
11

Berdasarkan jawaban dari @Xaver Kapeller, saya menemukan cara untuk membuat animasi gulir ketika tampilan baru muncul di layar (dan juga animasi untuk menyembunyikannya).

Itu pergi dari negara ini:

  • Tombol
  • Tombol Terakhir

untuk

  • Tombol
  • Tombol 1
  • Tombol 2
  • Tombol 3
  • Tombol 4
  • Tombol Terakhir

dan sebaliknya.

Jadi, ketika pengguna mengklik tombol pertama, elemen "Tombol 1", "Tombol 2", "Tombol 3" dan "Tombol 4" akan muncul menggunakan animasi fade dan elemen "Tombol Terakhir" akan bergerak ke bawah sampai akhir. Ketinggian tata letak akan berubah juga, memungkinkan penggunaan tampilan gulir dengan benar.

Ini adalah kode untuk menunjukkan elemen dengan animasi:

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;
}

dan ini adalah kode untuk menyembunyikan elemen animasi:

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();
}

Perhatikan ada hack sederhana pada metode untuk menyembunyikan animasi. Pada pendengar animasi mHiddenLinearLayout, saya harus menghapus pendengar itu sendiri dengan menggunakan:

mHiddenLinearLayout.animate().setListener(null);

Ini karena begitu pendengar animasi dilampirkan ke tampilan, saat berikutnya setiap animasi dieksekusi dalam tampilan ini, pendengar akan dieksekusi juga. Ini mungkin bug di pendengar animasi.

Kode sumber proyek ini ada di GitHub: https://github.com/jiahaoliuliu/ViewsAnimated

Selamat coding!

Pembaruan : Untuk setiap pendengar yang dilampirkan pada tampilan, itu harus dihapus setelah animasi berakhir. Ini dilakukan dengan menggunakan

view.animate().setListener(null);
jiahao
sumber
Yang ini adalah jawaban terbaik
Naveen Kumar M
1
The view.animate().setListener(null);pernyataan menyelamatkan hari saya. Ini jelas merupakan bug.
Michal Vician
@MichalVician Senang itu!
jiahao
8

Saya dapat menampilkan / menyembunyikan menu dengan cara ini:

MenuView.java (extend FrameLayout)

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);
                }
            });
}

Sumber

Nelson Almendra
sumber