Android全局布局监听器在android中反复调用

时间:2016-05-09 12:37:26

标签: android android-layout

即使没有附加侦听器,也会调用添加全局布局侦听器,在这种情况下它会进入循环,如何编辑属性而不在循环中触发全局布局侦听器?谢谢

final View getDecorView = activity.getWindow().getDecorView();
            getDecorView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {

                    if (Build.VERSION.SDK_INT > 16) {
                        getDecorView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    } else {
                        getDecorView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                    }

                    final TextView textView3 = (TextView) decorView.findViewById(2131558456);
                    if (textView3 != null) {
                                textView3.setText("updated");                      textView3.setBackgroundColor(Color.parseColor("#444444"));
                    }

                    getDecorView.getViewTreeObserver().addOnGlobalLayoutListener(this);

                }
            });

2 个答案:

答案 0 :(得分:4)

这种解决了你的问题:

final View decorView = activity.getWindow().getDecorView();
final TextView textView3 = (TextView) decorView.findViewById(2131558456);
decorView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {

        if (Build.VERSION.SDK_INT > 16) {
            decorView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        } else {
            decorView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
        }


        if (textView3 != null && !textView3.getText().equals("updated")) {
            textView3.setText("updated");
            textView3.setBackgroundColor(Color.parseColor("#444444"));
        }

        decorView.getViewTreeObserver().addOnGlobalLayoutListener(this);

    }
});

我假设textview3原来没有等待"更新"的文字,所以当你将文字设置为"更新"时,它可以作为一种旗帜,以便您将来不再设置它。您还可以执行以下操作,其中IMHO更清晰,因为您有一个实际的布尔标志,表示您是否应该更新TextView

final View decorView = activity.getWindow().getDecorView();
final TextView textView3 = (TextView) decorView.findViewById(2131558456);
decorView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

    boolean updateTextview = true;

    @Override
    public void onGlobalLayout() {

        if (Build.VERSION.SDK_INT > 16) {
            decorView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        } else {
            decorView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
        }


        if (textView3 != null && updateTextview) {
            updateTextview = false;
            textView3.setText("updated");
            textView3.setBackgroundColor(Color.parseColor("#444444"));
        }

        decorView.getViewTreeObserver().addOnGlobalLayoutListener(this);

    }
});

这两个解决方案都应该有效,因为它们会停止textview3的不断更新,从而导致另一个布局传递,导致更新textview3,从而导致另一个布局传递,导致......并且。

答案 1 :(得分:1)

这个解决了问题

final ViewTreeObserver.OnGlobalLayoutListener listener = this;

                if (Build.VERSION.SDK_INT > 16) {
                    getDecorView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                } else {
                    getDecorView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                }

                final TextView textView3 = (TextView) decorView.findViewById(2131558456);
                if (textView3 != null) {
                    textView3.setText("fert");
                    textView3.setBackgroundColor(Color.parseColor("#444444"));
                }

                getDecorView.post(new Runnable() {
                    @Override
                    public void run() {
                        getDecorView.getViewTreeObserver().addOnGlobalLayoutListener(listener);
                    }
                });