天天记录 - Android TextView setMaxLines后获取完整高度

当在Android的TextView中使用setMaxLines限制行数后,getHeight方法只会返回限定行数的高度。要获取显示所有内容时的完整高度,可以通过源码分析找到解决方案。关键在于调用TextView的getDesiredHeight方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



      TextView设置完setMaxLines后,通过TextView.getHeight方法获取的是当前行数的高度,而非文字完全显示的高度。

      以下左边的图是《选择》这首诗一共只显示5行,右侧的图片中可以看到5行文字的高度,但是此时获取不到完整显示时TextView的高度

		textView.setMaxLines(5);
		textView.getHeight();   // 125



                



获取TextView的完整高度,核心代码

	private int getTextViewHeight(TextView pTextView) {
		Layout layout = pTextView.getLayout();
		int desired = layout.getLineTop(pTextView.getLineCount());
		int padding = pTextView.getCompoundPaddingTop() + pTextView.getCompoundPaddingBottom();
		return desired + padding;
	}




完整代码

public class MainActivity extends Activity {
	
	private static final String value = "选   择    汪国真\n你的路\n已经走了很长很长\n走了很长"
			+ "\n可还是看不到风光\n你的心很苦\n很彷徨\n没有风帆的船\n不比死了强\n没有罗盘的风帆"
			+"\n只能四处去流浪\n如果你是鱼不要迷恋天空\n如果你是鸟不要痴情海洋";
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		final TextView output = (TextView) findViewById(R.id.output);
		output.setText("在屏幕上点击,可以获取输出TextView高度信息");
		
		
		final TextView textView = (TextView) findViewById(R.id.textview);
		textView.setText( value );
		textView.setMaxLines(5);
		
		
		RelativeLayout layout = (RelativeLayout) findViewById(R.id.layout);
		layout.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				StringBuilder stringBuilder = new StringBuilder();
				
				stringBuilder.append("当前TextView设置setMaxLines属性未全部显示\n");
				stringBuilder.append("textView.getHeight = ");
				stringBuilder.append( textView.getHeight() );
				stringBuilder.append("\n");
				
				
				stringBuilder.append("TextView全部文字显示的实际高度: ");
				stringBuilder.append(getTextViewHeight(textView));
				
				output.setText( stringBuilder.toString() );
				
				textView.setMaxLines(Integer.MAX_VALUE);
			}
		});
	}

	
	
	private int getTextViewHeight(TextView pTextView) {
		Layout layout = pTextView.getLayout();
		int desired = layout.getLineTop(pTextView.getLineCount());
		int padding = pTextView.getCompoundPaddingTop() + pTextView.getCompoundPaddingBottom();
		return desired + padding;
	}
	
	
}





    通过阅读TextView源码,查找其TextView宽高的计算方式,首先看TextView.onMeasure方法,TextView继承自View,View都是通过在onMeasure方法中确定宽高的。


     @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        // 宽度相关代码不看,此处此关心与高度相关的
	......
       

        // 高度
        if (heightMode == MeasureSpec.EXACTLY) {
            // Parent has told us how big to be. So be it.
            height = heightSize;
            mDesiredHeightAtMeasure = -1;
        } else {
             // 从这里获取的TextView高度
            int desired = getDesiredHeight();

            height = desired;
            mDesiredHeightAtMeasure = desired;

            if (heightMode == MeasureSpec.AT_MOST) {
                height = Math.min(desired, heightSize);
            }
        }

        // 没有填充的高度
        int unpaddedHeight = height - getCompoundPaddingTop() - getCompoundPaddingBottom();
        if (mMaxMode == LINES && mLayout.getLineCount() > mMaximum) {
            unpaddedHeight = Math.min(unpaddedHeight, mLayout.getLineTop(mMaximum));
        }

        /*
         * We didn't let makeNewLayout() register to bring the cursor into view,
         * so do it here if there is any possibility that it is needed.
         */
        if (mMovement != null ||
            mLayout.getWidth() > unpaddedWidth ||
            mLayout.getHeight() > unpaddedHeight) {
            registerForPreDraw();
        } else {
            scrollTo(0, 0);
        }

        setMeasuredDimension(width, height);
    }


从上面代码中可以获取到,高度是通过此TextView.getDesiredHeight获得,接着查看这段代码

    private int getDesiredHeight(Layout layout, boolean cap) {
        if (layout == null) {
            return 0;
        }
       
        // 行数
        int linecount = layout.getLineCount();
        // padding
        int pad = getCompoundPaddingTop() + getCompoundPaddingBottom();
        // 期望值
        int desired = layout.getLineTop(linecount);

        final Drawables dr = mDrawables;
        if (dr != null) {
            desired = Math.max(desired, dr.mDrawableHeightLeft);
            desired = Math.max(desired, dr.mDrawableHeightRight);
        }

        desired += pad;

        if (mMaxMode == LINES) {
            /*
             * Don't cap the hint to a certain number of lines.
             * (Do cap it, though, if we have a maximum pixel height.)
             */
            if (cap) {
                if (linecount > mMaximum) {
                    desired = layout.getLineTop(mMaximum) +
                              layout.getBottomPadding();

                    if (dr != null) {
                        desired = Math.max(desired, dr.mDrawableHeightLeft);
                        desired = Math.max(desired, dr.mDrawableHeightRight);
                    }

                    desired += pad;
                    linecount = mMaximum;
                }
            }
        } else {
            desired = Math.min(desired, mMaximum);
        }

        if (mMinMode == LINES) {
            if (linecount < mMinimum) {
                desired += getLineHeight() * (mMinimum - linecount);
            }
        } else {
            desired = Math.max(desired, mMinimum);
        }

        // Check against our minimum height
        desired = Math.max(desired, getSuggestedMinimumHeight());

        return desired;
    }





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值