Android レイアウトXMLで指定したViewの幅・高さの取得


## Activityの場合
従来のActivityベースのアプリの場合、『onWindowFocusChanged()』で取得すればよいです。

```java:MainActivity.java
public class MainActivity extends AppCompatActivity {

    private LinearLayout topContainer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        topContainer = (LinearLayout) findViewById(R.id.top_container);
        // Width = 0, Height = 0
        Log.i("", "MainActivity#onCreate() " +
                "Width = " + String.valueOf(topContainer.getWidth()) + ", " +
                "Height = " + String.valueOf(topContainer.getHeight()));

    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        // Width = 1440, Height = 525
        Log.i("", "MainActivity#onWindowFocusChanged() " +
                "Width = " + String.valueOf(topContainer.getWidth()) + ", " + 
                "Height = " + String.valueOf(topContainer.getHeight()));
    }
}
```

## Fragmentの場合
### 方法1 独自のインターフェースで実装する
* [how to get the onWindowFocusChanged on Fragment?](http://stackoverflow.com/questions/30129984/how-to-get-the-onwindowfocuschanged-on-fragment)
* 独自のインターフェースを定義して、ActivityでonWindowFocusChanged()が呼ばれた際に、Fragmentにも通知する。
* FragmentとActivityの結びつきが強くなってしまう可能性がある。

### 方法2 OnGlobalLayoutListener#onGlobalLayout()を利用する
* onGlobalLayout()でレイアウトに変化があった場合に値を取得します。
* OnGlobalLayoutListenerは、レイアウトが変化する度に呼ばれるので、再取得が不要な場合には、リスナーを削除しておきます。

```java:MainActivityFragment.java

public class MainActivityFragment extends Fragment {

    public MainActivityFragment() {
    }

    private LinearLayout topContainer;
    private ViewTreeObserver.OnGlobalLayoutListener globalLayoutListener;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_main, container, false);
        topContainer = (LinearLayout) view.findViewById(R.id.top_container);

        // Width = 0, Height = 0
        Log.i("", "MainActivityFragment#onCreateView() " +
                "Width = " + String.valueOf(topContainer.getWidth()) + ", " +
                "Height = " + String.valueOf(topContainer.getHeight()));

        globalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                // Width = 1440, Height = 525
                Log.i("", "OnGlobalLayoutListener#onGlobalLayout() " +
                        "Width = " + String.valueOf(topContainer.getWidth()) + ", " +
                        "Height = " + String.valueOf(topContainer.getHeight()));

                // removeOnGlobalLayoutListener()の削除
                topContainer.getViewTreeObserver().removeOnGlobalLayoutListener(globalLayoutListener);
            }
        };
        topContainer.getViewTreeObserver().addOnGlobalLayoutListener(globalLayoutListener);

        return view;
    }
}

```

## その他
* いずれの場合でも、幅・高さが取得できるのは、レンダリング後（画面への表示が終わった後）です。
 * 基本的に、相対表示なので、一度画面に表示してからでないと、絶対値が取れないということでしょう。 
* Android 5.1(API 22)で確認しました。
 *  removeOnGlobalLayoutListener()の実装方法は、Android 4.0(API 16)以上と未満で異なります。