(轉)onWindowFocusChanged觸發簡介

weixin_34041003發表於2016-11-06

轉自:http://blog.csdn.net/yueqinglkong/article/details/44981449

看看原始碼中對該方法的說明:
Called when the current Android.view.Window

of the activity gains or loses focus. This is the best indicator of whether this activity is visible to the user. The default implementation clears the key tracking state, so should always be called.
Note that this provides information about global focus state, which is managed independently of activity lifecycles. As such, while focus changes will generally have some relation to lifecycle changes (an activity that is stopped will not generally get window focus), you should not rely on any particular order between the callbacks here and those in the other lifecycle methods such asonResume()

.
As a general rule, however, a resumed activity will have window focus... unless it has displayed other dialogs or popups that take input focus, in which case the activity itself will not have focus when the other windows have it. Likewise, the system may display system-level windows (such as the status bar notification panel or a system alert) which will temporarily take window input focus without pausing the foreground activity.
大概意思:
當前窗體得到或失去焦點的時候的時候呼叫。這是這個活動是否是使用者可見的最好的指標。預設的實現清除重點跟蹤狀態,所以應該總是被呼叫。請注意,這提供了有關整體焦點狀態資訊,這是獨立管理活動的生命週期。因此,焦點的變化通常會有一些關係生命週期變化(一種活動停止一般不會得到視窗焦點),你應該不依賴於任何特定的順序之間的回撥在這裡和那些在其他生命週期方法如onresume()。作為一般規則,然而,一個恢復活動將得到視窗焦點…除非有其他對話方塊彈出視窗顯示或接受輸入焦點,在這種情況下,活動本身不會有焦點時,其他視窗擁有它。同樣,系統會顯示系統頂層視窗(如狀態列通知皮膚或警報系統)將暫時不停頓的前臺活動帶視窗的輸入焦點。
在Activity的生命週期中,onCreate()--onStart()--onResume()都不是窗體Visible的時間點,真正的窗體完成初始化可見獲取焦點可互動是在onWindowFocusChanged()方法被執行時,而這之前,對使用者的操作需要做一點限制。比如我們在做OTT專案時候,我們就是在這onWindowFocusChanged來獲取主按鍵的具體位置和寬高的,而在其他標準生命週期的介面中呼叫都是獲取不到的,比如在onResume,onStart中都獲取不到資訊。這個onWindowFocusChanged指的是這個Activity得到或者失去焦點的時候 就會call。。也就是說 如果你想要做一個Activity一載入完畢,就觸發什麼的話 完全可以用這個!!!使用一個view的getWidth() getHeight() 方法來獲取該view的寬和高,返回的值卻為0。如果這個view的長寬很確定不為0的話,那很可能是你過早的呼叫這些方法,也就是說在這個view被加入到rootview之前你就呼叫了這些方法,返回的值自然為0.

下面測試程式碼:

public class MainActivity extends Activity {  

    private String Tag = "MainActivity";  
  
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        init();  
        Log.d(Tag, "onCreate");  
    }  
  
    public void init() {  
        Button nextBtn = (Button) findViewById(R.id.btn_next);  
        nextBtn.setOnClickListener(new View.OnClickListener() {  
            @Override  
            public void onClick(View v) {  
                Intent intent = new Intent();  
                intent.setClass(MainActivity.this, NextActivity.class);  
                startActivity(intent);  
            }  
        });  
        Button nextBackBtn = (Button) findViewById(R.id.btn_next_back);  
        nextBackBtn.setOnClickListener(new View.OnClickListener() {  
            @Override  
            public void onClick(View v) {  
                Intent intent = new Intent();  
                intent.setClass(MainActivity.this, NextActivity.class);  
                startActivityForResult(intent, 10);  
            }  
        });  
  
        Button dialogBtn = (Button) findViewById(R.id.btn_dialog);  
        dialogBtn.setOnClickListener(new View.OnClickListener() {  
            @Override  
            public void onClick(View v) {  
                new AlertDialog.Builder(MainActivity.this)  
                        .setTitle("確認")  
                        .setMessage("確定嗎?")  
                        .setPositiveButton("是", null)  
                        .setNegativeButton("否", null)  
                        .show();  
            }  
        });  
    }  
  
    @Override  
    protected void onStart() {  
        super.onStart();  
        Log.d(Tag, "onStart");  
    }  
  
    @Override  
    protected void onResume() {  
        super.onResume();  
        Log.d(Tag, "onResume");  
    }  
  
    @Override  
    public void onAttachedToWindow() {  
        super.onAttachedToWindow();  
        Log.d(Tag, "onAttachedToWindow");  
    }  
  
    @Override  
    public void onWindowFocusChanged(boolean hasFocus) {  
        super.onWindowFocusChanged(hasFocus);  
        if (hasFocus) {  
            Log.d(Tag, "onWindowFocusChanged:" + "true");  
        } else {  
            Log.d(Tag, "onWindowFocusChanged:" + "false");  
        }  
    }  
  
    @Override  
    protected void onPause() {  
        super.onPause();  
        Log.d(Tag, "onPause");  
    }  
  
    @Override  
    protected void onStop() {  
        super.onStop();  
        Log.d(Tag, "onStop");  
    }  
  
    @Override  
    protected void onDestroy() {  
        super.onDestroy();  
        Log.d(Tag, "onDestroy");  
    }  
  
    @Override  
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
        super.onActivityResult(requestCode, resultCode, data);  
        Log.d(Tag, "onActivityResult");  
    }  

}  

跳轉的頁面:

public class NextActivity extends Activity {  

    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_next);  
        init();  
    }  
  
    public void init() {  
        Button backBtn = (Button) findViewById(R.id.btn_setback);  
        backBtn.setOnClickListener(new View.OnClickListener() {  
            @Override  
            public void onClick(View v) {  
                setResult(15, null);  
                finish();  
            }  
        });  
    }  
    
}  

執行效果,在圖中標註的很詳細了:

1318893-4ca094242cd5dfac.png
20150410164920239.png
1318893-6e01ce424269dd16.png
20150410164938244.png

注意:
1.token null is not valid; is your activity running:
在窗體不能互動的時候,彈出對話方塊之類有可能會報錯,在初始化過程中,講與其他視窗有關的操作放到獲取到焦點後操作。

  /**  
   * bug :unable to add window -- token null is not  
   * 新增窗體在檢視初始化完成過後  
   *  
   * @param hasFocus  
   */  
  @Override  
  public void onWindowFocusChanged(boolean hasFocus) {  
      super.onWindowFocusChanged(hasFocus);  
      if (hasFocus) {  
         //add Window.....  
      }  
  }  

相關文章