我遇到了一个关于android中片段转换的非常奇怪的错误。如果您在过渡动画期间将应用程序置于背景中,则始终可以重现。如果我在向后转换中从片段B转到片段A,片段B在片段A的顶部保持可见。视图层次结构不显示片段B的任何痕迹,片段B的可见元素不可点击,而是点击在下面的片段A的重叠元素上注册。
我在这里创建了一个关于错误的简短视频:https://imgur.com/In5IZub
为了弄清楚出了什么问题,我创建了一个新的应用程序,并努力设置我现有的应用程序。那时我可以本地化错误的来源:
maven { url "https://maven.google.com" }
在我的顶级build.gradle文件中。为什么会导致我的应用程序出现故障?这对我来说似乎是个大问题。
顶级build.gradle的完整内容:
// Top-level build file where you can add configuration options common to
all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
maven { url "https://maven.google.com" }
}
}
我的应用build.gradle的全部内容:
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
buildToolsVersion "26.0.2"
defaultConfig {
applicationId "com.example.mschaidinger.fragmenttransitiontest"
minSdkVersion 17
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner
"android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile "com.android.support:appcompat-v7:26.+"
compile "com.android.support:design:26.+"
compile 'com.android.support.constraint:constraint-layout:1.0.2'
testCompile 'junit:junit:4.12'
}
如果我从顶级gradle文件中删除存储库maven.google.com,则转换按预期工作。
如果没有这种奇怪的副作用,我做错了什么阻止我使用这个存储库?
编辑:添加转换代码
前进过渡:
FragmentTransaction openTransaction = getSupportFragmentManager().beginTransaction();
if (animate != ANIM_NONE) {
if (animate == ANIM_ENTER) {
openTransaction = openTransaction.setCustomAnimations(R.anim.enter, R.anim.exit, R.anim.pop_enter, R.anim.pop_exit);
} else {
openTransaction = openTransaction.setCustomAnimations(R.anim.pop_enter, R.anim.pop_exit, R.anim.pop_exit, R.anim.pop_enter);
}
}
openTransaction = openTransaction.replace(R.id.fragmentcontainer, fragment, String.valueOf(fragmentId));
if (addToBackStack) {
String transactionTag = "from" + oldFragmentId + "To" + fragmentId;
openTransaction.addToBackStack(transactionTag);
}
openTransaction.commitAllowingStateLoss();
向后过渡只是:
onBackPressed();
更新
问题不在于repo本身,而在于支持库的版本。本地我只有v26.0.0-alpha1,它似乎在动画问题上完美无缺。我尝试获取存储库的这个确切版本,它没有引起任何问题。我想现在我必须弄清楚为什么我的代码与支持库v26.0.0-alpha1一样工作,但没有任何更新的版本。我最初使用v25.1.0发现了这个问题,所以我仍然没有更接近解决方案,因为它已经出现在神奇版本v26.0.0-alpha1之前,现在也在该版本之后。我认为其他应用可能会遇到同样的问题,但浏览我已安装的应用时,我无法找到使用相同类型的转换。
答案 0 :(得分:0)
我找到了修复!我的所有片段都使用FragmentBase作为它们的超类。在FragmentBase中,我保留了对onCreateAnimations中创建的动画的引用,并且我写了一个函数来在我想的时候取消这些动画。
public abstract class FragmentBase extends Fragment {
private AnimationSet animationWrapper;
public void interruptAnimation() {
if(animationWrapper != null) {
animationWrapper.setDuration(0);
animationWrapper.cancel();
}
}
@Override
public AnimationSet onCreateAnimation(int transit, final boolean enter, final int nextAnim) {
Animation anim;
try {
anim = AnimationUtils.loadAnimation(getActivity(), nextAnim);
} catch (Resources.NotFoundException e) {
return null;
}
AnimationSet animationWrapper = new AnimationSet(false);
animationWrapper.addAnimation(anim);
this.animationWrapper = animationWrapper;
return this.animationWrapper;
}
}
在我的MainActivity中,我保留对当前可见片段(FragmentBase实例)的引用,并在onPause()中调用它们的interruptAnimation()方法。
public class MainActivity extends AppCompatActivity {
FragmentBase _currentFragment;
FragmentBase _previousFragment;
@Override
protected void onPause() {
if(_currentFragment != null) {
_currentFragment.interruptAnimation();
}
if(_previousFragment != null) {
_previousFragment.interruptAnimation();
}
}
}
在MainActivity中的OnBackStackChangedListener I注册中,对_currentFragment和_previousFragment的引用发生了变化。