나는를 표시하고있어 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
성장을 잊고 애니메이션화하는 것이 좋습니다 .
행운을 빕니다!
setStyle(DialogFragment.STYLE_NORMAL, R.style.MyCustomTheme)
을 onCreate(bundle)
참조하십시오. developer.android.com/reference/android/app/DialogFragment.html
이 코드를 확인하십시오.
// 슬라이드 업 애니메이션
<?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;
}
}
AppTheme.NoActionBar
DialogFragment가 기본값을 사용 하는 동안 MainActivity를 사용 하기 때문입니다 AppTheme
. 위의 방법은 조각과 활동 모두에서 일관된 주제를 가짐으로써 내 문제를 해결했습니다.
애니메이션이있는 전체 화면 대화 상자를 얻으려면 다음을 작성하십시오.
스타일 :
<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());
}
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로 거슬러 올라가보세요.
API를 통해 작업하려면 onCreateDialog가 아닌 DialogFragemnt-> onStart 내부에서 수행해야합니다.
@Override
public void onStart()
{
if (getDialog() == null)
{
return;
}
getDialog().getWindow().setWindowAnimations(
R.style.DlgAnimation);
super.onStart();
}
값 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;