常用 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();
}