Android中字体大小自适应设备

本文介绍3种字体大小自适应设备的方法。第1种方法是建立针对不同屏幕分辨率的values目录,然后在相应的values下建立dimens.xml文件,并修改其中的值,这种方法比较繁琐,同时要建立多个value文件;第2种方法是使用Google新发布的3个属性autoSizeMaxTextSize、autoSizeMinTextSize、autoSizeTextType,但是这3个属性支持的最小SdkVersion(minSdkVersion)是26,SdkVersion小于26的不能用;第3种方法是在使用控件时,先计算设备的分辨率,然后,计算控件中相应文字的长度,最后设置字体大小。

1、建立value目录的方法

1.1 分辨率了解

常见的手机或平板的分辨率有480x320、640x480、800x480、800x600、1024x768、1280x720、1280x800、1920x1080、1920x1280等等。

1.2 建立values目录

针对不同的屏幕分辨率建立不同的values目录名称,例如:values-480x320、values-640x480、values-800x480、values-800x600、values-1024x768、values-1280x720、values-1280x800、values-1920x1080、values-1920x1280等。

注意1:目录中的“x”是小写英文字母,不是乘号。

注意2:上述的目录设置只能适配竖屏,适配横屏会混乱,例如:屏幕分辨率是800x480,设备竖屏时能适配到values-800x480目下的dimens.xml,如果设备横屏的时候适配的可能是values-480x320目录下的dimens.xml。如果适配横屏需要将目录名称的分辨率反过来写,例如:屏幕分辨率是800x480,做屏幕适配时需要将values目录写成values-480x800。

注意3:如果没有建立与设备分辨率相应对应的values目录,系统会自动适配到已经建立的小于设备分辨率的values目录,例如:设备分辨率是800x500,则系统会自动适配到values-800x480。

           Android中字体大小自适应设备_第1张图片

 

1.3 布局xml和dimens.xml代码


(1)布局xml

    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    tools:context=".TestActivity">
            android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="@dimen/text_large"
        android:text="河南大学"/>

1.4 运行结果

values-1024x768目录下的dimens.xml


   
    10sp

分辨率是1024x768设备的运行结果如下:
(注意:设备横屏和竖屏时自适应的字体大小可能不同)

Android中字体大小自适应设备_第2张图片 Android中字体大小自适应设备_第3张图片

                               设备竖屏                                                                       设备横屏

values-1280x720目录下的dimens.xml



   
    100sp

分辨率是1280x720设备的运行结果如下:

Android中字体大小自适应设备_第4张图片 Android中字体大小自适应设备_第5张图片

                        设备竖屏                                                          设备横屏

 

 

2、 Google新属性


2.1 属性介绍

Google的新属性如下:
android:autoSizeMaxTextSize="60sp"
android:autoSizeMinTextSize="6dp"
android:autoSizeTextType="uniform"
注意:他们需要配合android:maxLines="1"一起使用,并且上面三个属性只能兼容SdkVersion=26以上的版本。

2.2 布局xml文件


    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    tools:context=".TestActivity">
            android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="40sp"
        android:maxLines="1"
        android:autoSizeMaxTextSize="60sp"
        android:autoSizeMinTextSize="6dp"
        android:autoSizeTextType="uniform"
        android:text="河南大学"/>
            android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="40sp"
        android:maxLines="1"
        android:autoSizeMaxTextSize="60sp"
        android:autoSizeMinTextSize="6dp"
        android:autoSizeTextType="uniform"
        android:text="河南大学是百年老校!1912年在古城开封清代贡院旧址建校!"/>

2.3 运行结果

(1)SdkVersion大于26的设备运行结果

Android中字体大小自适应设备_第6张图片 Android中字体大小自适应设备_第7张图片

                           设备竖屏                                        设备横屏

(2)SdkVersion=25的设备运行结果(不能自适应了)

Android中字体大小自适应设备_第8张图片 Android中字体大小自适应设备_第9张图片

                              设备竖屏                                           设备横屏

 

3、自定义重置计算字体大小

根据控件的宽度,重新计算字体的大小。首先需要获得控件的宽度和文本内容,然后,循环计算字体大小,直到文本内容完全适应控件的宽度。

3.1 xml源代码


    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    tools:context=".TestActivity">
            android:id="@+id/test_text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="40sp"
        android:maxLines="1"
        android:text="河南大学"/>
            android:id="@+id/test_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="40sp"
        android:maxLines="1"
        android:text="河南大学是百年老校!1912年在古城开封清代贡院旧址建校!"/>
            android:id="@+id/test_edit_text"
        android:layout_width="match_parent"
        android:maxLines="1"
        android:layout_height="wrap_content"/>

3.2 Activity源代码

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextPaint;
import android.text.TextWatcher;
import android.util.TypedValue;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class TestActivity extends AppCompatActivity {

    private Button button = null;
    private TextView textView = null;
    private EditText editText = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);

        this.button = findViewById(R.id.test_button);
        this.textView = findViewById(R.id.test_text_view);
        this.editText = findViewById(R.id.test_edit_text);

        this.initEvent();
    }

    /**
     * 初始化事件
     */
    private void initEvent(){
        this.editText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            // 监听EditText的长度变化
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                resetViewTextSize(editText,editText.getWidth(),editText.getText().toString().trim());
            }

            @Override
            public void afterTextChanged(Editable s) {
            }
        });
    }

    // Activity渲染结束后,回调onWindowFocusChanged方法,此时控件的width和height不再是0。
    // 注意:控件的width和height在onCreate()、onStart()和onResume()中获得的值都是0。
    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);

        this.resetViewTextSize(button,button.getWidth(),button.getText().toString().trim());
        this.resetViewTextSize(textView,textView.getWidth(),textView.getText().toString().trim());

    }

    /**
     * 重置控件中字体的大小
     * @param view view可以使EditText、Button、CheckBox、RadioButton,因为他们都继承
     * @param maxWidth
     * @param text
     */
    private void resetViewTextSize(TextView view, int maxWidth, String text) {
        // 获得控件的真实长度,去除控件的内部间距
        int realWidth = maxWidth - view.getPaddingRight() - view.getPaddingLeft();
        // 如果控件的长度小于等于0
        if (realWidth <= 0) {
            return;
        }
        // 查找合适的text长度
        TextPaint textPaint = new TextPaint(view.getPaint());
        float autoSize = textPaint.getTextSize();
        while (textPaint.measureText(text) > realWidth) {
            autoSize--;
            textPaint.setTextSize(autoSize);
        }
        // 字体大小最好使用px,因为上述使用getWidth获得的值是px,也可以使用COMPLEX_UNIT_SP是sp,但是需要转换。
        view.setTextSize(TypedValue.COMPLEX_UNIT_PX, autoSize);
    }
}

3.3 运行结果

Android中字体大小自适应设备_第10张图片 Android中字体大小自适应设备_第11张图片

                                  设备竖屏                                                                 设备横屏

你可能感兴趣的:(Android)