我正在尝试在回收站视图项(活动 A)和视图寻呼机(活动 B)之间创建一个“简单”的图像共享元素转换。我已经设法使一切变得平滑,但似乎无论我如何设置退出/重新进入/进入/返回转换,从 B 到 A 的转换,当共享元素恢复时,都会闪烁。闪烁是指整个屏幕。
我正在使用 AppCompat 主题和 ActivityCompat 方法以及 A(重新输入)和 B(当使用 Glide 设置图像时)中的 PreDrawListeners 组合。
Heres Activity A相关代码:
private Bundle mReenterState;
@TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override protected void initActivityTransitions() {
super.initActivityTransitions();
getWindow().setSharedElementsUseOverlay(false);
setExitSharedElementCallback(mCallback);
}
private final SharedElementCallback mCallback = new SharedElementCallback() {
@TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {
if (mReenterState != null) {
int startingSelection = mReenterState.getInt(DefinesGlobal.KEY_STARTING_INDEX);
int currentSelection = mReenterState.getInt(DefinesGlobal.KEY_CURRENT_INDEX);
if (startingSelection != currentSelection) {
String newTransitionName = mHotel.getDetail().getHotelImagesGallery().get(currentSelection);
View newSharedElement = mContentView.getGalleryView().getRecyclerViewPager()
.getLayoutManager().findViewByPosition(currentSelection);
if (newSharedElement != null) {
names.clear();
names.add(newTransitionName);
sharedElements.clear();
sharedElements.put(newTransitionName, newSharedElement);
}
}
mReenterState = null;
} else {
// If mReenterState is null, then the activity is exiting.
View navigationBar = findViewById(android.R.id.navigationBarBackground);
View statusBar = findViewById(android.R.id.statusBarBackground);
if (navigationBar != null) {
names.add(navigationBar.getTransitionName());
sharedElements.put(navigationBar.getTransitionName(), navigationBar);
}
if (statusBar != null) {
names.add(statusBar.getTransitionName());
sharedElements.put(statusBar.getTransitionName(), statusBar);
}
}
}
};
@Override public void onActivityReenter(int resultCode, Intent data) {
super.onActivityReenter(resultCode, data);
mReenterState = new Bundle(data.getExtras());
int startingSelection = mReenterState.getInt(DefinesGlobal.KEY_STARTING_INDEX);
int currentSelection = mReenterState.getInt(DefinesGlobal.KEY_CURRENT_INDEX);
if (startingSelection != currentSelection) {
mContentView.getGalleryView().getRecyclerViewPager().scrollToPosition(currentSelection);
}
ActivityCompat.postponeEnterTransition(this);
mContentView.getGalleryView().getRecyclerViewPager().getViewTreeObserver()
.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
mContentView.getGalleryView().getRecyclerViewPager().getViewTreeObserver().removeOnPreDrawListener(this);
mContentView.getGalleryView().getRecyclerViewPager().requestLayout();
ActivityCompat.startPostponedEnterTransition(ViewModelHotelDetailsActivity.this);
return true;
}
});
}
下面是活动 B 相关代码。
私有布尔 mIsReturning;
@Override public void finishAfterTransition() {
mIsReturning = true;
Intent data = new Intent();
data.putExtra(DefinesGlobal.KEY_CURRENT_INDEX, mCurrentSelection);
data.putExtra(DefinesGlobal.KEY_STARTING_INDEX, mStartingSelection);
setResult(RESULT_OK, data);
super.finishAfterTransition();
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override protected void initActivityTransitions() {
super.initActivityTransitions();
ActivityCompat.postponeEnterTransition(this);
setEnterSharedElementCallback(mCallback);
}
private final SharedElementCallback mCallback = new SharedElementCallback() {
@TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {
if (mIsReturning) {
ViewModelFullSizeGalleryFragment fragment =
((FullSizeGalleryPagerAdapter) mPager.getAdapter()).getCurrent();
ImageView sharedElement = fragment.getImageView();
if (sharedElement == null) {
names.clear();
sharedElements.clear();
} else if (mStartingSelection != mCurrentSelection) {
names.clear();
names.add(sharedElement.getTransitionName());
sharedElements.clear();
sharedElements.put(sharedElement.getTransitionName(), sharedElement);
}
}
}
};
活动 B 查看寻呼机片段:
公共类 ViewModelFullSizeGalleryFragment 扩展 ViewModelBaseFragment {
@Override protected int getLayoutId() {
return R.layout.view_model_fragment_full_size_gallery;
}
@Bind(R.id.full_size_image_view) ImageView mImageView;
public static ViewModelFullSizeGalleryFragment newInstance(String url, int position, int
target) {
ViewModelFullSizeGalleryFragment fragment = new ViewModelFullSizeGalleryFragment();
fragment.setUrl(url);
fragment.setIndexAndTarget(position, target);
return fragment;
}
private String mUrl;
private int mPosition;
private int mTarget;
public void setUrl(String url) {
mUrl = url;
}
public void setIndexAndTarget(int position, int target) {
mPosition = position;
mTarget = target;
}
@Override protected void initViewModel(View view) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mImageView.setTransitionName(mUrl);
}
Glide.with(getContext())
.load(mUrl)
.transform(new HotelDetailsImageTransformation(getContext(),
LMTApplication.mWidth))
.diskCacheStrategy(DiskCacheStrategy.ALL)
.skipMemoryCache(true)
.error(R.drawable.ic_nopic)
.into(new SimpleTarget<GlideDrawable>() {
@Override public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) {
if (mImageView != null && resource != null) {
mImageView.setImageDrawable(resource);
mImageView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override public boolean onPreDraw() {
mImageView.getViewTreeObserver().removeOnPreDrawListener(this);
if (mTarget == mPosition)
((ISharedElementCallback) getContext()).onViewReadyForTransition();
return true;
}
});
}
}
});
}
@Override public void onBackPressed() {
//!! Not used.
}
public interface ISharedElementCallback {
void onViewReadyForTransition();
}
public ImageView getImageView() {
return mImageView;
}
还没有弄清楚闪烁实际上是什么......任何帮助都会很大。谢谢。
还。如果它有任何帮助,那么 Activity A 回收器视图后面会有一个地图片段(如果有帮助的话)。