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
的View.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大小。