한 지점에서 성장하는 애니메이션으로 DialogFragment 표시


93

나는를 표시하고있어 DialogFragment사용자가의 행에 탭 때 ListView. 행의 중심에서 커지도록 대화 상자 표시를 애니메이션하고 싶습니다. 런처에서 폴더를 열 때 유사한 효과를 볼 수 있습니다.

내가 가진 한 가지 아이디어는 TranslateAnimation및 의 조합입니다 ScaleAnimation. 다른 방법이 있습니까?


1
DialogFragment의 애니메이션 링크 를 참조하십시오 .
ASH

답변:


168

클래스 DialogFragment의 래퍼 이기 때문에 원하는 애니메이션을 얻으려면 Dialog테마를 기본 Dialog으로 설정해야합니다 .

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

그런 다음 원하는 애니메이션을 포함 할 테마를 정의하기 만하면됩니다. 에서 styles.xml 사용자 지정 테마를 추가 :

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

이제 res / anim 폴더 에 애니메이션 파일을 추가 합니다.

(이 android:pivotY열쇠입니다)

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>

마지막으로, 여기서 까다로운 것은 애니메이션이 각 행의 중앙에서 자라도록하는 것입니다. 행이 화면을 가로로 채우고 있으므로 한편으로는 android:pivotX값이 정적 이라고 가정합니다 . 반면에 android:pivotY프로그래밍 방식으로 값을 수정할 수 없습니다 .

내가 제안하는 것은 android:pivotY속성 에 대해 각각 다른 백분율 값을 갖는 여러 애니메이션 (및 해당 애니메이션을 참조하는 여러 테마)을 정의하는 것입니다. 그런 다음 사용자가 행을 탭하면 화면에서 행의 백분율로 Y 위치를 계산합니다. 백분율로 위치를 알고 적절한 android:pivotY값 이있는 대화에 테마를 지정하십시오 .

완벽한 솔루션은 아니지만 당신을 위해 트릭을 할 수 있습니다. 결과가 마음에 들지 않으면 줄의 정확한 중심에서 DialogFragment단순한 View성장을 잊고 애니메이션화하는 것이 좋습니다 .

행운을 빕니다!


화면의 다른 위치에 대해 여러 애니메이션을 사용하는 것이 좋습니다. 해킹이지만 유일한 방법 인 것 같습니다.
Edward Dale

> API 11 @Kiran 바부 응답이만이 냄비 주위 작품이다
Blundell은

이러한 애니메이션이 완료되었을 때 콜백을받을 수있는 방법이 있는지 알고 있습니까? 대화 상자가 슬라이드 인한 다음 뷰를 페이드 인하는 두 부분으로 된 애니메이션을 만들고 싶습니다. 어떻게 리스너를 windowAnimations에 연결합니까?
android_student 2015-04-08

훌륭합니다! 내가 찾고 있던 것은 과연!
Aleksey Timoshchenko 2016 년

2
테마 설정 은 다음 setStyle(DialogFragment.STYLE_NORMAL, R.style.MyCustomTheme)onCreate(bundle)참조하십시오. developer.android.com/reference/android/app/DialogFragment.html
tropicalfish

117

이 코드를 확인하십시오.

// 슬라이드 업 애니메이션

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

// 슬라이드 dowm 애니메이션

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

// 스타일

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

// 대화 조각 내부

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

8
죄송합니다. 제 질문에 전혀 답변이 없습니다.
Edward Dale

3
이것은 OP가 요구하는 것과 정확히 일치하지 않을 수도 있지만 좋은 진입 점이라고 생각합니다.
mdelolmo 2013 년

2
훌륭한 예! 나를 위해 일한 유일한 샘플. 트릭 방법에 onActivityCreated (...) 세트 애니메이션 / 테마 인
tomurka

3
이것은 유용 할 수 있지만 질문에 전혀 대답하지 않습니다.
Olayinka 2014

이러한 애니메이션이 완료되었을 때 콜백을받을 수있는 방법이 있는지 알고 있습니까? 대화 상자가 들어가는 두 부분으로 된 애니메이션을 만들고 나서 뷰를 페이드 인하 고 싶습니다. 어떻게 리스너를 windowAnimations에 연결합니까?
android_student 2015-04-08

22

DialogFragment에는 이러한 정확한 이유로 오버라이드 할 수있는 공용 getTheme () 메서드가 있습니다. 이 솔루션은 더 적은 코드 라인을 사용합니다.

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

1
더 이상 걱정할 필요가 없습니다. 간단하고 직접적인 솔루션입니다.
Noundla Sandeep

이것이 저에게 가장 좋은 대답입니다!
수퍼 유저

원래 질문과 관련이 없지만 MainAcitvity에 사용자가 클릭하면 DialogFragment에서 슬라이드 쇼가 활성화되는 갤러리가 있습니다. 그러나 슬라이드 쇼에서 돌아올 때마다 MainActivity에 저크가 있습니다. 이것은 AppTheme.NoActionBarDialogFragment가 기본값을 사용 하는 동안 MainActivity를 사용 하기 때문입니다 AppTheme. 위의 방법은 조각과 활동 모두에서 일관된 주제를 가짐으로써 내 문제를 해결했습니다.
tingyik90

브로, 당신은 천재
재키 정

이 솔루션은 저에게 효과적이었습니다. 그러나 한 가지가 나를 혼란스럽게했습니다. Theme에서 windowEnterAnimation 또는 windowExitAnimation을 직접 설정하면 DialogFragments 애니메이션에 차이가 없습니다. 나를 위해 일한 유일한 것은 windowAnimationStyle을 스타일을 정의한 별도의 XML 파일로 설정하고 거기에 들어가기 및 나가기 애니메이션을 설정하는 것이

9

애니메이션이있는 전체 화면 대화 상자를 얻으려면 다음을 작성하십시오.

스타일 :

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

자바 코드 :

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

대화 조각의 onStart 내부에서 장식보기 사용

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


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

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

}

1
기본보기는 나중에 클릭 될 것 같지 않습니다
HaydenKai

3

DialogFragment에서 커스텀 애니메이션은 onCreateDialog라고합니다. 'DialogAnimation'은 이전 답변의 사용자 정의 애니메이션 스타일입니다.

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

1

보기 확대 / 축소에 대한 Android 개발자 교육을 보셨습니까 ? 좋은 출발점이 될 수 있습니다.

DialogFragment이 작업을 수행하기 위해 확장하는 사용자 정의 클래스를 만들고 싶을 것입니다 .

또한, Honeycomb Animation API 호환성을 위해 Jake Whartons NineOldAndroids 를 API 레벨 1로 거슬러 올라가보세요.


1

API를 통해 작업하려면 onCreateDialog가 아닌 DialogFragemnt-> onStart 내부에서 수행해야합니다.

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

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

        super.onStart();
    }

제 생각에는 최고의 솔루션입니다. AlertDialogs에서도 작동하며 onShowListener에서 사용하십시오. 감사!
Gabor Novak

0

값 anim에이 코드 추가

 <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에 대한 호출

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

자바 코드 : Onclick 설정

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

    }

방법 설정 :

alertDialog.getWindow().getAttributes().windowAnimations = type;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.