0

我正在尝试在回收站视图项(活动 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 回收器视图后面会有一个地图片段(如果有帮助的话)。

4

1 回答 1

4

设置 android:windowSharedElementsUseOverlay(在您的 Activity 的 XML 主题文件中)是否可以解决您的问题?

于 2017-01-22T15:52:20.823 回答