首页 > 其他分享 >自定义控件——视图的构建过程——视图的测量方法

自定义控件——视图的构建过程——视图的测量方法

时间:2022-09-03 13:44:07浏览次数:78  
标签:控件 自定义 text 视图 llayout import android 文本 public

 

 

 

 

 

 

 

 

 

 

对于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();
    }

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

123

标签:控件,自定义,text,视图,llayout,import,android,文本,public
From: https://www.cnblogs.com/xiaobaibailongma/p/16652468.html

相关文章

  • Google库 来实现 按钮图片等控件的圆角形状 告别shape、各种 drawable
    直接上导入implementation'com.google.android.material:material:1.2.0'MaterialButton继承AppCompatButton,在原来Button的基础上做了一些扩展,如圆角、描边等......
  • MySQL教程 - 视图(View)
    更新记录转载请注明出处。2022年9月3日发布。2022年9月3日从笔记迁移到博客。说明视图是虚拟的表,是一种存储结构可以对视图进行和表一样的操作,但一般用于查询数......
  • Java自定义Annotation注解开发详解
    Java自定义Annotation注解开发详解目录介绍一、运行期的自定义注解1.ClassLevelAnnotation2.MethodLevelAnnotation3.FieldLevelAnnotation4.使用自定义......
  • C#编写折线图控件
    原文:https://blog.csdn.net/bear_csdn/article/details/82918637 C#绘制统计图(柱状图,折线图,扇形图) :https://www.cnblogs.com/ziyiFly/archive/2008/09/24/1297......
  • 视图层与模板层
    网页伪静态伪静态页面其实是动态页面,只是看起来和静态页面一样,将动态网页伪装成静态网页,可以提升网页被搜索引擎收录的概率,表现上网址看的像一个具体的文件路径deftest(......
  • 【Django】 第04回 视图层与模板层
    目录1.网页伪静态2.视图层2.1视图函数的返回值问题2.2视图函数返回json格式数据2.3from表单携带文件数据2.4FEV与CBV2.5CBV源码分析3.模板层3.1模板语法传值3.2......
  • django之视图层与模板层
    一、伪静态网页'''其实就是如果一个网页如果是一个静态网页的话那么浏览器搜索会更容易搜索的到而如果一个动态网页想要让浏览器更容易搜索到的话可以在路由匹配的时......
  • pyqt5控件使用方法
    一)消息框(QMessageBox)一、提供的类型QMessageBox.information信息框QMessageBox.question问答框QMessageBox.warning警告QMessageBox.ctitical危险......
  • 自定义权限注解
    目录自定义权限注解1、新增一个注解2、增加一个bean监听处理器3、使用注解4、网关中对开放的路径放行自定义权限注解1、新增一个注解ps:此注解可以作用到类上或方法上i......
  • 自定义注解+aop做日志记录
    自定义一个注解:@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public@interfaceCommitLog{/***类型名称*@retu......