NB Похоже, что это не проблема с PhotoView версии 2.3.0.
PhotoView подвергается двум разметкам при воссоздании дляAPI 23 и ниже.Для API 24+ существует только один проход макета.Что происходит при двух проходах, так это то, что масштаб (матрица), который восстанавливается в onRestoreInstanceState()
из SaveStatePhotoView
, сбрасывается.В вашем коде вы удаляете прослушиватель глобального макета после первого прохода, поэтому, когда матрица сбрасывается на втором проходе макета, вы не перехватываете его.Для API 24+ проходит только один проход, и масштаб восстанавливается и не сбрасывается.Вот почему вы видите проблему для API 23, а не для 24.
Я думаю, что реальное исправление в PhotoView .Ваниль ImageView
также проходит два прохода макета, поэтому я не думаю, что дополнительный проход макета - это то, что PhotoView вызывает.Однако я считаю, что PhotoView неправильно обрабатывает матрицу масштабирования для определенных API.
Вы можете решить эту проблему, установив масштаб на втором проходе для API 24+, выполнив что-то подобное:
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (!(state instanceof SavedState)) {
super.onRestoreInstanceState(state);
return;
}
final SavedState ss = (SavedState) state;
super.onRestoreInstanceState(ss.getSuperState());
getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
private int invocationCount = 0;
// Only one layout pass for M and up. Otherwise, we'll see two and the
// scale set in the first pass is reset during the second pass, so the scale we
// set doesn't stick until the 2nd pass.
@Override
public void onGlobalLayout() {
setScale(Math.min(ss.scale, getMaximumScale()), getWidth() * ss.pivotX,
getHeight() * ss.pivotY, false);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M || ++invocationCount > 1) {
getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
}
});
}
Предыдущее основано на прилагаемом демонстрационном приложении, работающем PhotoView версия 1.3.1.