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是在performTraversalView.java调用的,因此这是预期的。

对于单亲子视图的使用情况,我想区分视图属性,使得doSpecialLogic被调用一次[ onGlobalLayout被调用两次],在标识图像完全可见之后。 请提出一些想法。

每当视图布局或可见性发生更改时,OnGlobalLayoutListener都会被调用。 也许你重置你的doSpecialLogic调用的意见?
编辑为@Guille89指出,这两个set调用导致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(); 

它似乎被称为每一个完成了imageView的一次

 logoImageMaster.setImageResource(resID); logoImageMaster.setImageDrawable(d); 

你应该尝试在android中使用kotlin插件

这个布局监听器通常用来在测量视图之后做些事情,所以你通常需要等到width和height都大于0。而且我们可能希望对调用它的视图做些什么,在你的情况下Imageview

因此,使函数生成化,以便任何扩展了View的对象都可以使用它,并且可以从函数访问所有特定的函数和属性

 [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大小。