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.   
  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进去就可以计算出正确的值出来。  

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值