2016-05-09 182 views
4

即使沒有監聽器連接,也會調用全局佈局監聽器,在這種情況下會得到一個循環,如何在不觸發全局佈局監聽器的情況下編輯屬性?謝謝Android全局佈局監聽器在android中重複調用

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); 

       } 
      }); 
+0

變化'getDecorView.getViewTreeObserver()addOnGlobalLayoutListener(本);''到getDecorView.getViewTreeObserver()removeOnGlobalLayoutListener(本);'裏面你'onGlobalLayout()' – NSimon

+0

@NicolasSimon是對的,你在每次調用結束時重新附加'GlobalLayoutListener',這就是重複調用它的原因。刪除該行。 – roarster

+0

@roarster這就是我想要做的事情,除了設置文本之外,我希望它被解僱,這就是爲什麼我在刪除後附加監聽器的原因,我該如何實現?謝謝。 – Mike

回答

3

這類解決了你的問題:

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原本不具備文字等於「更新」,所以當你其文本設置爲「已更新「它是一種標誌,所以你不會在未來重新設置它。您也可以執行以下操作,恕我直言,因爲您有一個實際的布爾標誌,表示您是否應該更新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更新導致另一個佈局傳遞導致......和。

+0

我有很多意見要在這一點上更新,所以檢查ifs對我來說會是一個大問題,爲什麼它會被解僱,即使在設置時沒有監聽者,但稍後添加它,你有什麼想法嗎?謝謝:) – Mike

+0

'getDecorView.post(新的Runnable(){@Override 公共 無效的run(){ getDecorView.getViewTreeObserver()addOnGlobalLayoutListener(監聽);} });'這一個工作,爲什麼你認爲這個工作?謝謝 – Mike

+0

啊,我完全忘了'View#post()'!它所做的是將'Runnable'添加到UI消息隊列中,該隊列在下一次迭代中運行。所以你添加'Runnable',然後Android決定更新'TextViews',並因此觸發UI線程上的任何消息運行,所以你的'Runnable'運行。對此有一些很好的解釋,但是你可能會發現它有時會起作用,並且在其他時候不起作用。你可以試試'View#postDelayed()',但我認爲你應該對你有什麼好:) – roarster

0

這一個問題解決了

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); 
        } 
       });