1. 程式人生 > >ScrollView與ListView合用(TextView多行顯示時計算不正確)的問題解決

ScrollView與ListView合用(TextView多行顯示時計算不正確)的問題解決

最近測試的時候發現在使用SrollView 中使用兩個listView,如果使用特大字型的話,比較長的LISTVIEW多行顯示會有問題。在網上搜索了一下,大概有兩種解決方案,一種是重寫ListView的onMeasure方法,一種是重寫TextView的onMeasure方法.

一 重寫ListView的onMeasure方法

首先,ListView不能直接用,要自定義一個,然後重寫onMeasure()方法:

 程式碼如下:
@Override  
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
    int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,  
            MeasureSpec.AT_MOST);  
    super.onMeasure(widthMeasureSpec, expandSpec);  
} 

第二步:寫個計算listView每個Item的方法:

程式碼如下:
public void setListViewHeightBasedOnChildren(ListView listView) {
  // 獲取ListView對應的Adapter
  ListAdapter listAdapter = listView.getAdapter();
  if (listAdapter == null) {
   return;
  }
  int totalHeight = 0;
  for (int i = 0; i < listAdapter.getCount(); 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.getDividerHeight()獲取子項間分隔符佔用的高度
  // params.height最後得到整個ListView完整顯示需要的高度
  listView.setLayoutParams(params);
 }


第三步:listview新增介面卡後設置高度即可:

程式碼如下:
listView.setAdapter(adapter);  
new ListViewUtil().setListViewHeightBasedOnChildren(listView); 

   二 重寫TextView的onMeasure方法

程式碼有

  1. @Override  
  2.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  3.         super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
  4.         Layout layout = getLayout();  
  5.         if (layout != null) {  
  6.             int height = (int)FloatMath.ceil(getMaxLineHeight(this.getText().toString()))  
  7.                     + getCompoundPaddingTop() + getCompoundPaddingBottom();  
  8.             int width = getMeasuredWidth();              
  9.             setMeasuredDimension(width, height);  
  10.         }  
  11.     }  
  12.     private float getMaxLineHeight(String str) {  
  13.         float height = 0.0f;  
  14.         float screenW = ((Activity)context).getWindowManager().getDefaultDisplay().getWidth();  
  15.         float paddingLeft = ((LinearLayout)this.getParent()).getPaddingLeft();  
  16.         float paddingReft = ((LinearLayout)this.getParent()).getPaddingRight();  
  17. //這裡具體this.getPaint()要注意使用,要看你的TextView在什麼位置,這個是拿TextView父控制元件的Padding的,為了更準確的算出換行  
  18.  int line = (int) Math.ceil( (this.getPaint().measureText(str)/(screenW-paddingLeft-paddingReft))); 
  19. height = (this.getPaint().getFontMetrics().descent-this.getPaint().getFontMetrics().ascent)*line; 
  20. return height;
  21. }  
  22. 上面的程式碼完成更能為,在ListView開始測量時,測量到TextView時,就呼叫我們的onMeasure方法,我們就可以測量字型的總寬度除與去掉邊距的螢幕的大小,就可以算出文字要幾行來顯示,然後測量字型的高度*行數可以得到字型的總高度,然後在加上上下邊距就是TextView真正的高度,然後setMeasuredDimension進去就可以計算出正確的值出來。