对于wrap_content形式的宽高,App需要测量它们的实际长度,需要测量的实体主要有3种:
(1)文本尺寸测量文本尺寸分为文本的宽度和高度,需根据文本大小分别计算。
(2)图形尺寸测量如果图形是Bitmap格式,就调用getWidth和getHeight方法;如果图形是Drawable格式,就调用getIntrinsicWidth和getIntrinsicHeight方法。
(3)布局尺寸测量调用measure方法按照测量规格进行测量操
===========================================================================================
文本尺寸的测量
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:padding="5dp" >
-
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="40dp" >
-
- <TextView
- android:id="@+id/tv_size"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_alignParentLeft="true"
- android:gravity="center"
- android:text="字体大小:"
- android:textColor="@color/black"
- android:textSize="17sp" />
-
- <Spinner
- android:id="@+id/sp_size"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_toRightOf="@+id/tv_size"
- android:gravity="left|center"
- android:spinnerMode="dialog" />
- </RelativeLayout>
-
- <TextView
- android:id="@+id/tv_desc"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="left"
- android:textColor="@color/black"
- android:textSize="17sp" />
-
- <TextView
- android:id="@+id/tv_text"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:padding="10dp"
- android:gravity="center"
- android:text="每逢佳节倍思亲"
- android:textColor="@color/black" />
-
- </LinearLayout>
- <TextView xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="40dp"
- android:singleLine="true"
- android:gravity="center"
- android:textSize="17sp"
- android:textColor="#0000ff" />
代码:
- package com.example.myapplication;
-
- import androidx.appcompat.app.AppCompatActivity;
- import android.os.Bundle;
- import android.util.TypedValue;
- import android.view.View;
- import android.widget.AdapterView;
- import android.widget.ArrayAdapter;
- import android.widget.Spinner;
- import android.widget.TextView;
- import com.example.myapplication.util.MeasureUtil;
-
- public class MainActivity extends AppCompatActivity
- {
- private TextView tv_desc, tv_text;
-
- @Override
- protected void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
-
- tv_desc = findViewById(R.id.tv_desc);
- tv_text = findViewById(R.id.tv_text);
-
-
- initSizeSpinner(); // 初始化文字大小的下拉框
- }
-
- // 初始化文字大小的下拉框
- private void initSizeSpinner()
- {
- ArrayAdapter<String> sizeAdapter = new ArrayAdapter<String>(this, R.layout.item_select, descArray);
-
- Spinner sp_size = findViewById(R.id.sp_size);
- sp_size.setPrompt("请选择文字大小");
- sp_size.setAdapter(sizeAdapter);
- sp_size.setOnItemSelectedListener(new SizeSelectedListener());
- sp_size.setSelection(0);
-
- }
-
- private String[] descArray = {"12sp", "15sp", "17sp", "20sp", "22sp", "25sp", "27sp", "30sp"};
-
- private int[] sizeArray = {12, 15, 17, 20, 22, 25, 27, 30};
-
- class SizeSelectedListener implements AdapterView.OnItemSelectedListener
- {
-
-
- public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3)
- {
-
- String text = tv_text.getText().toString();
-
- int textSize = sizeArray[arg2];
-
- tv_text.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize);
-
- // 计算获取指定文本的宽度(其实就是长度)
- int width = (int) MeasureUtil.getTextWidth(text, textSize);
-
- // 计算获取指定文本的高度
- int height = (int) MeasureUtil.getTextHeight(text, textSize);
-
- String desc = String.format("下面文字的宽度是%d,高度是%d", width, height);
-
- tv_desc.setText(desc);
- }
-
- public void onNothingSelected(AdapterView<?> arg0) {}
-
- }
-
- }
MeasureUtil
- package com.example.myapplication.util;
-
- import android.app.Activity;
- import android.graphics.Paint;
- import android.graphics.Paint.FontMetrics;
- import android.text.TextUtils;
- import android.view.View;
- import android.view.View.MeasureSpec;
- import android.view.ViewGroup;
- import android.view.ViewGroup.LayoutParams;
- import android.widget.LinearLayout;
-
- public class MeasureUtil
- {
-
- // 获取指定文本的宽度(其实就是长度)
- public static float getTextWidth(String text, float textSize)
- {
- if (TextUtils.isEmpty(text))
- {
- return 0;
- }
-
- Paint paint = new Paint(); // 创建一个画笔对象
- paint.setTextSize(textSize); // 设置画笔的文本大小
- return paint.measureText(text); // 利用画笔丈量指定文本的宽度
- }
-
- // 获取指定文本的高度
- public static float getTextHeight(String text, float textSize)
- {
- Paint paint = new Paint(); // 创建一个画笔对象
- paint.setTextSize(textSize); // 设置画笔的文本大小
- FontMetrics fm = paint.getFontMetrics(); // 获取画笔默认字体的度量衡
- return fm.descent - fm.ascent; // 返回文本自身的高度
- //return fm.bottom - fm.top + fm.leading; // 返回文本所在行的行高
- }
-
- // 根据资源编号获得线性布局的实际高度(页面来源)
- public static float getRealHeight(Activity act, int resid)
- {
- LinearLayout llayout = act.findViewById(resid);
- return getRealHeight(llayout);
- }
-
- // 根据资源编号获得线性布局的实际高度(视图来源)
- public static float getRealHeight(View parent, int resid)
- {
- LinearLayout llayout = parent.findViewById(resid);
- return getRealHeight(llayout);
- }
-
- // 计算指定线性布局的实际高度
- public static float getRealHeight(View child)
- {
- LinearLayout llayout = (LinearLayout) child;
-
- // 获得线性布局的布局参数
- LayoutParams params = llayout.getLayoutParams();
-
- if (params == null)
- {
- params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
- }
-
- // 获得布局参数里面的宽度规格
- int wdSpec = ViewGroup.getChildMeasureSpec(0, 0, params.width);
-
- int htSpec;
-
- if (params.height > 0) { // 高度大于0,说明这是明确的dp数值
- // 按照精确数值的情况计算高度规格
- htSpec = MeasureSpec.makeMeasureSpec(params.height, MeasureSpec.EXACTLY);
- } else { // MATCH_PARENT=-1,WRAP_CONTENT=-2,所以二者都进入该分支
- // 按照不确定的情况计算高度规则
- htSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
- }
- llayout.measure(wdSpec, htSpec); // 重新丈量线性布局的宽高
- // 获得并返回线性布局丈量之后的高度。调用getMeasuredWidth方法可获得宽度
- return llayout.getMeasuredHeight();
- }
-
- }
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" >
-
- <include layout="@layout/drag_drop_header" />
-
- <TextView
- android:id="@+id/tv_desc"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:padding="5dp"
- android:gravity="left"
- android:textColor="@color/black"
- android:textSize="17sp" />
-
- </LinearLayout>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/ll_header"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="#eeeeee"
- android:gravity="center_horizontal"
- android:orientation="vertical"
- android:paddingBottom="15dp"
- android:paddingTop="15dp" >
-
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/ic_header" />
-
- <LinearLayout
- android:id="@+id/ll_content"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:orientation="horizontal" >
-
- <ImageView
- android:id="@+id/iv_arrow"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:src="@drawable/ic_arrow" />
-
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="10dp"
- android:gravity="center_horizontal"
- android:orientation="vertical" >
-
- <TextView
- android:id="@+id/tv_tips"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="轻轻下拉,刷新精彩..."
- android:textColor="@color/black"
- android:textSize="17sp" />
- </LinearLayout>
- </LinearLayout>
-
- </LinearLayout>
代码:
- package com.example.myapplication;
-
- import androidx.appcompat.app.AppCompatActivity;
- import android.os.Bundle;
- import android.widget.LinearLayout;
- import android.widget.TextView;
- import com.example.myapplication.util.MeasureUtil;
-
- public class MainActivity extends AppCompatActivity
- {
-
- @Override
- protected void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
-
- LinearLayout ll_header = findViewById(R.id.ll_header);
-
- TextView tv_desc = findViewById(R.id.tv_desc);
-
- // 计算获取线性布局的实际高度
- float height = MeasureUtil.getRealHeight(ll_header);
-
- String desc = String.format("上面下拉刷新头部的高度是%f", height);
-
- tv_desc.setText(desc);
- }
- }
MeasureUtil
- package com.example.myapplication.util;
-
- import android.app.Activity;
- import android.graphics.Paint;
- import android.graphics.Paint.FontMetrics;
- import android.text.TextUtils;
- import android.view.View;
- import android.view.View.MeasureSpec;
- import android.view.ViewGroup;
- import android.view.ViewGroup.LayoutParams;
- import android.widget.LinearLayout;
-
- public class MeasureUtil
- {
-
- // 获取指定文本的宽度(其实就是长度)
- public static float getTextWidth(String text, float textSize)
- {
- if (TextUtils.isEmpty(text))
- {
- return 0;
- }
-
- Paint paint = new Paint(); // 创建一个画笔对象
- paint.setTextSize(textSize); // 设置画笔的文本大小
- return paint.measureText(text); // 利用画笔丈量指定文本的宽度
- }
-
- // 获取指定文本的高度
- public static float getTextHeight(String text, float textSize)
- {
- Paint paint = new Paint(); // 创建一个画笔对象
- paint.setTextSize(textSize); // 设置画笔的文本大小
- FontMetrics fm = paint.getFontMetrics(); // 获取画笔默认字体的度量衡
- return fm.descent - fm.ascent; // 返回文本自身的高度
- //return fm.bottom - fm.top + fm.leading; // 返回文本所在行的行高
- }
-
- // 根据资源编号获得线性布局的实际高度(页面来源)
- public static float getRealHeight(Activity act, int resid)
- {
- LinearLayout llayout = act.findViewById(resid);
- return getRealHeight(llayout);
- }
-
- // 根据资源编号获得线性布局的实际高度(视图来源)
- public static float getRealHeight(View parent, int resid)
- {
- LinearLayout llayout = parent.findViewById(resid);
- return getRealHeight(llayout);
- }
-
- // 计算指定线性布局的实际高度
- public static float getRealHeight(View child)
- {
- LinearLayout llayout = (LinearLayout) child;
-
- // 获得线性布局的布局参数
- LayoutParams params = llayout.getLayoutParams();
-
- if (params == null)
- {
- params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
- }
-
- // 获得布局参数里面的宽度规格
- int wdSpec = ViewGroup.getChildMeasureSpec(0, 0, params.width);
-
- int htSpec;
-
- if (params.height > 0) { // 高度大于0,说明这是明确的dp数值
- // 按照精确数值的情况计算高度规格
- htSpec = MeasureSpec.makeMeasureSpec(params.height, MeasureSpec.EXACTLY);
- } else { // MATCH_PARENT=-1,WRAP_CONTENT=-2,所以二者都进入该分支
- // 按照不确定的情况计算高度规则
- htSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
- }
- llayout.measure(wdSpec, htSpec); // 重新丈量线性布局的宽高
- // 获得并返回线性布局丈量之后的高度。调用getMeasuredWidth方法可获得宽度
- return llayout.getMeasuredHeight();
- }
-
- }