OnGlobalLayout различать различные вызовы
У меня есть вид логотипа, который является полноэкранным фрагментом, содержащим одиночный ImageView
.
Я должен выполнить некоторые операции после того, как изображение логотипа будет полностью видимым.
Следующий код используется для вызова специальной задачи
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ImageView logoImageMaster = new ImageView(getContext());
//logoImageMaster.setImageResource(resID); //even after removing this, i am getting the callback twice
try {
// get input stream
InputStream ims = getActivity().getAssets().open("product_logo.png");
// load image as Drawable
Drawable d = Drawable.createFromStream(ims, null);
// set image to ImageView
logoImageMaster.setImageDrawable(d);
}
catch(IOException ex) {
}
logoImageMaster.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() { //FIXME get called twice. Check this out, no info to distinguish first from second
// Log.e("PANEL", "onGlobalLayout of Logo IV ---------------------------------");
activityInterface.doSpecialLogic();
}
});
return logoImageMaster;
}
Моя конкретная проблема: onGlobalLayout
вызывается дважды для этой иерархии представлений.
Я знаю, что onGlobalLayout
вызывается в performTraversal
of View.java
, поэтому это ожидается.
В случае использования одного родительского элемента с одиночным дочерним представлением я хочу различать атрибуты вида, чтобы doSpecialLogic
вызывается один раз [onGlobalLayout
вызывается дважды], после того, как изображение логотипа полностью становится видимым.
Пожалуйста, предложите несколько идей.
Ответы
Ответ 1
OnGlobalLayoutListener вызывается каждый раз при изменении макета представления или видимости. Может быть, вы reset мнения в вашем вызове doSpecialLogic?
изменить
как указывал @Guille89, два заданных вызова вызывают onGlobalLayout, которые вызывают два раза
Во всяком случае, если вы хотите вызвать OnGlobalLayoutListener только один раз и не нуждаетесь в нем ни для чего другого, как насчет его удаления после вызова doSpecialLogic()
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
//noinspection deprecation
logoImageMaster.getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
logoImageMaster.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
activityInterface.doSpecialLogic();
Ответ 2
Кажется, он называется одним раз для каждого набора, выполненного над imageView
logoImageMaster.setImageResource(resID);
logoImageMaster.setImageDrawable(d);
Ответ 3
Вам следует попробовать использовать плагин kotlin в android
Этот приемник макета обычно используется для выполнения чего-то после измерения вида, поэтому вам обычно нужно подождать, пока ширина и высота не превысят 0. И мы, вероятно, хотим что-то сделать с видом, который вызвал его, в вашем дело
ImageView
Таким образом, эта функция была сгенерирована таким образом, чтобы ее можно было использовать любым объектом, который расширяет представление, а также может иметь доступ ко всем своим конкретным функциям и свойствам из функции
[kotlin]
inline fun <T: View> T.afterMeasured(crossinline f: T.() -> Unit) {
viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
if (measuredWidth > 0 && measuredHeight > 0) {
viewTreeObserver.removeOnGlobalLayoutListener(this)
f()
}
}
})
}
[/kotlin]
Примечание:
убедитесь, что ImageView правильно описан в макете. Это его layout_width и layout_height не должны быть wrap_content. Более того, другие представления не должны приводить к тому, что этот ImageView имеет размер 0.