如何解决Android过渡动画在26以下的API中不起作用
我尝试创建一个WhatsApp之类的个人资料偏好设置,其中个人资料照片与个人资料活动共享。我使用了以下代码,这些代码可在Android 8及更高版本中正常运行。但是在Android 7及更低版本中,共享元素动画不起作用。 This是对API 21进行测试的结果。
不符代码已被删除。
SettingsActivity.java:
public class SettingsActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
setupToolbar();
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.pref_content,new MainPreferenceFragment())
.commit();
}
private void setupToolbar() {
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
try {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
} catch (NullPointerException e) {
e.printStackTrace();
}
}}
MainPreferenceFragment.java:
import android.transition.TransitionInflater;
import androidx.core.app.ActivityOptionsCompat;
import androidx.preference.ListPreference;
import androidx.transition.Explode;
import androidx.transition.Fade;
import androidx.transition.Transition;
public class MainPreferenceFragment extends PreferenceFragmentCompat {
public static final String KEY_PROFILE = "pref_profile_key";
private File myPhotoFile;
private int profileIconSize;
private Preference profile;
@Override
public void onCreatePreferences(Bundle savedInstanceState,String rootKey) {
setPreferencesFromResource(R.xml.preferences,rootKey);
Context context = getContext();
initPreferences(context);
setListeners(context);
}
@Override
public void onResume() {
super.onResume();
profile.setTitle(MainBroadcastReceiver.getMyDeviceName());
if (myPhotoFile.exists()) {
profile.setIcon(
new BitmapDrawable(getResources(),ThumbnailUtils.extractThumbnail(
BitmapFactory.decodeFile(myPhotoFile.getPath()),profileIconSize,profileIconSize)));
} else {
profile.setIcon(R.drawable.avatar_contact);
}
}
private void initPreferences(Context context) {
profile = findPreference(KEY_PROFILE);
profile.setSummary(MainBroadcastReceiver.getMyDeviceMacAddress());
myPhotoFile = FileManager.myPhotoFile(context);
profileIconSize = ActivityManager.dp2px(context,67F);
}
private void setListeners(Context context) {
profile.setOnPreferenceClickListener(preference -> {
AppCompatActivity activity = (AppCompatActivity) getActivity();
Intent intent = new Intent(activity,ProfileActivity.class);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
activity.getWindow().setExitTransition(TransitionInflater.from(activity).inflateTransition(R.transition.fade));
View profileView = getListView().getChildAt(profile.getOrder());
ImageView profileImageView = profileView.findViewById(android.R.id.icon);
ActivityOptionsCompat options = ActivityOptionsCompat
.makeSceneTransitionAnimation(activity,profileImageView,profileImageView.getTransitionName());
startActivity(intent,options.toBundle());
} else {
startActivity(intent);
}
return true;
});
}}
preference_profile.xml:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/chat_row_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true">
<LinearLayout
android:layout_width="0dp"
android:layout_height="1dp"
android:background="?attr/dividerColor"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:layout_marginRight="12dp"
android:ellipsize="end"
android:gravity="start"
android:maxLines="1"
android:singleLine="true"
android:text="Okay,Bye."
android:textAlignment="gravity"
android:textColor="?android:attr/textColorSecondary"
android:textSize="14sp"
android:transitionName="macTransition"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="@android:id/title"
app:layout_constraintTop_toBottomOf="@android:id/title" />
<TextView
android:id="@android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginLeft="15dp"
android:ellipsize="end"
android:gravity="start"
android:maxLines="1"
android:singleLine="true"
android:text="Robert Downey"
android:textAlignment="gravity"
android:textColor="@android:color/black"
android:textSize="22sp"
android:transitionName="nameTransition"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toTopOf="@android:id/summary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintStart_toEndOf="@android:id/icon"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />
<de.hdodenhof.circleimageview.CircleImageView
android:id="@android:id/icon"
android:layout_width="67dp"
android:layout_height="67dp"
android:layout_marginStart="14dp"
android:layout_marginLeft="14dp"
android:layout_marginTop="17dp"
android:layout_marginBottom="17dp"
android:src="@drawable/avatar_contact"
android:transitionName="imageTransition"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
preferences.xml:
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.preference.Preference
android:icon="@drawable/avatar_contact"
android:key="pref_profile_key"
android:layout="@layout/preference_profile"
android:summary="u:n:k:n:o:w:n"
android:title="@string/unknown" />
</androidx.preference.PreferenceScreen>
ProfileActivity.java:
import android.transition.Transition;
import android.transition.TransitionInflater;
public class ProfileActivity extends BaseActivity {
private SimpleDraweeView imageDrawee;
private ImageView setImageImageView;
private boolean isBackPressed = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
setupTransition();
}
private void setupTransition() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().setAllowEnterTransitionOverlap(true);
Transition fade = TransitionInflater.from(this).inflateTransition(R.transition.fade);
fade.excludeTarget(R.id.setImage,true);
getWindow().setEnterTransition(fade);
getWindow().getSharedElementEnterTransition().addListener(new Transition.TransitionListener() {
@Override
public void onTransitionStart(Transition transition) {
}
@Override
public void onTransitionEnd(Transition transition) {
if (!isBackPressed) {
setImageImageView.setVisibility(View.VISIBLE);
ScaleAnimation scaleUp = new ScaleAnimation(0f,1f,0f,Animation.RELATIVE_TO_SELF,0.5f,0.5f);
scaleUp.setDuration(150);
scaleUp.setFillAfter(true);
setImageImageView.startAnimation(scaleUp);
}
}
@Override
public void onTransitionCancel(Transition transition) {
}
@Override
public void onTransitionPause(Transition transition) {
}
@Override
public void onTransitionResume(Transition transition) {
}
});
} else {
setImageImageView.setVisibility(View.VISIBLE);
ScaleAnimation scaleUp = new ScaleAnimation(0f,0.5f);
scaleUp.setDuration(150);
scaleUp.setFillAfter(true);
setImageImageView.startAnimation(scaleUp);
}
}
@Override
public void onBackPressed() {
isBackPressed = true;
ScaleAnimation scaleUp = new ScaleAnimation(1f,0.5f);
scaleUp.setDuration(150);
scaleUp.setFillAfter(true);
scaleUp.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
setImageImageView.setVisibility(View.INVISIBLE);
ProfileActivity.super.onBackPressed();
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
setImageImageView.startAnimation(scaleUp);
}}
activity_profile.xml:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/image"
android:layout_width="160dp"
android:layout_height="160dp"
android:layout_marginTop="24dp"
android:transitionName="imageTransition"
app:actualImageScaleType="centerCrop"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/appbar"
app:placeholderImage="@drawable/ic_settings_profile"
app:placeholderImageScaleType="centerCrop"
app:roundAsCircle="true" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/setImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="2dp"
android:layout_marginRight="2dp"
android:layout_marginBottom="2dp"
android:clickable="true"
android:focusable="true"
android:src="@drawable/ic_home_camera"
android:tint="@color/white"
android:visibility="invisible"
app:backgroundTint="@color/colorPrimaryLight"
app:fabCustomSize="48dp"
app:layout_constraintBottom_toBottomOf="@+id/image"
app:layout_constraintEnd_toEndOf="@+id/image"
app:rippleColor="@color/white" />
</androidx.constraintlayout.widget.ConstraintLayout>
syles.xml:
<resources>
<style name="AppTheme.Base" parent="Theme.AppCompat.Light.NoActionBar" />
<style name="AppTheme" parent="AppTheme.Base">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
styles.xml(v21):
<resources>
<style name="AppTheme.Base" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowActivityTransitions">true</item>
<item name="android:windowEnterTransition">@transition/explode</item>
<item name="android:windowExitTransition">@transition/explode</item>
<item name="android:windowSharedElementEnterTransition">
@transition/change_image_transform
</item>
<item name="android:windowSharedElementExitTransition">
@transition/change_image_transform
</item>
</style>
</resources>
change_image_transition.xml:
<transitionSet>
<changeImageTransform />
<changeBounds />
</transitionSet>
explode.xml(v21):
<explode xmlns:android="http://schemas.android.com/apk/res/android">
<targets>
<target android:excludeId="@android:id/statusBarBackground" />
<target android:excludeId="@android:id/navigationBarBackground" />
<target android:excludeId="@id/appbar" />
</targets>
</explode>
fade.xml(v21):
<fade xmlns:android="http://schemas.android.com/apk/res/android">
<targets>
<target android:excludeId="@android:id/statusBarBackground" />
<target android:excludeId="@android:id/navigationBarBackground" />
<target android:excludeId="@id/appbar" />
</targets>
</fade>
解决方法
26以下简单的API具有不同的内容,因此您可能要考虑用api 26及以下版本中的另一个替换动画(以及其他内容,但通常在此应用程序中可能没有,您可以谷歌搜索并转到andoid official website检查一下。 因此,简单地说,您可能不是拥有api 26及以下版本的大多数设备。 还要考虑在物理设备上进行测试。
转到此处,并确保在api下拉菜单的左上方选择26。 https://developer.android.com/reference/android/view/animation/package-summary 祝你好运
,我找到了此问题的原因和解决方案。问题不是我在问题中编写的代码,而是我在BaseActivity
中使用动态语言。我在Android 7及更低版本中实现的动态语言每次都通过onResume
方法重新创建活动。每次重新创建活动时,过渡动画都不会起作用。为了解决此问题,我为ProfileActivity
禁用了动态语言。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。