はじめに
FragmentのonActivityCreated等でビューの横幅、高さを取得しようとすると0が返ってくると思います。
これはビューの大きさが確定する前に取得しようとしているのが原因なのですが、
この解決策として、今までOnGlobalLayoutListener#onGlobalLayout()を使用していました。
ただこの方法ですと、コード量がちょっと多いです。
postを使ってより短く書ける方法がありましたので、そちらを共有します。
環境
AndroidStudio 4.1
kotlin 1.3.72
コード
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
import androidx.fragment.app.Fragment
import com.example.kotlinsample.R
class SampleFragment : Fragment() {
companion object {
private const val TAG = "SampleFragment"
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_sample, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
// 0. 対策なし
Log.d(TAG, "[0] width${view?.width}, height:${view?.height}")
// 1. OnGlobalLayoutListenerを使う方法
var globalLayoutListener: ViewTreeObserver.OnGlobalLayoutListener? = null
globalLayoutListener = ViewTreeObserver.OnGlobalLayoutListener {
Log.d(TAG, "[1] width${view?.width}, height:${view?.height}")
// リスナ解除
view?.viewTreeObserver?.removeOnGlobalLayoutListener(globalLayoutListener)
}
view?.viewTreeObserver?.addOnGlobalLayoutListener(globalLayoutListener)
// 2. postを使う方法
view?.post {
Log.d(TAG, "[2] width${view?.width}, height:${view?.height}")
}
}
}
結果
[0] width0, height:0
[1] width1080, height:1776
[2] width1080, height:1776
対策なしで取得した場合が0になり
OnGlobalLayoutListenerを使う方法、postを使う方法で横幅、高さが取得できました。
常に正しく取得できるかは未検証ですが、コード量がシンプルになるので積極的に使っていきたいですね。