AutoSize属性问题探索

AutoSize属性问题探索AutoSize属性问题探索如有错误,欢迎指出Google在Android8.0(APIlevel26)中,为TextView加入了一个动态属性AutoSize。在布局文件中,直接设置autoSizeTextType属性为uniform即可。这样,文本内容便会忽略android:textSize属性,从水平和垂直两个方向上缩放文本的内容。android:autoSizeTextType=”uniform”android:autoSizeMaxT

大家好,又见面了,我是你们的朋友全栈君。

AutoSize属性问题探索

如有错误,欢迎指出

Google在Android 8.0(API level 26)中,为TextView加入了一个动态属性AutoSize。
在布局文件中,直接设置autoSizeTextType属性为uniform即可。这样,文本内容便会忽略android:textSize属性,从水平和垂直两个方向上缩放文本的内容。

            android:autoSizeTextType="uniform"
            android:autoSizeMaxTextSize="35dp"
            android:autoSizeStepGranularity="1dp"
            android:autoSizeMinTextSize="1dp"

在API26以下,实现AutoSize需要支持库

<!-- 引入命名空间 -->
xmlns:app="http://schemas.android.com/apk/res-auto"

            app:autoSizeTextType="uniform"
            app:autoSizeMaxTextSize="35dp"
            app:autoSizeStepGranularity="1dp"
            app:autoSizeMinTextSize="1dp"

最近在使用autoSize时遇到了几个坑:

  1. 不能与SingleLine一起用
    与single连用后,当文本过长时会显示省略号,改用maxLines=1即可

  2. RadioButton的autosize属性
    经过多次试验,支持库在某些安卓版本上好像无法实现RadioButton的autosize属性

API app android
25 NO NO
26 NO YES
28 YES YES

我们知道,在API26中为TextView引入了AutoSize属性,而RadioButton -> CompoundButton(接口) -> Button -> TextView,因此在API26+中通过android设置的autosize属性可以生效

现在来分析通过app设置的autosize属性
support v7中的RadioButton的完整类名为:android.support.v7.widget.AppCompatRadioButton

public class AppCompatRadioButton extends RadioButton implements TintableCompoundButton { 
   
    private final AppCompatCompoundButtonHelper mCompoundButtonHelper;
    private final AppCompatTextHelper mTextHelper;
    ......
    public AppCompatRadioButton(Context context, AttributeSet attrs, int defStyleAttr) { 
   
        super(TintContextWrapper.wrap(context), attrs, defStyleAttr);
        this.mCompoundButtonHelper = new AppCompatCompoundButtonHelper(this);
        this.mCompoundButtonHelper.loadFromAttributes(attrs, defStyleAttr);
        this.mTextHelper = new AppCompatTextHelper(this);
        this.mTextHelper.loadFromAttributes(attrs, defStyleAttr);
    }
    ......
}

可以看到,AppCompatRadioButton中存在一个与text相关的成员变量mTextHelper

    AppCompatTextHelper(TextView view) { 
   
        this.mView = view;
        this.mAutoSizeTextHelper = new AppCompatTextViewAutoSizeHelper(this.mView);
    }

终于看到autosize了,现在去看看mAutoSizeTextHelper

class AppCompatTextViewAutoSizeHelper { 
   
    AppCompatTextViewAutoSizeHelper(TextView textView) { 
   
        this.mTextView = textView;
        this.mContext = this.mTextView.getContext();
    }
    void setAutoSizeTextTypeWithDefaults(int autoSizeTextType) { 
   ......}
    void setAutoSizeTextTypeUniformWithConfiguration(int autoSizeMinTextSize, int autoSizeMaxTextSize, int autoSizeStepGranularity, int unit) throws IllegalArgumentException { 
   ......}
    void setAutoSizeTextTypeUniformWithPresetSizes(@NonNull int[] presetSizes, int unit) throws IllegalArgumentException { 
   ......}
    ......    
}

可以发现 AppCompatTextViewAutoSizeHelper 类正是实现autosize属性的重要类,那么,是如何调用的呢?
我们再回到AppCompatRadioButton

    public AppCompatRadioButton(Context context, AttributeSet attrs, int defStyleAttr) { 
   
        super(TintContextWrapper.wrap(context), attrs, defStyleAttr);
        this.mCompoundButtonHelper = new AppCompatCompoundButtonHelper(this);
        this.mCompoundButtonHelper.loadFromAttributes(attrs, defStyleAttr);
        this.mTextHelper = new AppCompatTextHelper(this);
        this.mTextHelper.loadFromAttributes(attrs, defStyleAttr);
    }

通过搜索,mTextHelper仅出现在构造函数中
我们来看 this.mTextHelper = new AppCompatTextHelper(this);

    AppCompatTextHelper(TextView view) { 
   
        this.mView = view;
        this.mAutoSizeTextHelper = new AppCompatTextViewAutoSizeHelper(this.mView);
    }

    AppCompatTextViewAutoSizeHelper(TextView textView) { 
   
        this.mTextView = textView;
        this.mContext = this.mTextView.getContext();
    }

可知,this.mTextHelper = new AppCompatTextHelper(this);旨在初始化,还未涉及autosize属性的初始化
现在来看this.mTextHelper.loadFromAttributes(attrs, defStyleAttr); 从名称看,该方法用于加载属性

//AppCompatTextHelper.java
    @SuppressLint({ 
   "NewApi"})
    void loadFromAttributes(AttributeSet attrs, int defStyleAttr) { 
   
        ......
        this.mAutoSizeTextHelper.loadFromAttributes(attrs, defStyleAttr);
        if (AutoSizeableTextView.PLATFORM_SUPPORTS_AUTOSIZE && this.mAutoSizeTextHelper.getAutoSizeTextType() != 0) { 
   
            int[] autoSizeTextSizesInPx = this.mAutoSizeTextHelper.getAutoSizeTextAvailableSizes();
            if (autoSizeTextSizesInPx.length > 0) { 
   
                if ((float)this.mView.getAutoSizeStepGranularity() != -1.0F) { 
   
                    this.mView.setAutoSizeTextTypeUniformWithConfiguration(this.mAutoSizeTextHelper.getAutoSizeMinTextSize(), this.mAutoSizeTextHelper.getAutoSizeMaxTextSize(), this.mAutoSizeTextHelper.getAutoSizeStepGranularity(), 0);
                } else { 
   
                    this.mView.setAutoSizeTextTypeUniformWithPresetSizes(autoSizeTextSizesInPx, 0);
                }
            }
        }
        ......
    }

可以看到,该方法中存在setAutoSizeTextXXX 然而它要求AutoSizeableTextView.PLATFORM_SUPPORTS_AUTOSIZE为true,也就是VERSION.SDK_INT >= 27; 这里可以解释在API28上app设置autosize属性生效

继续看this.mAutoSizeTextHelper.loadFromAttributes(attrs, defStyleAttr);

//AppCompatTextViewAutoSizeHelper.java
    void loadFromAttributes(AttributeSet attrs, int defStyleAttr) { 
   
        ......
        if (this.supportsAutoSizeText()) { 
   
            if (this.mAutoSizeTextType == 1) { 
   
                ......
                this.setupAutoSizeText();
            }
        } else { 
   
            this.mAutoSizeTextType = 0;
        }
    }

//这里的mTextView是AppCompatRadioButton 应该返回true
    private boolean supportsAutoSizeText() { 
   
        return !(this.mTextView instanceof AppCompatEditText);
    }

//这个方法设置了一些属性
    private boolean setupAutoSizeText() { 
   
        if (this.supportsAutoSizeText() && this.mAutoSizeTextType == 1) { 
   
            if (!this.mHasPresetAutoSizeValues || this.mAutoSizeTextSizesInPx.length == 0) { 
   
                int autoSizeValuesLength = 1;

                for(float currentSize = (float)Math.round(this.mAutoSizeMinTextSizeInPx); Math.round(currentSize + this.mAutoSizeStepGranularityInPx) <= Math.round(this.mAutoSizeMaxTextSizeInPx); currentSize += this.mAutoSizeStepGranularityInPx) { 
   
                    ++autoSizeValuesLength;
                }

                int[] autoSizeTextSizesInPx = new int[autoSizeValuesLength];
                float sizeToAdd = this.mAutoSizeMinTextSizeInPx;

                for(int i = 0; i < autoSizeValuesLength; ++i) { 
   
                    autoSizeTextSizesInPx[i] = Math.round(sizeToAdd);
                    sizeToAdd += this.mAutoSizeStepGranularityInPx;
                }

                this.mAutoSizeTextSizesInPx = this.cleanupAutoSizePresetSizes(autoSizeTextSizesInPx);
            }

            this.mNeedsAutoSizeText = true;
        } else { 
   
            this.mNeedsAutoSizeText = false;
        }

        return this.mNeedsAutoSizeText;
    }

到这里后续已经没有调用了,也就是说,在API27以下AppCompatRadioButton并没有实现autosize属性

那么AppCompatTextView和AppCompatButton是如何实现的呢?
这里主要分析AppCompatTextView

public class AppCompatTextView extends TextView implements TintableBackgroundView,
        TintableCompoundDrawablesView, AutoSizeableTextView { 
   
        ......
    public AppCompatTextView(
            @NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { 
   
        super(TintContextWrapper.wrap(context), attrs, defStyleAttr);

        ThemeUtils.checkAppCompatTheme(this, getContext());

        mBackgroundTintHelper = new AppCompatBackgroundHelper(this);
        mBackgroundTintHelper.loadFromAttributes(attrs, defStyleAttr);

        mTextHelper = new AppCompatTextHelper(this);
        mTextHelper.loadFromAttributes(attrs, defStyleAttr);
        mTextHelper.applyCompoundDrawablesTints(); //比RadioButton多出

        mTextClassifierHelper = new AppCompatTextClassifierHelper(this);
    }
    ......
    public void setAutoSizeTextTypeWithDefaults(
            @TextViewCompat.AutoSizeTextType int autoSizeTextType) { 
   
        if (Build.VERSION.SDK_INT >= 26) { 
   
            super.setAutoSizeTextTypeWithDefaults(autoSizeTextType);
        } else { 
   
            if (mTextHelper != null) { 
   
                mTextHelper.setAutoSizeTextTypeWithDefaults(autoSizeTextType);
            }
        }
    }
    public void setAutoSizeTextTypeUniformWithConfiguration(
            int autoSizeMinTextSize,
            int autoSizeMaxTextSize,
            int autoSizeStepGranularity,
            int unit) throws IllegalArgumentException { 
   
        if (Build.VERSION.SDK_INT >= 26) { 
   
            super.setAutoSizeTextTypeUniformWithConfiguration(
                    autoSizeMinTextSize, autoSizeMaxTextSize, autoSizeStepGranularity, unit);
        } else { 
   
            if (mTextHelper != null) { 
   
                mTextHelper.setAutoSizeTextTypeUniformWithConfiguration(
                        autoSizeMinTextSize, autoSizeMaxTextSize, autoSizeStepGranularity, unit);
            }
        }
    }
    ......

相比于AppCompatRadioButton,它实现了AutoSizeableTextView接口,重写了setAutoSizeTextXXX方法,因此可以实现autosize属性

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/135086.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 3D移动 translate3d

    3D移动 translate3d3D转换我们主要学习工作中最常用的3D位移和3D旋转主要知识点3D移动在2D移动的基础上多加了一个可以移动的方向,就是z轴方向。translform:translateX(100px):仅仅是在x轴上移动 translform:translateY(100px):仅仅是在Y轴上移动 translform:translateZ(100px):仅仅是在Z轴上移动(注意:translateZ一般用px作单位) transform:translate3d(x,y,z):其中x、y、z分别指要移动的

    2022年10月23日
    0
  • SPSS聚类分析——一个案例演示聚类分…「建议收藏」

    SPSS聚类分析——一个案例演示聚类分…「建议收藏」本文实际为2010年5月8日完成并发布的,浏览量:7199,评论数:5。http://hi.baidu.com/datasoldier/item/37abae32474bf7f1a884289f在百度新版空间升级过程中,该篇文章丢失,今天,重新更新并发布,作为SPSS案例分析系列的第17篇文章。同时希望百度新版空间能不断完善,在升级过程中尽量避免出现文章丢失的现象。案例数据源:有20种

    2022年10月18日
    1
  • Android应用开发揭秘2

    Android应用开发揭秘2Android应用开发揭秘2

    2022年6月11日
    28
  • 使用Lucene检索文档中的关键字

    使用Lucene检索文档中的关键字

    2021年8月21日
    56
  • java局域网发送文件_Java如何实现局域网文件传输代码案例分享

    java局域网发送文件_Java如何实现局域网文件传输代码案例分享这篇文章主要介绍了java实现局域网文件传输的实例的相关资料,这里提供了实现代码可以帮助大家理解TCP及文件读写的知识,需要的朋友可以参考下java实现局域网文件传输的实例本文主要实现局域网文件传输的实例,对java的TCP知识,文件读写,Socket等知识的理解应用,很好的实例,大家参考下,实现代码:ClientFile.java/***更多资料欢迎浏览凯哥学堂官网:http://kai…

    2022年5月4日
    49
  • python简单代码表白-python告白代码,只属于程序员的浪漫

    python简单代码表白-python告白代码,只属于程序员的浪漫不知何时,不知何因,程序员这个行业成为大家茶余饭后取乐的无辜群体。只要说到程序员,脑海中就浮现出刻板印象,标配穿搭:格子衫,牛仔裤,黑框眼镜。当然秃顶也是必须的,更狠的吐槽还有邋里邋遢,不懂浪漫,不知人情世故!开始可能只是幽默玩笑,后面慢慢就越传越多,大家便信以为真!可是程序员真的是这样吗?随着现在编程这个行业的普遍高薪收入,程序员又成为大家关注的焦点,深入的了解后,发现程序员其实是很可爱的一个群…

    2022年5月25日
    31

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号