Android片段和动画
您应该如何实现蜂窝Gmail客户端使用的那种滑动功能Android片段和动画,android,android-fragments,android-3.0-honeycomb,Android,Android Fragments,Android 3.0 Honeycomb,您应该如何实现蜂窝Gmail客户端使用的那种滑动功能 通过添加和删除片段,TransactionManager是否可以自动处理此问题?由于模拟器是幻灯片,因此测试此问题有点困难:)要设置片段之间转换的动画,或者使用片段管理器创建片段事务,以动画化显示或隐藏片段的过程 在每个片段事务中,您可以指定将分别用于显示和隐藏(或在使用替换时同时用于显示和隐藏)的输入和输出动画 下面的代码显示了如何通过滑出一个片段并将另一个片段滑入到位来替换片段 FragmentTransaction ft = getFr
通过添加和删除片段,TransactionManager是否可以自动处理此问题?由于模拟器是幻灯片,因此测试此问题有点困难:)要设置片段之间转换的动画,或者使用
片段管理器
创建片段事务
,以动画化显示或隐藏片段的过程
在每个片段事务中,您可以指定将分别用于显示和隐藏(或在使用替换时同时用于显示和隐藏)的输入和输出动画
下面的代码显示了如何通过滑出一个片段并将另一个片段滑入到位来替换片段
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();
要实现隐藏或显示片段的相同功能,只需调用ft.show
或ft.hide
,分别传入要显示或隐藏的片段
作为参考,XML动画定义将使用objectAnimator
标记。左侧幻灯片的示例可能如下所示:
<?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>
如果您不必使用支持库,请查看答案 但如果要使用支持库,则必须使用旧的动画框架,如下所述 经过咨询和回答,我得到了以下代码的工作 按下back时,碎片从右侧滑入,从左侧滑出
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();
顺序很重要。这意味着您必须在replace()
之前调用setCustomAnimations()
,否则动画将不会生效强>
接下来,这些文件必须放在res/anim文件夹中
enter.xml:
exit.xml:
pop_enter.xml:
pop_exit.xml:
动画的持续时间可以更改为任何默认值,如@android:integer/config\u shortAnimTime
或任何其他数字
请注意,如果在片段替换之间发生配置更改(例如旋转),则不会设置后退动作的动画。这是一个仍然存在于支持库版本20中的问题 My modified支持使用视图动画(即
,
)和对象动画(即
)进行片段转换。它是通过以下方式实现的。有关详细信息,请参阅我在github上的文档。我用下面的方法解决这个问题
Animation anim = AnimationUtils.loadAnimation(this, R.anim.slide);
fg.startAnimation(anim);
this.fg.setVisibility(View.VISIBLE); //fg is a View object indicate fragment
我强烈建议您使用它而不是创建动画文件,因为它是一个更好的解决方案。Android Studio已经提供了默认值
动画
,无需创建任何新的XML文件即可使用。动画名称为android.R.anim.slide\u in\u left和android.R.anim.slide\u out\u right,您可以按如下方式使用它们:
fragmentTransaction.setCustomAnimations(安卓.R.anim.slide\u在左,安卓.R.anim.slide\u在右)强>
输出:
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()
}
}
}
}
至于我,我需要查看目录: 在->从右侧滑动 出->向左滑动 以下代码适用于我: 右.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>
<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>
当我尝试此操作时,它显示RuntimeException:未知动画师名称:translate。请确保在幻灯片\u in_left和right中定义的动画是使用一组objectAnimator定义而不是旧的动画定义构建的。这非常有帮助。我在正确的轨道上,只是没有一路走到那里。对于其他阅读器,您也可以将android:interpolator作为属性,并指定您最喜欢的属性(例如“@android:interpolator/linear”)。它默认为“@android:interpolator/accelerate\u decreate”。我的目标是API 7级的兼容API。有什么方法可以让我制作片段动画吗?@JarrodSmith你可以尝试使用兼容库,比如将蜂巢API下载到Eclair。这救了我一命。注意,注意顺序很重要,这自然是我第一次错过的。这意味着您必须在replace()之前调用setCustomAnimations()。我试图在我的片段上实现。我按照您提到的编写了所有内容,但logcat说:未知动画师名称翻译如何克服此问题?顺便说一句,我在导航抽屉(滑动菜单)上调用我的片段效果很好,但是使用构建工具21.1构建它会生成一个错误,说“无效的文件名:必须只包含小写字母和数字([a-z0-9_.])”。我建议编辑pop_enter.xml和pop_exit.xml.Great解决方案答案中的文件名,当我按下后退按钮时,效果会很好。我只有一个问题:如果我想创建一个自定义backButton,我应该调用什么代码来复制后退按钮的行为?Thomas如果你想后退,你应该实现以下表单:。setCustomAnimations(R.anim.pop_enter,R.anim.pop_exit,R.anim.enter,R.anim.exit)android.R。。。“Android Studio提供默认动画”,这不是针对Android Studio的,它也可以在eclipse中工作,Android.R是特定于Android的。顺便说一句,你没有分享这些API的信息。因为Android.R上的内容在不同的API上是不同的。@stevemoretz thaxs bro我同意你的观点。。我会更正并更新我的答案……Android似乎在用那些动画(特别是翻译动画)来忽悠过渡@GabrielDeOliveiraRohden对我来说不是所有的案例
Animation anim = AnimationUtils.loadAnimation(this, R.anim.slide);
fg.startAnimation(anim);
this.fg.setVisibility(View.VISIBLE); //fg is a View object indicate fragment
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();
<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>
<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>
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()
}
}
}
}