你可以下载我的整个项目来尝试调试。这是我的整个代码的回购:https ://bitbucket.org/lexic92/studio48/
当我尝试用空白片段替换空白片段时,过渡中出现了“幽灵片段”。
如何重现问题: 我有一个导航抽屉,当我单击一个项目时,它会打开一个填充整个屏幕的片段。
导航抽屉:
- 按钮 1 - 带有文本的片段
按钮 2 - 为空的片段
当我打开应用程序时,它从带有文本的片段开始。然后,我打开 Navigation Drawer 并单击 Button 2。Transition is bad,并在瞬间变成空白屏幕,然后切换回淡入淡出的文本,直到它变成空白屏幕。
如果我打开导航抽屉并再次单击按钮 2 ,它会从全文淡入空白屏幕。因此,在一瞬间,它会在不应该显示的情况下显示带有文本的片段。我在调试模式下逐步运行我的应用程序,以减慢它的速度并验证此行为是否确实发生了。
如果我打开导航抽屉并第三次再次单击按钮 2 ,它不会正确显示任何动画,因为它正在淡入同一屏幕。
有谁知道为什么会这样?你认为它与导航抽屉有什么关系吗?
这是我的整个代码的回购: https ://bitbucket.org/lexic92/studio48/
以下是一些代码摘录:
SongDetailActivity.java:
@Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager = getSupportFragmentManager();
//OPEN THE BLANK SCREEN
if(position == 1) {
fragmentManager.beginTransaction()
//.setCustomAnimations(R.anim.fade_in, R.anim.fade_out)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.replace(R.id.songlist_detail_container, PlaceholderFragment.newInstance(position + 1, mSongId))
.commit();
}
//OPEN THE SCREEN WITH TEXT
else {
SongDetailFragment sdf = new SongDetailFragment();
Bundle args = new Bundle();
args.putString(SongDetailFragment.ARG_ITEM_ID, mSongId);
sdf.setArguments(args);
fragmentManager.beginTransaction()
//.setCustomAnimations(R.anim.fade_in, R.anim.fade_out)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.replace(R.id.songlist_detail_container, sdf)
.commit();
}
}
当我注释掉说“.setTransition”的 2 行并取消注释说“.setCustomAnimations”的 2 行时,也会发生同样的问题。以下是自定义动画:
res/anim/fade_out.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
android:duration="@android:integer/config_mediumAnimTime" />
</set>
res/anim/fade_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="@android:integer/config_mediumAnimTime" />
</set>
如何在不出现“幽灵”片段的情况下使其顺利过渡?
规格:我在 Google Nexus 5 物理设备(不是模拟器)上使用 android.support.v7.app.ActionBarActivity、minSdkVersion == 15 和 targetSdkVersion == 21 运行。
我对答案的猜测:
这个网站似乎给了我一个提示:http ://gotoanswer.com/?q=Android+Animation+within+a+Fragment+not+working
就我个人而言,这是片段动画的 zPosition 的错误。
您看到的是“出现”的新片段,这是因为新片段附加在当前片段下方。
因此,当尝试对现有片段的“上方”片段进行动画处理时,似乎什么都没有发生,然后新片段就“出现”了。
我尝试了很多变通方法,使用 zPosition (仅影响窗口而不影响布局,因此对片段没有影响), onAnimationCreate() 将根布局置于前面,甚至在动画开始和停止时......似乎什么都不做。
因此,在没有为片段过渡编写完整的自定义动画的情况下,它们目前有点错误。
你可能不得不玩。.add(Fragment) 等待它被添加,然后调用 .remove(Fragment) 删除旧的片段,这样新的片段就物理地放置在现有片段的顶部。
我确实注意到在实例化 SongDetailActivity.java 时调用了这段代码,即使我没有点击导航抽屉:
//OPEN THE SCREEN WITH TEXT
else {
SongDetailFragment sdf = new SongDetailFragment();
Bundle args = new Bundle();
args.putString(SongDetailFragment.ARG_ITEM_ID, mSongId);
sdf.setArguments(args);
fragmentManager.beginTransaction()
//.setCustomAnimations(R.anim.fade_in, R.anim.fade_out)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.replace(R.id.songlist_detail_container, sdf)
.commit();
}
正如引用所暗示的那样,在淡入新片段之前,当前片段可能正在淡出到这个“基础”片段?
我最终做了什么
注意:我没有把它作为答案,因为它在技术上不能回答我的问题,但它是我能想到的最好的备份计划解决方案。
我尝试在没有动画的情况下查看问题是否已解决。“幽灵片段”没有出现,但我确实注意到加载片段需要一秒钟,看起来很刺耳和丑陋。我想要一个丝般流畅的应用,如果没有动画的时候不流畅,那么即使我修复了幽灵片段的错误,它也可能是无望的。我了解到片段只是错误的(见这里)。
我决定隐藏并显示视图。这是我的新代码:
SongDetailActivity.java
//---------- NAVIGATION DRAWER -------------
@Override
public void onNavigationDrawerItemSelected(int position) {
//HOME
if (position == 0) {
}
//LYRICS
else if(position == 1) {
findViewById(R.id.lyrics).setVisibility(View.VISIBLE);
findViewById(R.id.info).setVisibility(View.INVISIBLE);
}
//INFO
else if(position == 2) {
findViewById(R.id.info).setVisibility(View.VISIBLE);
findViewById(R.id.lyrics).setVisibility(View.INVISIBLE);
}
}
我还复制并粘贴了 2 个片段的布局(空的和有大量文本的)到相同的布局中,作为 FrameLayout 父级的子级:
fragment_songlist_detail.xml:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:background="#f8bbd0"
android:layout_width="match_parent"
>
<LinearLayout
android:id="@+id/lyrics"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
...
</LinearLayout>
<LinearLayout
android:id="@+id/info"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
...
</LinearLayout>
</FrameLayout>
它工作正常,但我只是不知道如何让它淡入淡出。但这是一个单独的堆栈溢出问题的问题。如果有人解开幽灵碎片之谜,我很想知道答案。但我决定我现在不打算浪费时间试图弄清楚它,特别是当片段的过渡在过去被证明是错误的时候(就像在那篇文章中一样)。