Android Parçaları ve animasyon


265

Örneğin Honeycomb Gmail istemcisinin kullandığı bu tür bir kaymayı nasıl uygulamalısınız?

Can TransactionManagerekleme ve Fragments kaldırarak otomatik olarak bu sap, bir slayt olmak emülatörü bu nedeniyle test etmek tür zor değil :)

Yanıtlar:


388

Fragmanları arasındaki geçiş canlandırmak için, ya da gösteriyor veya kullandığınız bir fragmanını gizleme işlemi animasyon Fragment Managerbir oluşturmak Fragment Transaction.

Her Parça İşleminde, sırasıyla gösterme ve gizleme için kullanılacak (veya değiştirme kullanıldığında her ikisi de) animasyonları girip çıkarabilirsiniz.

Aşağıdaki kod, bir parçayı kaydırarak diğerini yerine kaydırarak parçayı nasıl değiştireceğinizi gösterir.

FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);

DetailsFragment newFragment = DetailsFragment.newInstance();

ft.replace(R.id.details_fragment_container, newFragment, "detailFragment");

// Start the animated transition.
ft.commit();

Gizleme veya sadece arayacağını bir fragman gösteren aynı şeyi başarmak için ft.showya ft.hidesırasıyla göstermek veya gizlemek isteyen Fragment geçen.

Başvuru için, XML animasyon tanımları objectAnimatoretiketi kullanır . Bir slide_in_left örneği şöyle görünebilir:

<?xml version="1.0" encoding="utf-8"?>
<set>
  <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:propertyName="x" 
    android:valueType="floatType"
    android:valueFrom="-1280"
    android:valueTo="0" 
    android:duration="500"/>
</set>

57
Bunu denediğimde RuntimeException: Bilinmeyen animatör adı: translate gösterir .
Labeeb Panampullan

3
Slide_in_left ve right öğelerinde tanımlanan animasyonların, eski animasyon tanımı yerine bir nesneAnimator tanımları kümesi kullanılarak oluşturulduğundan emin olun.
Reto Meier

7
Bu çok yardımcı oldu. Doğru yoldaydım ama oraya kadar ulaşamadım. Diğer okuyucular için, android: interpolator'ı bir özellik olarak, en sevdiğinizi ("@android: interpolator / linear" gibi) belirtebilirsiniz. Varsayılan olarak "@android: enterpolatör / accelerate_decelerate" şeklindedir.
Dave MacLean

6
Uyumluluk API'leri ile API Seviye 7'yi hedefliyorum. Parçaları canlandırmamın bir yolu var mı?
Jarrod Smith

5
@JarrodSmith , Honeycomb API'sini Eclair'e getirmek için NineOldAndroids gibi bir uyumluluk kitaplığı kullanmayı deneyebilirsiniz .
Bay S

249

Destek kitaplığını kullanmanız gerekmiyorsa, Romanın cevabına bir göz atın .

Ancak destek kitaplığını kullanmak istiyorsanız , aşağıda açıklandığı gibi eski animasyon çerçevesini kullanmanız gerekir.

Danıştıktan sonra Reto en ve blindstuff en cevapları aşağıdaki kod çalışma aldık.

Parçacıklar sağdan içeri ve geriye basıldığında sola doğru kayıyor gibi görünür .

FragmentManager fragmentManager = getSupportFragmentManager();

FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.setCustomAnimations(R.anim.enter, R.anim.exit, R.anim.pop_enter, R.anim.pop_exit);

CustomFragment newCustomFragment = CustomFragment.newInstance();
transaction.replace(R.id.fragment_container, newCustomFragment );
transaction.addToBackStack(null);
transaction.commit();

Sıra önemlidir. Bu, daha setCustomAnimations()önce aramanız gerektiği replace()veya animasyonun etkili olmayacağı anlamına gelir !

Daha sonra bu dosyaların res / anim klasörünün içine yerleştirilmesi gerekir .

enter.xml :

<?xml version="1.0" encoding="utf-8"?>
<set>
    <translate xmlns:android="http://schemas.android.com/apk/res/android"
               android:fromXDelta="100%"
               android:toXDelta="0"
               android:interpolator="@android:anim/decelerate_interpolator"
               android:duration="@android:integer/config_mediumAnimTime"/>
</set>

exit.xml :

<set>
    <translate xmlns:android="http://schemas.android.com/apk/res/android"
               android:fromXDelta="0"
               android:toXDelta="-100%"
               android:interpolator="@android:anim/accelerate_interpolator"
               android:duration="@android:integer/config_mediumAnimTime"/>
</set>

pop_enter.xml :

<set>
    <translate xmlns:android="http://schemas.android.com/apk/res/android"
               android:fromXDelta="-100%"
               android:toXDelta="0"
               android:interpolator="@android:anim/decelerate_interpolator"
               android:duration="@android:integer/config_mediumAnimTime"/>
</set>

pop_exit.xml :

<?xml version="1.0" encoding="utf-8"?>
<set>
    <translate xmlns:android="http://schemas.android.com/apk/res/android"
               android:fromXDelta="0"
               android:toXDelta="100%"
               android:interpolator="@android:anim/accelerate_interpolator"
               android:duration="@android:integer/config_mediumAnimTime"/>
</set>

Animasyonların süresi, herhangi bir varsayılan değer @android:integer/config_shortAnimTimeveya başka bir sayı olarak değiştirilebilir.

Parça değiştirmeleri arasında bir yapılandırma değişikliği gerçekleşirse (örneğin döndürme) geri işlemin animasyonlu olmadığını unutmayın. Bu, destek kitaplığının rev 20'sinde hala var olan belgelenmiş bir hatadır .


47
Bu beni kurtardı. Not, siparişe dikkat etmek önemlidir , bu da doğal olarak ilk kez kaçırdım. Bu, replace () öğesinden önce setCustomAnimations () öğesini çağırmanız gerektiği anlamına gelir.
Stephen Kidson

3
Her şeyi söylediğin gibi yazdım ama logcat diyor ki: unknow animatör ismi tercüme etmek Bu sorunun üstesinden nasıl gelebilirim? Bu arada
parçamı

Harika çalışıyor, ancak yapı araçları 21.1 ile oluşturmanın "Geçersiz dosya adı: yalnızca küçük harfler ve rakamlar içermesi ([a-z0-9_.])" Şeklinde bir hata oluşturduğu ortaya çıkıyor. Pop_enter.xml ve pop_exit.xml yanıtındaki dosya adlarını düzenlemenizi öneririm.
smichak

Harika bir çözüm ve geri düğmesine bastığımda harika çalışıyor. Ben sadece bir sorum var: Eğer özel bir backButton oluşturmak istiyorsanız, geri düğmesinden davranışı çoğaltmak için hangi kodu çağırmalıyım?
Thomas Teilmann

1
Thomas, geri dönmek istiyorsanız, bu formu uygulamalısınız: .setCustomAnimations (R.anim.pop_enter, R.anim.pop_exit, R.anim.enter, R.anim.exit)
Alex Zaraos

26

Animasyon dosyası oluşturmak yerine bunu kullanmanızı şiddetle tavsiye ediyorum çünkü çok daha iyi bir çözüm. Android Studio, herhangi bir yeni XML dosyası oluşturmadan kullanabileceğiniz varsayılanı zaten sağlar animation. Animasyonların adları android.R.anim.slide_in_left ve android.R.anim.slide_out_right şeklindedir ve bunları aşağıdaki gibi kullanabilirsiniz:

fragmentTransaction.setCustomAnimations (android.R.anim.slide_in_left, android.R.anim.slide_out_right);

FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();              
fragmentTransaction.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
fragmentManager.addOnBackStackChangedListener(this);
fragmentTransaction.replace(R.id.frame, firstFragment, "h");
fragmentTransaction.addToBackStack("h");
fragmentTransaction.commit();

Çıktı:

resim açıklamasını buraya girin


1
android.R ... "Android Studio varsayılan animasyon sağlar", bu da tutulma çalışabilir android stüdyo için değil, android.R android özel.Ve bu arada apis ne var bilgilerini paylaşmadı. çünkü android.R şeyler farklı apis farklıdır.
steve moretz

@stevemoretz thaxs bro Senin fikrin üzerinde anlaştım .. Cevabımı düzeltip güncelleyeceğim ...
Gowthaman M


2

Bana gelince, görünüm kesişmesi gerekir:

içinde -> sağdan hızlıca kaydırın

dışarı -> sola kaydır

İşte benim için çalışır kodu:

slide_in_right.xml

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="50%p" android:toXDelta="0"
            android:duration="@android:integer/config_mediumAnimTime"/>
    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
            android:duration="@android:integer/config_mediumAnimTime" />
</set>

slide_out_left.xml

 <set xmlns:android="http://schemas.android.com/apk/res/android">
        <translate android:fromXDelta="0" android:toXDelta="-50%p"
                android:duration="@android:integer/config_mediumAnimTime"/>
        <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
                android:duration="@android:integer/config_mediumAnimTime" />
    </set>

işlem kodu:

inline fun FragmentActivity.setContentFragment(
        containerViewId: Int,
        backStack: Boolean = false,
        isAnimate: Boolean = false,
        f: () -> Fragment

): Fragment? {
    val manager = supportFragmentManager
    return f().apply {
        manager.beginTransaction().let {
            if (isAnimate)
                it.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left)

            if (backStack) {
                it.replace(containerViewId, this, "Fr").addToBackStack("Fr").commit()
            } else {
                it.replace(containerViewId, this, "Fr").commit()
            }
        }
    }
}

Android, bu animasyonlarla geçişleri titriyor gibi görünüyor (özellikle tercüme edilenler)
Gabriel De Oliveira Rohden

@GabrielDeOliveiraRohden benim için olduğu gibi tüm casses değil
Serg Burlaka

1

Bunu aşağıdaki şekilde çözerim

Animation anim = AnimationUtils.loadAnimation(this, R.anim.slide);
fg.startAnimation(anim);
this.fg.setVisibility(View.VISIBLE); //fg is a View object indicate fragment
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.