Подтвердить что ты не робот

Фрагменты ViewPager - переходы с общим элементом

Приложение, которое я разрабатываю, отображает сетку изображений. Когда вы нажимаете изображение, оно переходит в представление деталей. В представлении сведений содержится ViewPager, который позволяет прокручивать каждое изображение в сетке. Это делается путем передачи списков путей (содержащих каждое изображение в сетке) вместе со смещением изображения, которое было нажато, чтобы ViewPager можно было установить для отображения этой страницы вначале.

Какой лучший способ иметь общий переход элемента внутри фрагмента текущей страницы смещения в ViewPager? Изображение сетки (RecyclerView) должно отображаться на полном экране в текущей странице. Я видел возможность отложить и возобновить переходы активности, поэтому приложение будет ждать, пока отобразит переход общего элемента, пока изображение не будет загружено с диска. Но я хочу, чтобы он мог оживить правильную страницу на пейджере представления, а также выйти на любую текущую страницу, когда пользователь вернется (поскольку вы можете провести между страницами). Если теперь вы перейдете на другую страницу, начальная страница - это то, что оживляет обратно в сетку.

В настоящее время я назначаю каждое изображение в Фрагментах пейджера представления с именем перехода в формате "image_ [index]". Когда я начинаю работу с деталями, я использую одно имя перехода с индексом, являющимся смещением.

В связи с этим мне также было интересно, как заставить рябь работать с длинными нажатиями. Когда вы меняете активированное состояние просмотра, оно, похоже, отменяет пульсацию. Мне нужен эффект, похожий на Gmail, где пульсация начинается снова и быстро заканчивается после того, как длинное нажатие завершено и запускает активированное состояние.

4b9b3361

Ответ 1

Из того, что я могу сказать (и исправьте меня, если я ошибаюсь), то, что вы пытаетесь достичь, в основном примерно так: предположим, что у вас есть MainActivity, a DetailsActivity и произвольный набор изображений, MainActivity отображает набор изображений в сетке, а DetailsActivity отображает один и тот же набор изображений в горизонтальном ViewPager. Когда пользователь выбирает изображение в MainActivity, это изображение должно перейти от своего положения в сетке к правильной странице во втором действии ViewPager.

Проблема, которую мы хотим решить, - "что, если пользователь переключает страницы внутри DetailsActivity"? Если это произойдет, мы хотим изменить общий образ, который будет использоваться во время обратного перехода. По умолчанию структура перехода к действию будет использовать общий элемент, который использовался во время перехода ввода... но страница пейджера просмотра изменилась, поэтому, очевидно, мы хотим как-то переопределить это поведение. Для этого нам нужно установить SharedElementCallback в ваших методах MainActivity и DetailsActivity onCreate() и переопределить метод onMapSharedElements() следующим образом:

private final SharedElementCallback mCallback = new SharedElementCallback() {
    @Override
    public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {
        if (mCurrentImagePosition != mOriginalImagePosition) {
            View sharedView = getImageAtPosition(mCurrentImagePosition);
            names.clear();
            sharedElements.clear();
            names.add(sharedView.getTransitionName());
            sharedElements.put(sharedView.getTransitionName(), sharedView);
        }
    }

    /**
     * Returns the image of interest to be used as the entering/returning
     * shared element during the activity transition.
     */
    private View getImageAtPosition(int position) {
        // ...
    }
};

Для более полного решения я создал образец проекта на GitHub, который достигнет этого эффекта (слишком много кода для сообщение в одном ответе StackOverflow).

Ответ 2

Я предполагаю, что вы используете Fragment Transitions и что вы не оживляете действия. Это возможно в обоих переходах активности и переходах фрагментов, но конкретный код немного отличается. Однако отсрочка недоступна для переходов фрагментов.

В addSharedElement используется второй параметр. Если вы знаете конкретное имя в целевом фрагменте, когда вы его вызываете, вы можете просто выбрать имя в фрагменте детали для использования. Если вы этого не сделаете, вы можете выбрать любое имя и переназначить его с помощью SharedElementCallback, установленного на фрагменте.

fragment.setEnterSharedElementCallback(new SharedElementCallback() {
    @Override
    public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {
        sharedElements.put("detailView", mTargetDetailView);
    }
});

Если это не соответствует обратному пути, тот же вызов выполняется для его переназначения. Вероятно, это будет как в вызывающем фрагменте, так и в вызываемом фрагменте - на вызывающем фрагменте вы используете setExitSharedElementCallback. Я ожидаю, что это будет в вашем приложении.

Аналогично, в Activity Transitions вы устанавливаете один и тот же SharedElementCallback и используете одно и то же сопоставление, но вы делаете это вместо действия.