为了账号安全,请及时绑定邮箱和手机立即绑定

ListView加载完数据为什么屏幕会自动和ListView的顶部对齐,而不是最布局中最顶部的控件?

ListView加载完数据为什么屏幕会自动和ListView的顶部对齐,而不是最布局中最顶部的控件?

回首忆惘然 2019-04-13 08:37:19
我在ScrollView里先后放了一个ViewPager,可以显示几页广告;下边是一个ListView里,会从网络请求数据,并加载出一些图片出来。正常应该显示ViewPager里的内容,ViewPager没占满屏幕,ViewPager下面再显示ListView部分。但是我的ListView请求完数据就会自动将其滑到屏幕顶部,也就是说ViewPager被滑上去了。屏幕里从ListView开始显示。怎么才能不让ListView影响默认显示的效果呢?求教
查看完整描述

2 回答

?
翻过高山走不出你

TA贡献1875条经验 获得超3个赞

遇到过一个类似的问题,不过当时ScrollView里嵌套的是GridView,分享下解决方案及过程,只想要解决方案的话看分隔线上面的就好了
grid.setFocusable(false)
update数据后,手动scrollto(0,0)
重写ScrollView中的computeScrollDeltaToGetChildRectOnScreen,让该方法返回0
ScrollView中嵌套GridView导致ScrollView默认不停留在顶部的解决方案和分析
发生情况大概是我在ScrollView顶部放了一个ViewPager用来做广告Banner,底部放了个GridVie,来实现一个类似9宫格效果的展示.
然后出现的状况是,当我获取完数据并调用notifyDataSetChanged();后ScrollView自动滚到了最底部,也就是GridView所在的位置.
研究了一下,获取了一些解决方案
--让界面顶部的某一个View获取focus--grid.setFocusable(false);--手动scrollto(0,0)--重写ScrollView中的computeScrollDeltaToGetChildRectOnScreen,让该方法返回0
目前简单的用setFocusable(false)解决了该问题
试着分析一下这个问题产生的原因.从解决方案反推,可以发现这个问题和focus有关系
一个猜测是notifyDataSetChanged()之后,grid由于加载了数据的关系高度产生了变化
这导致了ScrollView内部重新走了onLayout/onMeaure流程在这个流程中ScrollView会将自身滚动到获得focus的child位置
上面关于focus的解决方案即是从这个角度去解决问题
跟踪一下调用链
protectedvoidonLayout(booleanchanged,intl,intt,intr,intb){
super.onLayout(changed,l,t,r,b);
mIsLayoutDirty=false;
//Giveachildfocusifitneedsit
if(mChildToScrollTo!=null&&isViewDescendantOf(mChildToScrollTo,this)){
scrollToChild(mChildToScrollTo);
}
...
}
可以看到onLayout的时候确实会将ScrollView滚动到focuschild位置
privatevoidscrollToChild(Viewchild){
child.getDrawingRect(mTempRect);
/*Offsetfromchild'slocalcoordinatestoScrollViewcoordinates*/
offsetDescendantRectToMyCoords(child,mTempRect);
intscrollDelta=computeScrollDeltaToGetChildRectOnScreen(mTempRect);
if(scrollDelta!=0){
scrollBy(0,scrollDelta);
}
}
从代码逻辑上来看避免GridView获取focus可以解决该问题.
而重写ScrollView中的computeScrollDeltaToGetChildRectOnScreen则是从另一个角度解决该问题
而scrollToChild这个方法会根据computeScrollDeltaToGetChildRectOnScreen的返回值来计算滚动的位置
重载computeScrollDeltaToGetChildRectOnScreen让其返回0会导致ScrollView内布局产生变化时,不能正确滚动到focuschild位置,当然,这也就是我们想要的效果,布局变化时ScrollView不需要自己去滚动.
至于computeScrollDeltaToGetChildRectOnScreen代码太长就不贴了
大致代码是根据当前scrollY和focuschild的rect.bottom去计算要滚到哪
逻辑理顺以后觉得这个问题也没什么奇怪的.
                            
查看完整回答
反对 回复 2019-04-13
  • 2 回答
  • 0 关注
  • 429 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信