NestedScrollView嵌套ListView可行性总结
由于公司项目遗留代码仍然使用PullToRefreshListView(后文简称PTRLV),且存在复用,更换RecyclerView成本太大,同时又想使用CoordinatorLayout来实现一些嵌套滑动效果,所以研究了NestedScrollView嵌套PTRLV的方案。
对于NestedScrollView嵌套普通的ListView,常见的问题有:
- 嵌套后ListView只显示一行。
- ListView无法滑动。
网上的解决方案主要是2种:
重写ListView的onMeasure方法。
@Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);super.onMeasure(widthMeasureSpec, expandSpec);}
将ListView所有子View的高度以及分隔线的高度相加,重新设置给ListView。
private void setListViewHeightBasedOnChildren(ListView listView) {ListAdapter listAdapter = listView.getAdapter(); //获得Adapterif (listAdapter == null) { return;}int totalHeight = 0;for (int i = 0; i < listAdapter.getCount(); i++) {View listItem = listAdapter.getView(i, null, listView);listItem.measure(0, 0);totalHeight += listItem.getMeasuredHeight();}ViewGroup.LayoutParams params = listView.getLayoutParams();params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));listView.setLayoutParams(params);}
这种方法要求子View的根布局必须是LinearLayout。
这2种方法乍看之下也都能解决NestedScrollView嵌套PTRLV的问题,但其实局限性很大,项目中实践后发现场景稍有变化就仍然有问题。
主要有:
- 有些场景下展示的数据并不会在Activity的onCreate方法中就获取,例如搜索页需要用户输入关键字后才去获取数据,然后才将数据给到PTRLV展示,这时PTRLV只显示半行。
- 在PTRLV中改写添加的预加载功能失效。
第1个问题出现的原因在于,上述2种解决方案都是改变PTRLV中真正的ListView的大小,让它能够将全部的子View展现出来。在这个场景中,界面初始化时,ListView中是没有数据的,所以在measure时ListView本身大小为0,只测量出了PTRLV的那个滑动指示块的高度,所以PTRLV只有那么高。
那为什么获取到数据后再notify还是只有这么高呢?因为PTRLV在真正的ListView之外还有两层FrameLayout。虽然ListView因为重写了onMeasure方法已经展示全了,但这两层FrameLayout还是只有滑块那么高,所以PTRLV看起来还是没有改变。
解决方案为:
重写PTRLV内部的FrameLayout的onMeasure方法,跟ListView一样就行
public class NoScrollFrameLayout extends FrameLayout {public NoScrollFrameLayout(Context context) {super(context);}public NoScrollFrameLayout(Context context, AttributeSet attrs) {super(context, attrs);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);super.onMeasure(widthMeasureSpec, expandSpec);} }
在PTRLV的父类PullToRefreshBase中改写addRefreshableView方法
private void addRefreshableView(Context context, T refreshableView) {mRefreshableViewWrapper = new NoScrollFrameLayout(context);mRefreshableViewWrapper.addView(refreshableView, ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);addViewInternal(mRefreshableViewWrapper, new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT)); }
第2个问题出现的原因是因为滑动事件的冲突。这里可能会有疑问,为什么还说滑动事件有冲突,通过上述方案不是已经可以正常滑动了吗?那是因为那只是看上去像ListView的滑动,其实是NestedSrcollView在滑动,ListView根本没有动。
从第1个问题的原因中我们已经知道了,解决NestedScrollView中嵌套ListView显示不全问题的方法,其本质都是手动修改ListView的内容的高度,而且不是将高度match_parent,而是将ListView的子View全部加载进来,假如有50个数据,就一次性加载50个子View,所以ListView就相当于一个有50个子View的LinearLayout。(当然也就不会有复用,性能很差)
另一方面,NestedSrcollView在onInterceptTouchEvent中拦截了所有的Touch事件,ListView没有分发到任何事件,所以虽然看上去像ListView在滑动,实际上是ScrollView包裹着相当于LinearLayout的ListView在滑动,而由于我们项目的预加载逻辑写在ListView的onScrollStateChange方法中,没有分到任何Touch事件的情况下根本不会调用onScrollStateChange,因此预加载就失效了。
这个问题在不改动预加载逻辑实现位置的情况下是无解的。同时也可以得出:如果你在ListView的Touch事件中有自定义的逻辑,那么请不要用NestedSrcollView嵌套ListView,因为NestedSrcollView会拦截Touch事件,所有的滑动解决方案并没有真正解决滑动冲突,ListView是获取不到Touch事件的。
转载于:https://www.cnblogs.com/zhujiabin/p/7371735.html
NestedScrollView嵌套ListView可行性总结相关推荐
- Android中RecyclerView嵌套RecyclerView或嵌套ListView
Android中RecyclerView嵌套RecyclerView或嵌套ListView
- scrollview中嵌套listview产生冲突问题
在scrollview中嵌套listview或者gridview时 如果listview或者gridview的高度时wrap-content会导致两者只显示一行多一点 原因: listview和gri ...
- Android之解决在scrollview中嵌套ListView切换界面时scrollview整体向下滑动
有时候我们在scrollview中会嵌套ListView,在嵌套ListView(ListView上面还有一些控件)后,切换Activity时会发现整个 scrollview 被向下滑动直到ListV ...
- 当PullToRefreshScrollView里面嵌套ListView
当PullToRefreshScrollView里面嵌套ListView,ListView上面还是有内容的,当下拉刷新的 时候,数据填充完成之后ListView就会往上面滑动,导致ListView上面 ...
- 四种方案解决ScrollView嵌套ListView问题
在工作中,曾多次碰到ScrollView嵌套ListView的问题,网上的解决方法有很多种,但是杂而不全.我试过很多种方法,它们各有利弊. 在这里我将会从使用ScrollView嵌套ListView结 ...
- ScrollView中嵌套ListView
放置比较少的ListView组件效果图: Item布局文件 list_view_item.xml 布局文件的内容: <RelativeLayo ...
- android中ScrollView嵌套ListView或GridView显示位置问题
Android中ScrollView中嵌套ListView或GridView时在开始进入界面时总是显示中间位置,开头的位置显示不出来.这种情况下只需要在ScrollView的父控件中添加以下两行代码即 ...
- ScrollView嵌套ListView后,进入页面不从顶部开始显示的问题解决
ScrollView嵌套ListView后,进入页面不从顶部开始显示的问题解决 首先,正常情况下,如果在ScrollView里嵌套ListView后,会发现ListView只显示1条数据 那么,为了解 ...
- Android之解决NestedScrollView嵌套RecyclerView部分手机返回到这个页面Recyclerview顶部,而不是页面NestedScrollView顶部
1.问题 NestedScrollView嵌套Recyclerview部分手机返回到这个页面Recyclerview顶部,而不是页面NestedScrollView顶部 部分布局大致如下 <an ...
- 解决Android学习之ScollView嵌套ListView和GridView问题
Android学习之ScollView嵌套ListView和GridView问题,gridview与这种写法一样 import android.content.Context; import andr ...
最新文章
- Vue 动态路由的实现以及 Springsecurity 按钮级别的权限控制
- MySQL列转行sql语句
- ACL 2021 | 复旦大学邱锡鹏组:面向不同NER子任务的统一生成框架
- [zz]Ubuntu下使用Eclipse和PyDev搭建完美Python开发环境
- 组件化与插件化的差别在哪里?内含福利
- hal库串口dma卡死_HAL库版DMA循环模式串口数据收发
- 排序算法python实现_合并排序算法– Java,C和Python实现
- 第一行代码笔记-第五章
- VS报错——无法打开文件XXX.lib
- 《数据结构》-二叉树(二叉链表实现)
- java论文3000字_一篇文章让你真正了解Java(纯干货)
- 【智能优化算法-灰狼算法】基于非支配排序灰狼优化器(NS-GWO)算法求解多目标优化算法附matlab代码
- 认识计算机微课导学单,微课“任务单”与“导学案”之比较
- CentOS7创建组删除组创建用户删除用户
- 关于双因素认证(2FA),这些基础知识你一定要知道
- 从user 登陆开始
- RFID技术如何解决鞋帽行业应用
- 宜信 、《麻省理工科技评论》共同揭晓: 35岁以前最有可能改变世界的中国科技精英丨Xtecher 前线
- Mac 下eclipse 快捷键
- 授权sh文件执行权限