我有一个充满多行TextViews的listView。每个TextView都有不同数量的文本。在按下一个按钮后,用户被带到另一个活动中,他们可以改变字体和字体大小。当重新进入Fragment时,如果这些设置发生了变化,listView会被重置,TextViews的尺寸也会改变。
我需要知道这些设置改变后,视图中第一个TextView的测量高度。由于某些原因,测量后的高度一开始是不同的。一旦我手动滚动列表,真正的高度测量就会被记录下来。
Log output:
测量后:电视高度=2036
测量后:电视高度=2036
滚动后:tv高度=7950
最小的代码。
class FragmentRead : Fragment() {
private var firstVisiblePos = 0
lateinit var adapterRead: AdapterRead
lateinit var lvTextList: ListView
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
lvTextList = view.findViewById(R.id.read_listview)
setListView(lvTextList)
lvTextList.setOnScrollListener(object : AbsListView.OnScrollListener {
var offset = 0
override fun onScrollStateChanged(view: AbsListView, scrollState: Int) {
if(scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
offset = if(lvTextList.getChildAt(0) == null) 0 else lvTextList.getChildAt(0).top - lvTextList.paddingTop
println("After scroll: tv height = ${lvTextList[0].height}")
override fun onScroll(view: AbsListView, firstVisibleItem: Int, visibleItemCount: Int, totalItemCount: Int) {
firstVisiblePos = firstVisibleItem
/*=======================================================================================================*/
fun setListView(lv: ListView) {
adapterRead = AdapterRead(Data.getTextList(), context!!)
lv.apply {this.adapter = adapterRead}
/*=======================================================================================================*/
inline fun <T : View> T.afterMeasured(crossinline f: T.() -> Unit) {
viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
if(measuredWidth > 0 && measuredHeight > 0) {
println("After measured: tv height = ${lvTextList[0].height}")
viewTreeObserver.removeOnGlobalLayoutListener(this)
/*=======================================================================================================*/
override fun onStart() {
if(Settings.settingsChanged) {
setListView(lvTextList)
lvTextList.afterMeasured {
println("After measured: tv height = ${lvTextList[0].height}")
我所尝试的。
我试着用文本和layoutParams设置一个TextView,并按照这里的解释读取高度(在渲染到布局之前获得文本视图的高度),但结果是一样的。测量的高度比我滚动列表后的高度小得多。
我也试着用lvTextList.scrollBy(0,1)来编程滚动列表,以便在读取正确的高度时触发滚动监听器或其他什么东西。
编辑:我在回到碎片后放了一个延迟。
Handler().postDelayed({
println("tv height after delay = ${lvScriptureList[0].height}")}, 1000)
而这报告的高度是正确的。所以我的猜测是,OnGlobalLayoutListener被提前调用了。有什么方法可以解决这个问题吗?