При переходе к общему элементу Android весь экран мерцает при повторном входе

Я пытаюсь создать «простой» переход общего элемента изображения между элементом представления ресайклера (действие A) и просмотром пейджера (действие B). Мне удалось все сгладить, но кажется, что независимо от того, как я устанавливаю переходы выхода/повторного входа/входа/возврата, переход обратно от B к A, когда общий элемент устанавливается обратно, мерцает. И под мерцанием я подразумеваю весь экран.

Я использую темы AppCompat и методы ActivityCompat с комбинациями PreDrawListeners как в A (повторный ввод), так и в B (когда изображение установлено с помощью Glide).

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;
        }
    });
}

Вот код, связанный с Activity 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);
            }
        }
    }
};

Фрагмент пейджера вида Activity 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, если это поможет.




Ответы (1)


Помогает ли установка android:windowSharedElementsUseOverlay (внутри XML-файла темы Activity) значения false решить вашу проблему?

person VladimirVip    schedule 22.01.2017
comment
Это устранило аналогичную проблему, с которой я столкнулся с волновым эффектом для элементов RecyclerView. Спасибо ! - person Arthur Attout; 19.08.2019
comment
Благодаря тебе я теперь могу спать Т_Т - person Hocine B; 19.11.2019