TextView 获取自适应 wrap_content 的宽高 Android 获得view的宽和高

http://blog.csdn.net/yangdeli888/article/details/25405263



在oncreate()中利用view.getWidth()或是view.getHeiht()来获取view的宽和高,看似没有问题,其实他们去得值是0,并不是你想要的结果?

这是为什么呢?

在调用oncreate()方法时,界面处于不可见状态,内存加载组件还没有绘制出来,你是无法获取他的尺寸。

那如何在绘制组件之前能获取到该组件的尺寸大小呢?

这里有三种方法,经过验证的:

方法一 
//测量方法
?
1
2
3
4
5
int width =View.MeasureSpec.makeMeasureSpec( 0 ,View.MeasureSpec.UNSPECIFIED);
int height =View.MeasureSpec.makeMeasureSpec( 0 ,View.MeasureSpec.UNSPECIFIED);
view.measure(width,height);
int height=view.getMeasuredHeight();
int width=view.getMeasuredWidth();
  android:maxWidth="100dp"
        android:maxWidth="100dp"
        android:ellipsize="end"
        android:text="一二三四五六七八九十一二三四五六七八九十一二三四五六七八九十一二三四五六七八九十一二三四五六七八九十"
        android:singleLine="true" />


方法二 
?
1
2
3
4
5
6
7
8
9
//增加组件绘制之前的监听
ViewTreeObserver vto =view.getViewTreeObserver();
vto.addOnPreDrawListener( new ViewTreeObserver.OnPreDrawListener() {
    @Override
     public boolean onPreDraw() {
int height =view.getMeasuredHeight();
int width =view.getMeasuredWidth();    
    }
});
方法三  : 
?
1
2
3
4
5
6
7
8
9
10
//增加整体布局监听
ViewTreeObserver vto = view.getViewTreeObserver(); 
vto.addOnGlobalLayoutListener( new OnGlobalLayoutListener(){
     @Override 
     public void onGlobalLayout() {
view.getViewTreeObserver().removeGlobalOnLayoutListener( this );     
int height =view.getMeasuredHeight();
int width =view.getMeasuredWidth(); 
    
});

那么,在activity进入运行期时,组件的尺寸获取方法就很简单了,直接getWidth()和getHeight().

方法经验证 方法方法三,设置为wrap_content;

	ViewTreeObserver vto = tv.getViewTreeObserver();  

	vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener(){ 

	    @Override 
	    public void onGlobalLayout() { 

	    	tv.getViewTreeObserver().removeGlobalOnLayoutListener(this);     

	    int height =tv.getMeasuredHeight(); 
	    int width =tv.getMeasuredWidth();  
	    Log.d("阿萨德法师打发卡是", "height ="+tv.getMeasuredHeight()+";width ="+tv.getMeasuredWidth()+";");

	    }
	});
	

 

//通过这个方法可以做某些事情,
	CharSequence ellipsize = TextUtils.ellipsize("一二三四五六七八九十一二三四五六七八九十一二三四五六七八九十一二三四五六七八九十一二三四五六七八九十", //
					tv.getPaint(), 
					tv.getMeasuredWidth(),
					TextUtils.TruncateAt.END,
					false, 
					new TextUtils.EllipsizeCallback() {
	                    @Override
	                    public void ellipsized(int i, int i1) {//脚标 从0 开始算起
	                        Log.e("TGA", "被省略范围 " + i + " " + i1);
	                    }
	                });

	Log.e("阿萨德法师打发卡是", 
							"0ellipsize="+ellipsize.toString()+
							"\n0tv.getWidth()="+tv.getWidth()+
							"0ellipsize="+ellipsize.toString()+
							"\n0tv.getMeasuredWidth()="+tv.getMeasuredWidth()+
							"\n0tv.getPaddingLeft()="+tv.getPaddingLeft()+
							"\n0tv.getAvailableWidth()="+tv.getAvailableWidth());

下面是我自己的代码需要的自己整下

package com.example.ellsptextview;

import android.app.Activity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextUtils.EllipsizeCallback;
import android.text.TextUtils.TruncateAt;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {

	private EditText ed;
	private EllpsizeTextView tv;
	private MyEditTextTextWatcher edTextWatcher;
	private MyTextViewTextWatcher tvTextWatcher;
	private EllipsizeCallback ell;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		initView();
		initData();
		initListener();

	}
	
//	============================下面全是初始化,和debug==============================================
	/**
	 * @version 1.0
	 *
	 * @author DongXiang
	 * 
	 * @action EditText 判断文本内容变化的监听
	 * 
	 * @time 2016年10月11日下午1:14:44
	 * 
	 */
	class MyEditTextTextWatcher implements TextWatcher {
		 /**
		  * 文本内容  改变后
		  * */
		 @Override
		 public void afterTextChanged(Editable s) {//表示最终内容
	         Log.d("afterTextChanged", s.toString());
		
		 }
		/**
		  * 文本内容  没有改变前
		  * */
		 @Override
		 public void beforeTextChanged(CharSequence s, int start/**开始位置*/, int count/**被改变的旧内容数*/,int after/**改变后的内容数量*/) {
			 //这里的s表示改变之前的内容,通常start和count组合,可以在s中读取本次改变字段中被改变的内容。而after表示改变后新的内容的数量。
		
		 }
		
		/**
		  * 文本内容   动态改变;没变化一次执行一次;
		  * */
		 @Override
		 public void onTextChanged(CharSequence s, int start/**开始位置*/, int before/**改变前的内容数量*/, int count/**新增数*/) {
	         //这里的s表示改变之后的内容;通常start和count组合,可以在s中读取本次改变字段中新的内容。而before表示被改变的内容的数量。
			 Log.d("onTextChanged",  s+"");
			 tv.setText(s);
//			 Log.d("onTextChanged_isEllipsize",  intText(R.id.ellipsize_tv_show, MainActivity.this)+"");
		 
		 }
	
	
	}
	/**
	 * @version 1.0
	 *
	 * @author DongXiang
	 * 
	 * @action TextView 判断 文本变化的 监听
	 * 
	 * @time 2016年10月11日下午1:14:03
	 * 
	 */
	class MyTextViewTextWatcher implements TextWatcher {
		/**
		 * 文本内容  改变后
		 * */
		@Override
		public void afterTextChanged(Editable s) {//表示最终内容
			
		}
		/**
		 * 文本内容  没有改变前
		 * */
		@Override
		public void beforeTextChanged(CharSequence s, int start/**开始位置*/, int count/**被改变的旧内容数*/,int after/**改变后的内容数量*/) {
			//这里的s表示改变之前的内容,通常start和count组合,可以在s中读取本次改变字段中被改变的内容。而after表示改变后新的内容的数量。
			
		}
		
		/**
		 * 文本内容   动态改变;没变化一次执行一次;
		 * */
		@Override
		public void onTextChanged(CharSequence s, int start/**开始位置*/, int before/**改变前的内容数量*/, int count/**新增数*/) {
			//这里的s表示改变之后的内容;通常start和count组合,可以在s中读取本次改变字段中新的内容。而before表示被改变的内容的数量。
//			if (tv.isOverFlowed()) {
//				Toast.makeText(MainActivity.this, "TextView发生了省略", Toast.LENGTH_SHORT).show();
//				Log.d("onTextChanged isOverFlowed",  s+"&&&&&");
//			}
		}
		
		
	}
//	===================下面都是Activity 里面的功能=========================
	private void initView() {
		ed = (EditText) this.findViewById(R.id.ellipsize_et_input);
		tv = (EllpsizeTextView) this.findViewById(R.id.ellipsize_tv_show);
	}
	
	private void initData() {
		edTextWatcher=new MyEditTextTextWatcher();
		tvTextWatcher=new MyTextViewTextWatcher();
		
	}
	private void initListener() {
		ed.addTextChangedListener(edTextWatcher);
//	tv.addTextChangedListener(tvTextWatcher);
	// 先让tv  绘制下,再获取他的宽高
//	int width =View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
//	
//	int height =View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
//	
//	tv.measure(width,height);
//	CharSequence ellipsize = TextUtils.ellipsize("1234567890123456789012345678901234567890", //
	CharSequence ellipsize = TextUtils.ellipsize("一二三四五六七八九十一二三四五六七八九十一二三四五六七八九十一二三四五六七八九十一二三四五六七八九十", //
					tv.getPaint(), 
					tv.getMeasuredWidth(),
					TextUtils.TruncateAt.END,
					false, 
					new TextUtils.EllipsizeCallback() {
	                    @Override
	                    public void ellipsized(int i, int i1) {//脚标 从0 开始算起
	                        Log.e("TGA", "被省略范围 " + i + " " + i1);
	                    }
	                });

	Log.e("阿萨德法师打发卡是", 
							"0ellipsize="+ellipsize.toString()+
							"\n0tv.getWidth()="+tv.getWidth()+
							"0ellipsize="+ellipsize.toString()+
							"\n0tv.getMeasuredWidth()="+tv.getMeasuredWidth()+
							"\n0tv.getPaddingLeft()="+tv.getPaddingLeft()+
							"\n0tv.getAvailableWidth()="+tv.getAvailableWidth());
	
	
	//增加整体布局监听

	ViewTreeObserver vto = tv.getViewTreeObserver();  

	vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener(){ 

	    @Override 
	    public void onGlobalLayout() { 

	    	tv.getViewTreeObserver().removeGlobalOnLayoutListener(this);     

	    int height =tv.getMeasuredHeight(); 
	    int width =tv.getMeasuredWidth();  
	    Log.d("阿萨德法师打发卡是", "height ="+tv.getMeasuredHeight()+";width ="+tv.getMeasuredWidth()+";");

	    }
	});
	
	
	}
	
	public void resetEditText(View view) {
		ed.setText("一二三四五六七八九十一二三四五六七八九十一二三四五六七八九十一二三四五六七八九十一二三四五六七八九十");
//		ed.setText("1234567890123456789012345678901234567890");
	}
}




    
    

    

    

package com.example.ellsptextview;

import android.R.bool;
import android.R.integer;
import android.content.Context;
import android.graphics.Paint;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

public class EllpsizeTextView extends TextView {


	public EllpsizeTextView(Context context, AttributeSet attrs,
			int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		// TODO Auto-generated constructor stub
	}

	public EllpsizeTextView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
	}

	public EllpsizeTextView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
	}

	public int getAvailableWidth() {
		return getWidth() - getPaddingLeft() - getPaddingRight();
	}
	public int getAvailableHeight() {
		return getHeight() - getPaddingTop() - getPaddingRight();
	}

	public boolean isOverFlowed() {
		Paint paint = getPaint();
		int width =View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
		
		int height =View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
		
		measure(width,height);
		
		float width0 = paint.measureText(getText().toString());
		Log.d("EllipsizeTextView", width0+"~~~~"+getAvailableWidth());
		if (width0 > getAvailableWidth()) return true;
		return false;
	}
	
	public boolean isEllipsize() {
		
		return false;
	}
	
	
//	public int getLines() {
//		Paint paint = getPaint();
//		paint.getLetterSpacing();
//		float width = paint.measureText(getText().toString());
//	}

//	@Override
//	protected void onTextChanged(CharSequence text, int start,
//			int lengthBefore, int lengthAfter) {
//		// TODO Auto-generated method stub
//		super.onTextChanged(text, start, lengthBefore, lengthAfter);
//	}

	
}

你可能感兴趣的:(Android开发日志)