神奇的TextView

TextView和文字的高度

问题

首先来想一个问题,下面这个textview,他的高度是多少?

 

        <TextView
            android:id="@+id/first"
            android:layout_width="50dp"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:background="#7777ff"
            android:text="第一个"
            android:textSize="13sp" />

wrapContent的,那应该是13dp吧,很遗憾不对,我的手机上试了下是18dp,为什么呢?

分析

这是android字体文档,http://developer.android.com/reference/android/graphics/Paint.FontMetrics.html,写的比较简单,看不太懂。来看这个吧,http://stackoverflow.com/questions/27631736/meaning-of-top-ascent-baseline-descent-bottom-and-leading-in-androids-font

 

下面这张图非常好,一般来说我们的文字(特别是汉字)只占了ascent到baseline之间的距离,像“y”会有一部分在baseline和descent之间,而音标要放在ascent和top之间。leading是2行之间的距离,一般都是0不用管。

TextView的includeFontPadding作用是上下多留一些空间,如果想要textview的宽度小一点,可以把他设置为false。

以下是官方解释

Leaveenough room for ascenders and descenders instead of using the font ascent anddescent strictly. (Normally true).

TextView includes extra topand bottom padding to make room for accents that go above the normal ascent anddescent. The default is true


举个例子moduleTextView

xml代码 

<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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="click me" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:background="#f7f7f7">

        <TextView
            android:id="@+id/first"
            android:layout_width="50dp"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:background="#7777ff"
            android:text="第一个"
            android:textSize="13sp" />

        <TextView
            android:id="@+id/second"
            android:layout_width="50dp"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_toRightOf="@id/first"
            android:background="#00ff00"

            android:includeFontPadding="false"
            android:text="第二个hj"
            android:textSize="13sp" />


        <TextView
            android:id="@+id/third"
            android:layout_width="50dp"
            android:layout_height="13dp"
            android:layout_alignParentBottom="true"
            android:layout_toRightOf="@id/second"
            android:background="#0000ff"
            android:text="第三个"
            android:textSize="13sp" />

    </RelativeLayout>

</LinearLayout>


我的手机是xxdpi(1dp=3px),这里firstsize52px,second46px,third39pxincludeFontPadding为true的时候,上下padding是9,7,改为false之后上下padding为3,6,可见主要是上边padding小掉了。

 

 

 结论

1、对textview的高度要求或者界面间距要求高的时候,尽量使用includeFontPadding=false不要让textview使用较多padding,

2、textview的baseline和bottom之间大约有2个dp的距离,比如视觉说文字下方10dp处放个图片,那么我应该在文字下方8dp处放图片才符合他的要求。

 drawable press

textview内部可以有drawable,比如 android:drawableLeft="@drawable/open"
但是press的时候,drawable没有按下效果,得加一个 android:focusableInTouchMode="true"才可以,默认focusableInTouchMode是false的

模拟TextView按下效果

继承TextView,可以实现TextView的按下效果,代码如下,其实TextView本身也是这么实现的,用的setPressed方法
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            setPressed(true);
            return true;
        } else if (event.getAction() == MotionEvent.ACTION_UP) {
            setPressed(false);
        }

        return super.onTouchEvent(event);
    }

    /**
     * {@link android.view.View#setPressed}
     * @param b
     */
    private void setCustomPressed(boolean b) {
        setBackgroundColor(b ? Color.GRAY : Color.WHITE);
    }

setText与requestLayout

是否setText一定会触发requestLayout,不一定,看TextView的宽度,如果宽度为wrap_content,那么必定触发,不管你实际text变化了没。但是如果width是其他的话,那就不一定了,如果text未发生变化是不会触发requestLayout的

参考资料

http://mikewang.blog.51cto.com/3826268/871765

http://qiaoweishu.iteye.com/blog/780526

http://www.cnblogs.com/tianzhijiexian/p/4297664.html

http://blog.youkuaiyun.com/carrey1989/article/details/10399727

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值