Activityの場合
従来のActivityベースのアプリの場合、『onWindowFocusChanged()』で取得すればよいです。
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?
- 独自のインターフェースを定義して、ActivityでonWindowFocusChanged()が呼ばれた際に、Fragmentにも通知する。
- FragmentとActivityの結びつきが強くなってしまう可能性がある。
方法2 OnGlobalLayoutListener#onGlobalLayout()を利用する
- onGlobalLayout()でレイアウトに変化があった場合に値を取得します。
- OnGlobalLayoutListenerは、レイアウトが変化する度に呼ばれるので、再取得が不要な場合には、リスナーを削除しておきます。
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)以上と未満で異なります。