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

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

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



답변

클래스 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성장을 잊고 애니메이션화하는 것이 좋습니다 .

행운을 빕니다!


답변

이 코드를 확인하십시오.

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

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


답변

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

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


답변

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

스타일 :

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


답변

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

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


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

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

}


답변

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

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


답변

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

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

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