onGlobalLayout区分各种调用

时间:2016-08-02 11:00:04

标签: android android-view android-viewgroup

我有一个徽标视图,这是一个包含单个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的{​​{1}}中调用了performTraversal,因此这是预期的。

对于具有单个子视图的单亲的用例,我希望区分视图属性,以便在完全制作徽标图像后,在{View.java被调用两次后调用doSpecialLogic可见。 请提出一些想法。

3 个答案:

答案 0 :(得分:5)

每次视图布局或可见性更改时都会调用OnGlobalLayoutListener。也许您重置了doSpecialLogic调用中的视图??
修改 正如@ Guille89指出的那样,两个set调用导致onGlobalLayout被调用两次

无论如何,如果你想只调用一次OnGlobalLayoutListener并且不需要它,那么在doSpecialLogic()调用之后如何删除它呢?

$user

答案 1 :(得分:1)

对于在imageView

上完成的每个集合,似乎都会调用一次
logoImageMaster.setImageResource(resID);

logoImageMaster.setImageDrawable(d);

答案 2 :(得分:1)

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

此布局侦听器通常用于在测量视图后执行某些操作,因此您通常需要等到宽度和高度大于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大小。