Фрагменты ViewPager - переходы общего элемента
Приложение, которое я разрабатываю, отображает сетку изображений. Когда вы нажимаете на изображение, оно переходит в подробный вид. Подробное представление содержит ViewPager, который позволяет перемещаться между каждым изображением в сетке. Это делается путем передачи списков путей (содержащих каждое изображение в сетке) вместе со смещением изображения, к которому было произведено касание, так что ViewPager может быть настроен для первоначального отображения этой страницы.
Каков наилучший способ сделать переход общего элемента внутри фрагмента текущей страницы смещения в ViewPager? Изображение сетки (RecyclerView) должно развернуться в полноэкранное изображение на текущей странице. Я видел возможность откладывать и возобновлять переходы активности, поэтому приложение будет ожидать отображения перехода общего элемента, пока изображение не будет загружено с диска. Но я хочу иметь возможность анимировать его на нужной странице в пейджере, а также выходить на текущую страницу, когда пользователь возвращается (поскольку вы можете перемещаться между страницами). Если вы проведете пальцем по другой странице сейчас, начальная страница - это то, что оживляет обратно в сетку.
В настоящее время я присваиваю каждое изображение во фрагментах пейджера представления с transitionName в формате "image_[index]". Когда я запускаю операцию детализации, я использую то же имя transitionName, где индексом является смещение.
В связи с этим мне также было интересно, как заставить пульсации работать при длинных нажатиях. Когда вы изменяете активированное состояние вида, кажется, что он отменяет пульсации. Мне нужен эффект, похожий на Gmail, когда пульсация начинается снова и быстро заканчивается после длительного нажатия и вызывает активированное состояние.
2 ответа
Из того, что я могу сказать (и поправьте меня, если я ошибаюсь), то, что вы пытаетесь достичь, в основном примерно так: Предположим, у вас есть MainActivity
, DetailsActivity
и произвольный набор изображений. MainActivity
отображает набор изображений в сетке и DetailsActivity
отображает тот же набор изображений в горизонтальном ViewPager
, Когда пользователь выбирает изображение в MainActivity
, это изображение должно перейти от своей позиции в сетке к правильной странице во втором упражнении ViewPager
,
Проблема, которую мы хотим решить: "что если пользователь переключает страницы внутри DetailsActivity
"? Если это произойдет, мы хотим изменить совместно используемое изображение, которое будет использоваться во время обратного перехода. По умолчанию инфраструктура перехода активности будет использовать общий элемент, который использовался во время перехода перехода... но страница пейджера просмотра имеет изменилось так очевидно, что мы хотим как-то переопределить это поведение. Для этого нам нужно установить SharedElementCallback
в вашем MainActivity
а также DetailsActivity
"s 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, который достигнет этого эффекта (слишком много кода для публикации в одном ответе Stackru).
Я предполагаю, что вы используете переходы фрагментов и что вы не анимируете между действиями. Это возможно как в переходах активности, так и в переходах фрагментов, но конкретный код немного отличается. Однако откладывание недоступно для переходов фрагментов.
AddSharedElement принимает второй параметр. Если вы знаете конкретное имя в целевом фрагменте при вызове, вы можете просто выбрать имя в фрагменте сведений для использования. Если вы этого не сделаете, вы можете выбрать любое имя, которое вам нужно, и переназначить его с помощью SharedElementCallback, установленного во фрагменте.
fragment.setEnterSharedElementCallback(new SharedElementCallback() {
@Override
public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {
sharedElements.put("detailView", mTargetDetailView);
}
});
Если он не совпадает на обратном пути, делается тот же вызов, чтобы переназначить его. Вероятно, это будет как в вызывающем фрагменте, так и в вызываемом фрагменте - в вызывающем фрагменте вы используете setExitSharedElementCallback. Я ожидаю, что это так в вашем приложении.
Аналогично, в переходах действия вы устанавливаете тот же SharedElementCallback и используете то же отображение, но вместо этого делаете это в действии.