Android自动调整TextView的大小

时间:2020-02-23 14:28:46  来源:igfitidea点击:

在本教程中,我们将研究如何实现TextView,使其能够根据Android应用程序中指定的可用空间和属性自动调整自身大小。

自动调整TextView的大小

Android Oreo引入了自动调整TextView大小的功能。
如果您设置了必需的属性,则文本大小将在其视图内自动更改。
自动调整TextView的大小一直支持向后兼容,直到API 4。

要使用自动调整TextView大小,您必须使用SDK 26依赖关系或者更高版本:

implementation 'com.android.support:appcompat-v7:26.1.0'

以下是您必须在TextView上添加的核心属性,才能启用TextSize自动调整大小:

  • android:autoSizeTextType-设置为统一值或者无。
    统一垂直和水平调整文本大小
  • android:autoSizeMaxTextSize– TextView的最大文本大小
  • android:autoSizeMinTextSize– TextView的最小文本大小

可以在xml中将自动调整大小的TextView定义为:

<TextView
      android:id="@+id/autoTextView"
      android:layout_width="match_parent"
      android:layout_height="125dp"
      android:text="Resizable TextView here."
      android:autoSizeMaxTextSize="100sp"
      android:autoSizeMinTextSize="12sp"
      android:autoSizeTextType="uniform" 

为了使自动调整大小的TextView正常工作,建议不要使用WRAP_CONTENT。

文字如何自动调整大小?

有三种方法可以做到:

  • 默认值-大小更改发生1像素。
    这表示粒度为1像素

  • 粒度–这是一种尺寸,文本大小可在最小和最大文本大小之间逐步增大或者减小。
    示例:ʻandroid:autoSizeStepGranularity =" 2sp""将文本大小增加/减少2 sp。

  • 预设–用于从一组预定义的文字大小值中自动调整文字大小。

使用预设

我们可以在values文件夹的arrays.xml中定义预定义的。

<resources>
<array name="autosize">
  <item>10sp</item>
  <item>30sp</item>
  <item>20sp</item>
  <item>40sp</item>
  <item>100sp</item>
</array>
</resources>

在TextView中将此设置为:

<TextView
  android:layout_width="match_parent"
  android:layout_height="200dp"
  android:autoSizeTextType="uniform"
  app:autoSizePresetSizes="@array/autosize" 

自动调整Or-Pre设备的尺寸

以上属性仅在Android Oreo及更高版本上可以正常使用。
为了使其与旧版本兼容,我们需要做两件事:

  • 使用AppCompatTextView小部件代替TextView
  • 使用app:命名法

在XML中定义自动调整大小的TextView为:

<android.support.v7.widget.AppCompatTextView
      android:layout_width="match_parent"
      android:layout_height="60dp"
      android:text="TextView"
      app:autoSizeMaxTextSize="100sp"
      app:autoSizeMinTextSize="8sp"
      app:autoSizeStepGranularity="2sp"
      app:autoSizeTextType="uniform"
      

以编程方式自动调整TextView的大小

要以编程方式在自动调整大小的TextView上设置属性,我们使用TextViewCompat类。

您需要传递TextView实例以及属性的相应大小。

将autoSize文本类型设置为:" TextViewCompat.AUTO_SIZE_TEXT_TYPE_NONE"或者" TextViewCompat.AUTO_SIZE_TEXT_TYPE_UNIFORM"。

以编程方式设置预设:

要以编程方式设置预设,您需要不同地定义arrays.xml。

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <array name="autosize">
      <item>20</item>
      <item>40</item>
      <item>50</item>
      <item>60</item>
      <item>70</item>
  </array>
</resources>

要在TextView上进行设置,请执行以下操作:

TextViewCompat.setAutoSizeTextTypeUniformWithPresetSizes(textView, getResources().getIntArray(R.array.autosize), TypedValue.COMPLEX_UNIT_SP);

让我们构建一个Android应用程序,演示自动调整TextView大小的各种用例。

代码

下面给出了activity_main.xml布局的代码:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android"
  xmlns:app="https://schemas.android.com/apk/res-auto"
  xmlns:tools="https://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".MainActivity">

  <TextView
      android:id="@+id/textView"
      android:layout_width="0dp"
      android:layout_height="125dp"
      android:background="@android:color/black"
      android:text="Not resizable TextView. The text size is fixed here."
      android:textColor="@android:color/white"
      app:layout_constraintEnd_toStartOf="@+id/autoTextView"
      app:layout_constraintHorizontal_bias="0.5"
      app:layout_constraintHorizontal_chainStyle="packed"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toBottomOf="@+id/editTextPreset" 

  <android.support.v7.widget.AppCompatTextView
      android:id="@+id/autoTextView"
      android:layout_width="0dp"
      android:layout_height="125dp"
      android:background="@android:color/black"
      android:text="Resizable TextView here. This can vary the text size based on it."
      android:textColor="@android:color/white"
      app:autoSizeMaxTextSize="100sp"
      app:autoSizeMinTextSize="12sp"
      app:autoSizeStepGranularity="2sp"
      app:autoSizeTextType="uniform"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintHorizontal_bias="0.5"
      app:layout_constraintStart_toEndOf="@+id/textView"
      app:layout_constraintTop_toBottomOf="@+id/editTextPreset" 

  <android.support.v7.widget.AppCompatTextView
      android:id="@+id/autoTextViewDynamic"
      android:layout_width="match_parent"
      android:layout_height="60dp"
      android:layout_marginEnd="8dp"
      android:layout_marginLeft="8dp"
      android:layout_marginRight="8dp"
      android:layout_marginStart="8dp"
      android:layout_marginTop="8dp"
      android:text="TextView"
      app:autoSizeMaxTextSize="100sp"
      app:autoSizeMinTextSize="8sp"
      app:autoSizeStepGranularity="2sp"
      app:autoSizeTextType="uniform"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toTopOf="parent" 

  <EditText
      android:id="@+id/editText"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:layout_marginEnd="8dp"
      android:layout_marginLeft="8dp"
      android:layout_marginRight="8dp"
      android:layout_marginStart="8dp"
      android:layout_marginTop="8dp"
      android:ems="10"
      android:hint="Enter here"
      android:maxLines="1"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toBottomOf="@+id/autoTextViewDynamic" 

  <EditText
      android:id="@+id/editTextPreset"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:layout_marginEnd="8dp"
      android:layout_marginLeft="8dp"
      android:layout_marginRight="8dp"
      android:layout_marginStart="8dp"
      android:layout_marginTop="8dp"
      android:ems="10"
      android:hint="Enter here for preset size changes"
      android:maxLines="1"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toBottomOf="@+id/editText" 

  <android.support.v7.widget.AppCompatTextView
      android:id="@+id/autoTextViewEllipsize"
      android:layout_width="match_parent"
      android:layout_height="50dp"
      android:layout_marginTop="16dp"
      android:ellipsize="end"
      android:maxLines="1"
      android:text="Auto sizing TextView with ellipsize at the end. AppCompat TextVie2"
      app:autoSizeMaxTextSize="100sp"
      app:autoSizeMinTextSize="16sp"
      app:autoSizeStepGranularity="2sp"
      app:autoSizeTextType="uniform"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toBottomOf="@+id/textView" 

</android.support.constraint.ConstraintLayout>

我们在一个自动调整大小的TextView上添加了一个ellipisize属性。
这样,如果内容以最小文本大小填充,则剩余的文本将被截断

MainActivity.java类的代码如下:

package com.theitroad.androidautosizingtextview;

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

public class MainActivity extends AppCompatActivity {

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

      final TextView txtAutoSizeTextViewDynamic = findViewById(R.id.autoTextViewDynamic);
      final TextView textView = findViewById(R.id.textView);
      EditText editText = findViewById(R.id.editText);
      EditText editTextWithPresetChanges = findViewById(R.id.editTextPreset);

      editText.addTextChangedListener(new TextWatcher() {
          @Override
          public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

          }

          @Override
          public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

              txtAutoSizeTextViewDynamic.setText(charSequence.toString());

          }

          @Override
          public void afterTextChanged(Editable editable) {

          }
      });

      editTextWithPresetChanges.addTextChangedListener(new TextWatcher() {
          @Override
          public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
              TextViewCompat.setAutoSizeTextTypeUniformWithPresetSizes(textView, getResources().getIntArray(R.array.autosize), TypedValue.COMPLEX_UNIT_SP);
          }

          @Override
          public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
              textView.setText(charSequence);
          }

          @Override
          public void afterTextChanged(Editable editable) {

          }
      });
  }
}

我们已在两个EditText上添加了TextWatchers,它们将在更改编辑文本时更新自动调整大小的TextView。

在第二个EditText中输入文本后,我们将普通文本视图更改为自动调整大小的视图。