ListView嵌套ScrollView,MeasureSpec相关
来源:互联网 发布:kindle微信推送 知乎 编辑:程序博客网 时间:2024/06/05 03:12
初始情景
需要在ScrollView中嵌套ListView中,并且ListView高度有最大值,超出部分滑动展示,不足部分自适应大小。需要解决:
- ListView在ScrollView中使用只展示一项的问题;
- ListView和ScrollView的滑动冲突问题。
问题解决
只展示一项
重写一个继承自ListView的控件,重写onMeasure()测量方法,重新获取测量大小,并设置代码如下:
public class AgentListView extends ListView { public AgentListView(Context context) { super(context); } public AgentListView(Context context, AttributeSet attrs) { super(context, attrs); } public AgentListView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // 重写测量方法,自适应大小的高度,且最大高度约等Integer.MAX_VALUE/4 int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); }}
滑动冲突
mListView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_UP) { mScrollView.requestDisallowInterceptTouchEvent(false); }else { // 父类不拦截action mScrollView.requestDisallowInterceptTouchEvent(true); } return false; } });
onMeasure(widthMeasureSpec, heightMeasureSpec)方法
View中使用此方法进行测量控件大小,传入两个参数,长度和宽度。
每一个int型参数都包含了两个信息:测量模式 & 测量大小。
一个int型整数,如何表示两个信息?
一个int型,4byte,32bit,即32位。
这里使用前两位作为测量模式:UNSPECIFIED, EXACTLY, AT_MOST
后30位表示控件的测量大小。
MeasureSpec源码如下:
public static class MeasureSpec { private static final int MODE_SHIFT = 30; private static final int MODE_MASK = 0x3 << MODE_SHIFT; // 测量模式注解 @IntDef({UNSPECIFIED, EXACTLY, AT_MOST}) @Retention(RetentionPolicy.SOURCE) public @interface MeasureSpecMode {} // UNSPECIFIED 未指定模式 前两位为: 00 public static final int UNSPECIFIED = 0 << MODE_SHIFT; // EXACTLY 精确测量模式 前两位为: 01 public static final int EXACTLY = 1 << MODE_SHIFT; // AT_MOST 最大测量模式 前两位为: 10 public static final int AT_MOST = 2 << MODE_SHIFT; /** * 传入测量大小和测量模式,获取 规范测量值 * @params size 大小范围 0 ~ 2^30-1 * @params mode MeasureSpecMode模式三选一 */ public static int makeMeasureSpec(@IntRange(from = 0, to = (1 << MeasureSpec.MODE_SHIFT) - 1) int size, @MeasureSpecMode int mode) { if (sUseBrokenMakeMeasureSpec) { return size + mode; } else { return (size & ~MODE_MASK) | (mode & MODE_MASK); } } // 类似上面方法,UNSPECIFIED时返回0,用于兼容 public static int makeSafeMeasureSpec(int size, int mode) { if (sUseZeroUnspecifiedMeasureSpec && mode == UNSPECIFIED) { return 0; } return makeMeasureSpec(size, mode); } // 获取测量模式 @MeasureSpecMode public static int getMode(int measureSpec) { //noinspection ResourceType return (measureSpec & MODE_MASK); } // 获取测量大小 public static int getSize(int measureSpec) { return (measureSpec & ~MODE_MASK); } static int adjust(int measureSpec, int delta) { //省略 } public static String toString(int measureSpec) { // 省略 } }
如上问题解决,即使用AT_MOST测量模式,且最大值为2^(31-2)-1,也几乎等于有多大就是多大。
下面测量方式,即最大高度为 2400/4=600,实现不足600自适应大小,最大高度600滑动展示剩余项。
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int expandSpec = MeasureSpec.makeMeasureSpec(2400 >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); }
1 0
- ListView嵌套ScrollView,MeasureSpec相关
- MeasureSpec学习(解决ScrollView中嵌套ListView,ListView只显示一行的问题)
- MeasureSpec详解 顺便解决了scrollView嵌套listView和GirdView的冲突
- 自定义ScrollView嵌套Pageview和GridView(ListView)的相关问题
- Android开发之scrollview嵌套listview相关布局的解析
- ListView嵌套ListView,ScrollView嵌套ListView
- android ScrollView嵌套ListView
- ScrollView中嵌套ListView
- ScrollView中嵌套ListView
- ScrollView中嵌套ListView
- ScrollView嵌套 ListView
- android ScrollView嵌套ListView
- ScrollView嵌套ListView解决办法
- ScrollView和ListView嵌套
- ScrollView中嵌套ListView
- ScrollView嵌套ListView问题
- ScrollView中嵌套ListView
- ScrollView中嵌套ListView
- MBProgressHUD显示适应横屏
- C++第1次作业-个人所得税计算器
- 经典递归算法
- 【Linux】Linux定时任务crond
- 带分数
- ListView嵌套ScrollView,MeasureSpec相关
- 什么是数据库
- popUpWindow
- 浅析网络数据解析
- VMware虚拟机启动Ubuntu时提示piix4_smbus: Host SMBus controller not enabled错误的解决办法
- HDU 1166敌兵布阵
- C primer plus 第七章 C控制语句-分支和跳转 编程练习个人答案
- Java常用jar包用途
- LintCode : 二分查找