我想在Android Lollipop的应用程序中实现共享元素转换.在我阅读了文档,SO问题和一些帖子之后我决定试一试,但现在我遇到了问题.
场景是我有两个片段容器(用于平板电脑),就像普通的列表/详细设计模式一样.
我想在触摸列表项时执行列表片段到详细信息片段之间的共享元素转换.详细信息片段的输入正常,但只要按下后退按钮,应用程序就会在转换框架代码中崩溃并显示NullPointerException.
共享元素转换是否支持该方案?
以下是启动详细信息片段的代码:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
Fragment fragment = DetailFragment.create((int)id);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
View title = view.findViewById(R.id.item_name);
title.setTransitionName("title");
listFragment.setSharedElementReturnTransition(
TransitionInflater.from(this).inflateTransition(R.transition.change_bounds));
listFragment.setExitTransition(
TransitionInflater.from(this).inflateTransition(android.R.transition.explode));
fragment.setSharedElementEnterTransition(
TransitionInflater.from(this).inflateTransition(R.transition.change_bounds));
fragment.setEnterTransition(
TransitionInflater.from(this).inflateTransition(android.R.transition.explode));
ft.addSharedElement(title, "title");
}
else {
ft.setCustomAnimations(R.anim.slide_in_right, 0, 0, R.anim.slide_out_right);
}
ft.replace(R.id.detail_panel, fragment)
.addToBackStack(null)
.commit();
Run Code Online (Sandbox Code Playgroud)
Logcat在这里:
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.support.v4.app.Fragment.getAllowReturnTransitionOverlap()' on a null object reference
at android.support.v4.app.BackStackRecord.configureTransitions(BackStackRecord.java:1201)
at android.support.v4.app.BackStackRecord.beginTransition(BackStackRecord.java:1029)
at android.support.v4.app.BackStackRecord.popFromBackStack(BackStackRecord.java:883)
at android.support.v4.app.FragmentManagerImpl.popBackStackState(FragmentManager.java:1541)
at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:502)
at android.support.v4.app.FragmentActivity.onBackPressed(FragmentActivity.java:176)
...
Run Code Online (Sandbox Code Playgroud) android-fragments android-transitions android-5.0-lollipop shared-element-transition
我已经使用爆炸动画实现了两个片段之间的转换(标准谷歌过渡 - > http://goo.gl/tE5xzl).有没有机会确定爆炸的方向?
问题是,当我之前将背板拉到我的片段时,我会得到一个随机动画,其爆炸方向不同.这看起来对用户来说有点混乱.
谢谢你的帮助 :)
android android-ui android-layout android-fragments android-transitions
我正在玩Lollipop的Activity Transition.
我在Activity A中有一个按钮,当点击它时调用Activity B.在Activity B中,我重写onBackPressed()并调用finishAfterTransition()
活动B只有两个具有背景颜色的相对布局块.我已经将一个共享元素从Button转换到其中一个块,它完美地运行.即使回归过渡也有效.
但我遇到的问题是我无法取消共享元素返回转换并实现正常的退出转换.
目的是将两个滑块从屏幕上滑下,顶部一个从顶部开始,另一个从底部滑下.如果我启用了共享元素转换,则无效.
我尝试设置退出转换并将null设置为活动B上的sharedElementReturn转换.不起作用.
我尝试使用幻灯片转换在活动A上设置重新转换过渡,但仍然是在后退时反转共享元素转换.
如果我关闭共享元素转换,从活动B返回到A时,所需的效果是完美的.
有任何想法吗?
我正在使用在Android 5.0上运行的设备,minSdk即21和targetSdk22.
应用说明
我正在使用2个活动的应用程序,活动A包含GridView带有图片和文本的活动,活动B包含一个ImageView,一个TextView和一个片段.该片段包含与文本关联的图像列表.当点击活动A的图像时,有一个共享元素转换,它将图像和文本移动到活动B ImageView和TextView活动B.我还在活动A和B之间设置了淡入淡出过渡.片段被动态添加到活动B在onCreate()方法中.我设置并进入并退出到片段的转换:
MyFragment myFragment = new MyFragment();
myFragment.setEnterTransition(new Slide());
myFragment.setExitTransition(new Slide);
getFragmentManager().beginTransaction()
.add(R.id.container, myFragment, MyFragment.TAG)
.commit();
Run Code Online (Sandbox Code Playgroud)
关于片段退出转换,我使用了一个技巧,当按下后退按钮时,我用另一个片段替换片段强制它:
@Override
public void onBackPressed() {
if (myFragment.isVisible()) {
getFragmentManager().beginTransaction()
.replace(R.id.container, new Fragment())
.commit();
}
super.onBackPressed();
}
Run Code Online (Sandbox Code Playgroud)
我的应用程序的主题是一个孩子,Theme.Material所以我没有定义
getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
Run Code Online (Sandbox Code Playgroud)
也不
<item name="android:windowActivityTransitions">true</item>
<item name="android:windowContentTransitions">true</item>
Run Code Online (Sandbox Code Playgroud)
(我尝试过,它没有任何区别).
应用问题
我的问题涉及片段输入转换无法正常工作,而退出转换工作正常.我试过不同的案例:
getWindow().setEnterTransition(new Fade());
getWindow().setExitTransition(new Fade());
结果与未定义显式活动转换的结果相同.
<item name="android:windowEnterTransition">@transition/fade</item>
<item name="android:windowExitTransition">@transition/fade</item>
结果是片段将通过淡入进入并被Fragment.setEnterTransition()忽略.android android-animation android-fragments android-transitions android-5.0-lollipop
当活动将一个转移到另一个共享元素时,它们会在新活动的屏幕上显示,覆盖导航栏,如图所示

您还可以在视频视图叠加导航栏中看到此错误
我正在尝试将URL中的图像加载到ImageView使用Picasso中.
共享转换的图像位于a CardView中RecyclerView,而第二个图像位于LinearLayout中.第一次发出请求时,元素没有动画,因为毕加索需要将图像加载到视图中,但是在后续请求中它很好.
如何ImageView在启动转换之前确保已成功填充?
我有一个如下图所示的布局
其中橙色框架是HostFragment这样的:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<android.support.design.widget.AppBarLayout
android:id="@id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="@id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:titleMarginStart="68dp"
/>
<de.halfbit.audiopie.ui.common.views.SlidingTabs
android:id="@id/tabs"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:slidingTabsIndicatorColor="@color/accent"
/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
Run Code Online (Sandbox Code Playgroud)
而蓝框是一个ItemsFragment带有a 的孩子RecyclerView.
当我点击我的瓷砖RecyclerView替换HostFragment另一个ContentFragment片段时,假设共享点击的图像.我是通过应用共享元素转换来实现的,如下所示:
FragmentManager fm = getChildFragmentManager();
Fragment fragment = ContentFragment.newInstance();
AutoTransition autoTransition = new AutoTransition();
autoTransition.setDuration(3000);
fragment.setSharedElementEnterTransition(autoTransition);
fm.beginTransaction()
.replace(R.id.library, fragment)
.addSharedElement(view, "cover")
.commit();
Run Code Online (Sandbox Code Playgroud)
它可以正常工作:当ContentFragment中的动画开始时,封面图块的初始位置是错误的(参见此屏幕投射视频) - 它具有不希望的底部偏移.
在视觉上,此偏移量看起来等于标签栏的高度HostFragment.你们有没有想过如何避免这种偏移? …
我正在尝试使用Transitions API为两个ViewGroup之间的共享元素设置动画.目标是绿色视图从"父母的边界"向"新位置"移动.
我有以下布局:
first.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="200dp"
android:layout_height="200dp"
android:background="#f00" />
<FrameLayout
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:background="#00f">
<View
android:id="@+id/myview"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center"
android:background="#0f0" />
</FrameLayout>
</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)
second.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="200dp"
android:layout_height="200dp"
android:background="#f00">
<View
android:id="@+id/myview"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center"
android:background="#0f0" />
</FrameLayout>
<FrameLayout
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:background="#00f" />
</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)
但是,我无法让它正常工作.默认转换只是淡出所有内容,ChangeBounds转换什么都不做,而且ChangeTransform看起来也不正确.
我正在使用的代码:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final ViewGroup root = (ViewGroup) findViewById(android.R.id.content);
setContentView(R.layout.first);
View myView1 = findViewById(R.id.myview);
myView1.setTransitionName("MYVIEW");
new …Run Code Online (Sandbox Code Playgroud) 我想在下一个活动中添加一个输入转换.
所以我做了:
getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);
window.setEnterTransition(new Slide());
Run Code Online (Sandbox Code Playgroud)
这似乎不起作用.在做了一些试验和错误之后(因为我将这个转换用于其他活动)我发现它在调用后确实有效
ActivityOptionsCompat activityOptionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, "some_name");
ActivityCompat.startActivity(activity, new Intent(TourAndLoginActivity.this, LoginActivity.class), activityOptionsCompat.toBundle());
Run Code Online (Sandbox Code Playgroud)
但我没有共享元素(我添加了一个视图来测试它).无法将"null"添加为共享元素.
这样做真的是强制性的吗?我的解决方法是添加一个不可见的共享元素.
我有两个活动(A和B),当我点击一个按钮时,A中的元素开始动画过渡到B.但是,我想要从B回到A时禁用向后播放的相同过渡.
在提出这个问题之前,我在互联网上进行了研究,发现有两种方法setSharedElementReturnTransition(transition)和setSharedElementReenterTransition(transition).这些方法在适当的活动方法中调用onCreate(),transition = null并且不起作用.
唯一的解决办法,我发现,取消过渡,打电话finish()的onBackPressed()代替super.onBackPressed().有没有其他方法可以实现理想的行为?
总而言之,当我将向后转换设置为null时,没有任何改变 - 转换未被覆盖.
编辑1.这是一个代码:
ActivtyA.java
public class ActivityA {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_A);
}
...
@Override
public void onPersonalProfileEditIconClicked() {
Intent intent = new Intent(ActivityA.this, ActivityB.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
View sharedView = avatarView;
String sharedElementName = getString(R.string.profile_avatar);
ActivityOptions transitionActivityOptions = ActivityOptions.makeSceneTransitionAnimation
(ActivityA.this, sharedView, sharedElementName);
startActivity(intent, transitionActivityOptions.toBundle());
} else startActivity(intent);
}
}
Run Code Online (Sandbox Code Playgroud)
ActivityB.java
public class …Run Code Online (Sandbox Code Playgroud)