1. 程式人生 > >當ListView顯示不全時,除了總體測量外還要測量TextView的高度

當ListView顯示不全時,除了總體測量外還要測量TextView的高度

好,直接擼程式碼,這樣更明瞭

1.關於總體測量

當使用ScrollView巢狀ListView的時候,如果不對ListView進行高度的測量,ListView也不知道自己到底有多長,所以ListView會顯示不全的,這裡先上總體測量ListView的方法(這種測量方式有很多中,這裡就上一種了);
public void setListViewHeight(ListView listView) {

    // 獲取ListView對應的Adapter
ListAdapter listAdapter = listView.getAdapter();
    if (listAdapter == null
) { return; } int totalHeight = 0; for (int i = 0, len = listAdapter.getCount(); i < len; i++) { // listAdapter.getCount()返回資料項的數目 View listItem = listAdapter.getView(i, null, listView); listItem.measure(0, 0); // 計運算元項View 的寬高 totalHeight += listItem.getMeasuredHeight(); // 統計所有子項的總高度 } ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); listView.setLayoutParams(params); }
程式碼很簡單,先拿到ListView的adapter,通過adapter迴圈拿到每個itemview,然後計算每個itemview的高度再疊加起來,再加上分割線的高度。 這種測量方式在一般的情況下是沒有問題的,測量的高度也好,顯示也完整,但是在專案中的時候itemview的佈局會很複雜,當有多行的TextView的時候著個測量方法就沒有什麼效果了,ListView顯示就不完整了

2.完整的測量方式

當在itemview的佈局裡面有多行的textview的時候,itemview自身測量的高度是不準確的,它並不知道如何去測量這個多行的textview,所以這時候就要求我們幫助他來完成這個多行的textview的測量,重寫一個textview的自定義類就行了 寫一個類繼承自TextView,重寫它的onMeasure方法(這裡參考了其他大神的測量方法
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
Layout layout = getLayout();
    if (layout != null) {
        int height = (int) FloatMath.ceil(getMaxLineHeight(this.getText().toString()))
                + getCompoundPaddingTop() + getCompoundPaddingBottom();
        int width = getMeasuredWidth();
setMeasuredDimension(width, height);
}
}

private float getMaxLineHeight(String str) {
    float screenW = ((Activity)getContext()).getWindowManager().getDefaultDisplay().getWidth();
    float paddingLeft = ((LinearLayout)this.getParent()).getPaddingLeft();
    float paddingReft = ((LinearLayout)this.getParent()).getPaddingRight();
//這裡具體this.getPaint()要注意使用,要看你的TextView在什麼位置,這個是拿TextView父控制元件的Padding的,為了更準確的算出換行
int line = (int) Math.ceil( (this.getPaint().measureText(str)/(screenW-paddingLeft-paddingReft)));
    float height = (this.getPaint().getFontMetrics().descent-this.getPaint().getFontMetrics().ascent)*line;
    return height;
}

將itemview中的textview替換掉,然後再配合上上一種的測量方法,大部分的測量都不會出問題的。