ScrollView与ListView合用(TextView多行显示时计算不正确)的问题解决

来源:互联网 发布:mac 查看下载速度 编辑:程序博客网 时间:2024/06/07 06:28

最近测试的时候发现在使用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.   
  5.         Layout layout = getLayout();  
  6.         if (layout != null) {  
  7.             int height = (int)FloatMath.ceil(getMaxLineHeight(this.getText().toString()))  
  8.                     + getCompoundPaddingTop() + getCompoundPaddingBottom();  
  9.             int width = getMeasuredWidth();              
  10.             setMeasuredDimension(width, height);  
  11.         }  
  12.     }  
  13.   
  14.     private float getMaxLineHeight(String str) {  
  15.         float height = 0.0f;  
  16.         float screenW = ((Activity)context).getWindowManager().getDefaultDisplay().getWidth();  
  17.         float paddingLeft = ((LinearLayout)this.getParent()).getPaddingLeft();  
  18.         float paddingReft = ((LinearLayout)this.getParent()).getPaddingRight();  
  19. //这里具体this.getPaint()要注意使用,要看你的TextView在什么位置,这个是拿TextView父控件的Padding的,为了更准确的算出换行  
  20.  int line = (int) Math.ceil( (this.getPaint().measureText(str)/(screenW-paddingLeft-paddingReft))); 
  21. height = (this.getPaint().getFontMetrics().descent-this.getPaint().getFontMetrics().ascent)*line; 
  22. return height;
  23. }  
  24. 上面的代码完成更能为,在ListView开始测量时,测量到TextView时,就调用我们的onMeasure方法,我们就可以测量字体的总宽度除与去掉边距的屏幕的大小,就可以算出文字要几行来显示,然后测量字体的高度*行数可以得到字体的总高度,然后在加上上下边距就是TextView真正的高度,然后setMeasuredDimension进去就可以计算出正确的值出来。  

0 0