关于手机设置中,显示和字体大小的变更对视图展示效果的影响

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/anhenzhufeng/article/details/85328328

在手机中的设置功能中,一般会有显示和字体大小调节的选项:

其中字体大小调节的是文字的大小,比如说控件TextView中的文字大小,一般我们在设置textview文字大小的时候,单位一般会使用sp(跟密度和用户偏好有关),布局宽高一般使用dp(密度相关)。官方这样定义:

sp:
Scale-independent Pixels – This is like the dp unit, but it is also scaled by the user’s font size preference. It is recommend you use this unit when specifying font sizes, so they will be adjusted for both the screen density and the user’s preference.

dp:
Density-independent Pixels - An abstract unit that is based on the physical density of the screen. These units are relative to a 160 dpi (dots per inch) screen, on which 1dp is roughly equal to 1px. When running on a higher density screen, the number of pixels used to draw 1dp is scaled up by a factor appropriate for the screen's dpi. Likewise, when on a lower density screen, the number of pixels used for 1dp is scaled down. The ratio of dp-to-pixel will change with the screen density, but not necessarily in direct proportion. Using dp units (instead of px units) is a simple solution to making the view dimensions in your layout resize properly for different screen densities. In other words, it provides consistency for the real-world sizes of your UI elements across different devices.

sp 中文解说:
尺度独立的像素类似于dp单位,但是受用户偏好设置(就是系统字体大小)。推荐在使用字体设置的时候使用该单位,因此sp将根据屏幕密度和用户偏好设置。

dp 中文解说:
由于dp的太长了 我也不多说 ,相信大家都懂dp是什么鬼,这个dp不是重点。

总的来说就是 sp 会受到偏好设置影响,而dp则根据屏幕密度定。

例如,我们默认显示大小和字体大小的情况下是这样的,其中三个并排的图片的布局是均分整个父控件也就是屏幕的宽度,下面文字和图片,文字控件的宽度使用layout_weight属性充满除右边图片控件所占满的父控件的位置,具体布局如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".FontSizeActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <ImageView
            android:layout_width="0dp"
            android:layout_height="100dp"
            android:layout_weight="1"
            android:scaleType="centerCrop"
            android:src="@drawable/hubei"/>
        <ImageView
            android:layout_width="0dp"
            android:layout_height="100dp"
            android:layout_weight="1"
            android:scaleType="centerCrop"
            android:layout_marginStart="10dp"
            android:src="@drawable/dongfang"/>
        <ImageView
            android:layout_width="0dp"
            android:layout_height="100dp"
            android:layout_weight="1"
            android:scaleType="centerCrop"
            android:layout_marginStart="10dp"
            android:src="@drawable/jiangxi"/>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:orientation="horizontal">
        <TextView
            android:id="@+id/display"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="ddsdsdfasdfsdfsdfasdffsdddddddddddddddddddddddsdfsdfdfdasf"
            android:textSize="12sp"/>
        <ImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:src="@drawable/shenzhen"/>
    </LinearLayout>
</LinearLayout>

代码获取屏幕分辨率信息是这样的:

TextView dtv = (TextView) findViewById(R.id.display);
        DisplayMetrics display = getResources().getDisplayMetrics();
        dtv.setText("dpi:" + display.densityDpi + ", density:" + display.density + ", scale:" + display.scaledDensity
        + "\n height:" + display.heightPixels + ", width:" + display.widthPixels);

显示了四个重要的属性:

densityDpi:Dots Per Inch的缩写, 每英寸点数,即每英寸包含像素个数,比如320:表示每英寸上有320个像素点

density:屏幕密度,比如densityDpi=320,那density=320/160最终是2

scaledDensity:屏幕密度上的缩放(字体显示使用)

heightPixels,widthPixecls:屏幕的像素

我们在布局中使用的单位dp和屏幕像素px的换算关系就是:px = dp * (dpi / 160), 这里的dpi就是densityDpi

下图是上面布局后的显示

这里文字显示的就是默认情况下的文字大小。

显示大小不变,字体大小切换为小号看下效果:

区别不是很大,dpi,density和分辨率都没有变化,只有scale变了。我们在看下设置超大字体的情况下:

同样的只有scale变了,对应的文字的大小也变了,但是布局文件的位置和大小都没有变化。

单就字体大小的变化还是比较好适配的,只要控件预留足够的高度和宽度应该就能满足需求。

因为改变字体大小并不会改变dpi的值,所以也就无从使用layout-hdpi或者value-w320dp这种资源来适配。

接下来文字大小保持默认,改变一下显示大小为小:

再改变为大看下:

dpi变了,布局随之变大变小。这里的布局大小,主要在文字右边的单张图片中,很明显的变大变小。

而上面三张图片的宽度几乎没什么变更,反倒是高度有随之变化,已经中间的间隔有变化。原因就是,在布局中,图片的高度是设置了确定的100dp,而两张图的间隔也是设置了固定的10dp,那么在dpi变化的过程中,实际的间隔和高度就会变化。而宽度变化为什么不明显呢,是因为我设置了每个imageview在父布局中的权重都是layout_weight=1,三个iamgeview平分父布局的空间,也就是屏幕有多大就三个平分,虽然我们改变了显示大小,但是实际上屏幕的大小是没变的,所以三个控件的宽度就没什么太大的变化,只所以稍微有点变化,那是因为在三个控件中间增加了margin,margin的值为根据dpi来重新计算,为了更好的说明平分,我把margin去掉了,看下:

可以看到,去掉了中间的间隔,无论显示大小如何,三个图片的宽度都是一样的,只有高度在变化。

在资讯流中,一般会有三张图片的资讯和单张图片的资讯。类似上面的布局,而单张图片的宽高应该要和三张图片中的每张图片的宽高一致才美观。

之前再我的项目中,为了方便三张图片能正常均分父布局,采用了权重的方式,这样在默认显示模式下当然不会出现问题

显示模式变小后就不太美观了:

为了适配dpi的变化,我们应该在layout中分别定义不同dpi下的dp值,或者在value中定义不同dpi下的dimension值

猜你喜欢

转载自blog.csdn.net/anhenzhufeng/article/details/85328328
今日推荐