本文介绍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 dp 字体设置 android 字体大小自适应_Android dp 字体设置

 

1.3 布局xml和dimens.xml代码

(1)布局xml

<?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     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">
     <TextView
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:textSize="@dimen/text_large"
         android:text="河南大学"/>
 </LinearLayout>

1.4 运行结果

values-1024x768目录下的dimens.xml

<?xml version="1.0" encoding="utf-8"?>
 <resources>
     <!--text size-->
     <dimen name="text_large">10sp</dimen>
 </resources>

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

Android dp 字体设置 android 字体大小自适应_android_02

 

Android dp 字体设置 android 字体大小自适应_android_03

                               设备竖屏                                                                       设备横屏

values-1280x720目录下的dimens.xml

<?xml version="1.0" encoding="utf-8"?>
 <resources>
     <!--text size-->
     <dimen name="text_large">100sp</dimen>
 </resources>

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

Android dp 字体设置 android 字体大小自适应_xml_04

 

Android dp 字体设置 android 字体大小自适应_控件_05

                        设备竖屏                                                          设备横屏

 

2、 Google新属性

2.1 属性介绍

Google的新属性如下:

android:autoSizeMaxTextSize="60sp"
 android:autoSizeMinTextSize="6dp"
 android:autoSizeTextType="uniform"


注意:他们需要配合android:maxLines="1"一起使用,并且上面三个属性只能兼容SdkVersion=26以上的版本。

2.2 布局xml文件

<?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     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">
     <TextView
         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="河南大学"/>
     <TextView
         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年在古城开封清代贡院旧址建校!"/>
</LinearLayout>

2.3 运行结果

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

Android dp 字体设置 android 字体大小自适应_android_06

 

Android dp 字体设置 android 字体大小自适应_xml_07

                           设备竖屏                                        设备横屏

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

Android dp 字体设置 android 字体大小自适应_Android dp 字体设置_08

 

Android dp 字体设置 android 字体大小自适应_控件_09

                              设备竖屏                                           设备横屏

 

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

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

3.1 xml源代码

<?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     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">
     <TextView
         android:id="@+id/test_text_view"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:textSize="40sp"
         android:maxLines="1"
         android:text="河南大学"/>
     <Button
         android:id="@+id/test_button"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:textSize="40sp"
         android:maxLines="1"
         android:text="河南大学是百年老校!1912年在古城开封清代贡院旧址建校!"/>
     <EditText
         android:id="@+id/test_edit_text"
         android:layout_width="match_parent"
         android:maxLines="1"
         android:layout_height="wrap_content"/>
 </LinearLayout>

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 dp 字体设置 android 字体大小自适应_xml_10

 

Android dp 字体设置 android 字体大小自适应_Android dp 字体设置_11

                                  设备竖屏                                                                 设备横屏