常用 Scrollview嵌套Listview写法如下:
public class NoScrollListView extends ListView {
/**
* 构造
*/
public NoScrollListView(Context context) {
super(context);
}
/**
* 构造
*/
public NoScrollListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* 构造
*/
public NoScrollListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**
* makeMeasureSpec第一个参数size给出父布局能容纳的最大高度,这里取约定俗成的无限大一半,
* 第二个参数mode取wrap_content,包裹自己item数目。
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
现在有一个需求,是要在Scrollview嵌套之下的Listview,可折叠item数目(默认显示2个item,展开显示全部),固不可采用上面的高度写死方法,采用如下写法:
/**
* Created by Luzj on 2018/8/16.
*
* 禁止滑动的Listview,可动态设置宽高
*/
public class ScrollDisabledListView extends ListView {
private int mPosition;
public ScrollDisabledListView(Context context) {
super(context);
}
public ScrollDisabledListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ScrollDisabledListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
final int actionMasked = ev.getActionMasked() & MotionEvent.ACTION_MASK;
if (actionMasked == MotionEvent.ACTION_DOWN) {
// 记录手指按下时的item
mPosition = pointToPosition((int) ev.getX(), (int) ev.getY());
return super.dispatchTouchEvent(ev);
}
if (actionMasked == MotionEvent.ACTION_MOVE) {
// 最关键的地方,忽略MOVE 事件
// ListView onTouch获取不到MOVE事件所以不会发生滚动处理
return true;
}
// 手指抬起时
if (actionMasked == MotionEvent.ACTION_UP
|| actionMasked == MotionEvent.ACTION_CANCEL) {
// 手指按下与抬起都在同一个视图内,交给父控件处理,这是一个点击事件
if (pointToPosition((int) ev.getX(), (int) ev.getY()) == mPosition) {
super.dispatchTouchEvent(ev);
} else {
// 如果手指已经移出按下时的Item,说明是滚动行为,清理Item pressed状态
setPressed(false);
invalidate();
return true;
}
}
return super.dispatchTouchEvent(ev);
}
}
另外,给出折叠listview写法:
/**
* 自绘高度兼容scrollview下的历史记录listview
* @param isExpand 是否要折叠,true显示全部,false折叠成2个item
* 注意,listview的item根布局高度必须是wrap_content
* 原因是listview的item高度要在xml里面起效,都必须套一层wrap的父布局
*/
private void changeHisListViewHeight(boolean isExpand) {
int itemNum;
if(isExpand || mCommunityData.size() < 2) {//小于两个情况下不折叠
itemNum = mAdapter.getCount();
} else {
itemNum = 2;
}
View listItem = mAdapter.getView(0, null, historyList);
listItem.measure(0, 0);
int itemHeight = listItem.getMeasuredHeight();
int totalHeight = itemHeight * (itemNum);
totalHeight += (historyList.getDividerHeight() * (itemNum - 1))
+ historyList.getPaddingTop() + historyList.getPaddingBottom();
ViewGroup.LayoutParams params = historyList.getLayoutParams();
params.height = totalHeight;
historyList.setLayoutParams(params);
mAdapter.notifyDataSetChanged();
}