神奇的TextView

来源:互联网 发布:淘宝销售冠军苏亚 编辑:程序博客网 时间:2024/06/08 20:15

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.csdn.net/carrey1989/article/details/10399727

 

0 0
原创粉丝点击