Bir noktadan büyüyen animasyonla DialogFragment'ı göster


95

DialogFragmentKullanıcı bir satıra dokunduğunda bir gösteriyorum ListView. Satır ortasından itibaren büyümesi için iletişim kutusunun gösterimini canlandırmak istiyorum. Başlatıcıdan bir klasör açarken benzer bir etki görülebilir.

Sahip olduğum bir fikir, TranslateAnimationve kombinasyonudur ScaleAnimation. Başka bir yolu var mı?


1
DialogFragment üzerindeki animasyonlar için bağlantıya bakın .
ASH

Yanıtlar:


175

Being DialogFragmentiçin bir sarıcı Dialogsınıfın, kendi tabanına bir tema belirlesin Dialogistediğiniz animasyonu almak için:

public class CustomDialogFragment extends DialogFragment implements OnEditorActionListener
{
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) 
    {
        return super.onCreateView(inflater, container, savedInstanceState);
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) 
    {
        // Set a theme on the dialog builder constructor!
        AlertDialog.Builder builder = 
            new AlertDialog.Builder( getActivity(), R.style.MyCustomTheme );

        builder  
        .setTitle( "Your title" )
        .setMessage( "Your message" )
        .setPositiveButton( "OK" , new DialogInterface.OnClickListener() 
            {      
              @Override
              public void onClick(DialogInterface dialog, int which) {
              dismiss();                  
            }
        });
        return builder.create();
    }
}

Ardından, istediğiniz animasyonu içerecek temayı tanımlamanız yeterlidir. In styles.xml özel tema ekleyin:

<style name="MyCustomTheme" parent="@android:style/Theme.Panel">
    <item name="android:windowAnimationStyle">@style/MyAnimation.Window</item>
</style>

<style name="MyAnimation.Window" parent="@android:style/Animation.Activity"> 
    <item name="android:windowEnterAnimation">@anim/anim_in</item>
    <item name="android:windowExitAnimation">@anim/anim_out</item>
</style>    

Şimdi animasyon dosyalarını res / anim klasörüne ekleyin :

( android:pivotYanahtar)

anim_in.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <scale
        android:interpolator="@android:anim/linear_interpolator"
        android:fromXScale="0.0"
        android:toXScale="1.0"
        android:fromYScale="0.0"
        android:toYScale="1.0"
        android:fillAfter="false"
        android:startOffset="200"
        android:duration="200" 
        android:pivotX = "50%"
        android:pivotY = "-90%"
    />
    <translate
        android:fromYDelta="50%"
        android:toYDelta="0"
        android:startOffset="200"
        android:duration="200"
    />
</set>

anim_out.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <scale
        android:interpolator="@android:anim/linear_interpolator"
        android:fromXScale="1.0"
        android:toXScale="0.0"
        android:fromYScale="1.0"
        android:toYScale="0.0"
        android:fillAfter="false"
        android:duration="200" 
        android:pivotX = "50%"        
        android:pivotY = "-90%"        
    />
    <translate
        android:fromYDelta="0"
        android:toYDelta="50%"
        android:duration="200"
    />
</set>

Son olarak, buradaki zor olan, animasyonunuzun her satırın ortasından büyümesini sağlamaktır. Sanırım satır ekranı yatay olarak dolduruyor, bu yüzden bir yandan android:pivotXdeğer statik olacak. Öte yandan, android:pivotYdeğeri programlı olarak değiştiremezsiniz .

Önerdiğim şey, her biri android:pivotYöznitelikte farklı bir yüzde değerine (ve bu animasyonlara atıfta bulunan birkaç temaya) sahip birkaç animasyon tanımlamanızdır . Ardından, kullanıcı satıra dokunduğunda, ekrandaki satırın yüzdesi olarak Y konumunu hesaplayın. Yüzde cinsinden konumu bilerek, diyaloğunuza uygun android:pivotYdeğere sahip bir tema atayın .

Mükemmel bir çözüm değil ama sizin için hile yapabilir. Sonucu beğenmezseniz, o zaman DialogFragmentbasit bir Viewbüyümeyi unutmanızı ve sıranın tam ortasından hareketlendirmenizi öneririm .

İyi şanslar!


Ekrandaki farklı konumlar için çoklu animasyonlarla iyi fikir. Bu bir hack, ama tek yol gibi görünüyor.
Edward Dale

> API 11 @Kiran Babu cevap Bunu yaptığınızda yalnızca wok etrafında bir işi olduğunu
Blundell

Bu animasyonlar tamamlandığında geri aranmanın olası bir yolu olup olmadığını biliyor musunuz? 2 parçalı bir animasyon yapmak istiyorum, diyalogun içeri girdiği ve ardından görünümleri solduran bir animasyon. Bir dinleyiciyi pencereye nasıl bağlarım?
android_student

Mükemmel! Kesinlikle aradım!
Aleksey Timoshchenko

2
Ayar tema yapıyor olarak basit olarak olabilir setStyle(DialogFragment.STYLE_NORMAL, R.style.MyCustomTheme)üzerinde onCreate(bundle): See developer.android.com/reference/android/app/DialogFragment.html
tropicalfish

123

Bu koda bakın, benim için çalışıyor

// Animasyonu yukarı kaydır

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" >

    <translate
        android:duration="@android:integer/config_mediumAnimTime"
        android:fromYDelta="100%"
        android:interpolator="@android:anim/accelerate_interpolator"
        android:toXDelta="0" />

</set>

// Slayt dowm animasyonu

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <translate
        android:duration="@android:integer/config_mediumAnimTime"
        android:fromYDelta="0%p"
        android:interpolator="@android:anim/accelerate_interpolator"
        android:toYDelta="100%p" />

</set>

// Stil

<style name="DialogAnimation">
    <item name="android:windowEnterAnimation">@anim/slide_up</item>
    <item name="android:windowExitAnimation">@anim/slide_down</item>
</style>

// Dialog Parçası İçinde

@Override
public void onActivityCreated(Bundle arg0) {
    super.onActivityCreated(arg0);
    getDialog().getWindow()
    .getAttributes().windowAnimations = R.style.DialogAnimation;
}

8
Üzgünüm, bu sorumu hiç cevaplamıyor.
Edward Dale

3
Bu, OP'nin tam olarak istediği şey olmayabilir, ancak bence bu iyi bir giriş noktası.
mdelolmo

3
Mükemmel örnek! Benim için çalışan tek örnek.
İşin püf noktası

3
Bu yararlı olabilir ancak soruyu hiç yanıtlamaz.
Olayinka

Bu animasyonlar tamamlandığında geri aranmanın olası bir yolu olup olmadığını biliyor musunuz? 2 parçalı bir animasyon yapmak istiyorum, diyalogun içeri girdiği ve ardından görünümleri solduran bir animasyon. Bir dinleyiciyi pencereye nasıl bağlarım?
android_student

22

DialogFragment, tam da bu nedenle kullanabileceğiniz genel bir getTheme () yöntemine sahiptir. Bu çözüm daha az kod satırı kullanır:

public class MyCustomDialogFragment extends DialogFragment{
    ...
    @Override
    public int getTheme() {
        return R.style.MyThemeWithCustomAnimation;
    }
}

1
Endişeye gerek yok ... Basit ve doğru çözüm.
Noundla Sandeep

Bu benim için en iyi cevap!
superuser

Orijinal soruyla ilgili olmasa da, MainAcitvity'de kullanıcı tıklamasının DialogFragment'daki slayt gösterisini etkinleştireceği bir galerim vardı. Bununla birlikte, slayt gösterisinden her dönüldüğünde MainActivity'de bir sarsıntı oluyor. Bunun nedeni, DialogFragment AppTheme.NoActionBarvarsayılanı kullanırken MainActivity kullanmasıdır AppTheme. Yukarıdaki yöntem, hem parça hem de etkinlik açısından tutarlı bir temaya sahip olarak sorunumu çözdü.
tingyik90

Kardeşim sen dahisin
Jacky Chong

Bu çözüm benim için çalıştı. Ancak bir şey kafamı karıştırdı; windowEnterAnimation veya windowExitAnimation'ın doğrudan Tema içinde ayarlanması DialogFragments animasyonlarımda bir fark yaratmaz. Benim için çalışan tek şey windowAnimationStyle'ı stili tanımlayan ayrı bir XML dosyasına ayarlamak ve oradaki giriş ve çıkış animasyonlarını ayarlamaktı
szaske

10

Animasyonlu tam ekran bir iletişim kutusu almak için aşağıdakileri yazın ...

Stiller:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="actionModeBackground">?attr/colorPrimary</item>
    <item name="windowActionModeOverlay">true</item>
</style>

<style name="AppTheme.NoActionBar">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
</style>

<style name="AppTheme.NoActionBar.FullScreenDialog">
    <item name="android:windowAnimationStyle">@style/Animation.WindowSlideUpDown</item>
</style>

<style name="Animation.WindowSlideUpDown" parent="@android:style/Animation.Activity">
    <item name="android:windowEnterAnimation">@anim/slide_up</item>
    <item name="android:windowExitAnimation">@anim/slide_down</item>
</style>

res / anim / slide_up.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
     android:shareInterpolator="@android:interpolator/accelerate_quad">

    <translate
        android:duration="@android:integer/config_shortAnimTime"
        android:fromYDelta="100%"
        android:toYDelta="0%"/>
</set>

res / anim / slide_down.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
     android:shareInterpolator="@android:interpolator/accelerate_quad">

    <translate
        android:duration="@android:integer/config_shortAnimTime"
        android:fromYDelta="0%"
        android:toYDelta="100%"/>
</set>

Java kodu:

public class MyDialog extends DialogFragment {

    @Override
    public int getTheme() {
        return R.style.AppTheme_NoActionBar_FullScreenDialog;
    }
}

private void showDialog() {
    FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
    Fragment previous = getSupportFragmentManager().findFragmentByTag(MyDialog.class.getName());
    if (previous != null) {
        fragmentTransaction.remove(previous);
    }
    fragmentTransaction.addToBackStack(null);

    MyDialog dialog = new MyDialog();
    dialog.show(fragmentTransaction, MyDialog.class.getName());
}

4

Diyalog parçanızda onStart içindeki dekor görünümünü kullanın

@Override
public void onStart() {
    super.onStart();


    final View decorView = getDialog()
            .getWindow()
            .getDecorView();

    decorView.animate().translationY(-100)
            .setStartDelay(300)
            .setDuration(300)
            .start();

}

1
Altta yatan görünüm daha sonra tıklanabilir görünmüyor
HaydenKai

3

DialogFragment'ta özel animasyon onCreateDialog olarak adlandırılır. 'DialogAnimation' önceki cevapta özel animasyon stilidir.

public Dialog onCreateDialog(Bundle savedInstanceState) 
{
    final Dialog dialog = super.onCreateDialog(savedInstanceState);
    dialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation;
    return dialog;
}

1

Android Geliştiricilerinin Görünümü Yakınlaştırma Eğitimi'ne baktınız mı ? İyi bir başlangıç ​​noktası olabilir.

Muhtemelen bunu çalıştırmak için özel bir sınıf oluşturmak istersiniz DialogFragment.

Ayrıca, Jake Whartons NineOldAndroids for Honeycomb Animation API uyumluluğuna, API Seviye 1'e kadar bir göz atın .


1

API'ler üzerinden çalışmak istiyorsanız, onCreateDialog içinde değil, DialogFragemnt-> onStart içinde yapmanız gerekir.

@Override
    public void onStart() 
    {
        if (getDialog() == null) 
        {
            return;
        }

        getDialog().getWindow().setWindowAnimations(
                  R.style.DlgAnimation);

        super.onStart();
    }

Bence en iyi çözüm. AlertDialogs için de çalışır, sadece onShowListener'da kullanın. Teşekkürler!
Gabor Novak

0

Bu kodu değerler animuna ekle

 <scale
    android:duration="@android:integer/config_longAnimTime"
    android:fromXScale="0.2"
    android:fromYScale="0.2"
    android:toXScale="1.0"
    android:toYScale="1.0"
    android:pivotX="50%"
    android:pivotY="50%"/>
<alpha
    android:fromAlpha="0.1"
    android:toAlpha="1.0"
    android:duration="@android:integer/config_longAnimTime"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"/>

styles.xml çağrısı

<style name="DialogScale">
    <item name="android:windowEnterAnimation">@anim/scale_in</item>
    <item name="android:windowExitAnimation">@anim/scale_out</item>
</style>

Java kodunda: Onclick'i ayarlayın

public void onClick(View v) {
        fab_onclick(R.style.DialogScale, "Scale" ,(Activity) context,getWindow().getDecorView().getRootView());
      //  Dialogs.fab_onclick(R.style.DialogScale, "Scale");

    }

yöntemde kurulum:

alertDialog.getWindow().getAttributes().windowAnimations = type;
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.