129

我知道,它已经讨论了 1000 次,但我无法针对不同的屏幕尺寸调整文本大小。我尝试在我的自定义样式中使用“sp”作为尺寸单位:

<style name="CustumButtonStyle" parent="@android:style/Widget.Button">
    ...
    <item name="android:textSize">30sp</item>
    ...
</style>

在 2.7 QVGA 中看起来不错:

2.7QVGA 30sp

但在 7in WSVGA 中,它看起来像这样:

7英寸 WSVGA 30sp

我尝试同时使用“sp”和“dp”,结果相同。

您能否解释一下如何使这些按钮在任何屏幕上看起来都一样?

完整的自定义按钮样式

<style name="CustumButtonStyle" parent="@android:style/Widget.Button">
    <item name="android:background">@drawable/custom_button</item>
    <item name="android:layout_width">fill_parent</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:layout_margin">3dp</item>
    <item name="android:textColor">#ffffff</item>
    <item name="android:gravity">center</item>
    <item name="android:textSize">30sp</item>
    <item name="android:textStyle">bold</item>
    <item name="android:shadowColor">#000000</item>
    <item name="android:shadowDx">1</item>
    <item name="android:shadowDy">1</item>
    <item name="android:shadowRadius">2</item>
</style>

在我的应用程序主题中,我有

<item name="android:buttonStyle">@style/CustumButtonStyle</item>

还有我的布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/RelativeLayout1"
android:layout_width="fill_parent"
android:background="@drawable/grid"
android:gravity="center"
android:orientation="vertical" android:layout_height="fill_parent">

<Button
    android:id="@+id/buttonContinue"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layout_gravity="center"
    android:gravity="center"
    android:text="@string/continue_game" android:layout_marginTop="3dp" android:layout_marginBottom="3dp"/>



<Button
    android:id="@+id/buttonNewGame"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/buttonContinue"
    android:layout_alignRight="@+id/buttonContinue"
    android:layout_below="@+id/buttonContinue"
    android:layout_gravity="center"
    android:gravity="center"
    android:text="@string/new_game" android:layout_marginTop="3dp" android:layout_marginBottom="3dp"/>



<Button
    android:id="@+id/ButtonAbout"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/buttonNewGame"
    android:layout_alignRight="@+id/buttonNewGame"
    android:layout_below="@+id/buttonNewGame"
    android:layout_gravity="center"
    android:gravity="center"
    android:text="@string/about" android:layout_marginTop="3dp" android:layout_marginBottom="3dp"/>

4

12 回答 12

170

@forcelain 我认为您需要检查此Google IO Pdf for Design。在该 pdf 中转到第 77 页,您将在其中找到如何建议将 dimens.xml 用于不同的 android 设备,例如,请参见下面的结构:

res/values/dimens.xml

res/values-small/dimens.xml

res/values-normal/dimens.xml

res/values-large/dimens.xml

res/values-xlarge/dimens.xml

例如,您在值中使用了以下 dimens.xml。

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <dimen name="text_size">18sp</dimen>
</resources>

在其他值文件夹中,您需要更改文本大小的值。

注意:正如@espinchi 所指出的,自 Android 3.2 以来,small、normal、large 和 xlarge 已被弃用,取而代之的是:

为 Android 3.2 声明平板电脑布局

对于运行 Android 3.0 的第一代平板电脑,声明平板电脑布局的正确方法是将它们放在具有 xlarge 配置限定符的目录中(例如 res/layout-xlarge/)。为了适应其他类型的平板电脑和屏幕尺寸(尤其是 7 英寸平板电脑),Android 3.2 引入了一种新方法来为更离散的屏幕尺寸指定资源。这项新技术基于您的布局所需的空间量(例如600dp 的宽度),而不是试图使您的布局适合通用尺寸组(例如大或 xlarge)。

使用通用尺寸组时设计 7 英寸平板电脑的原因是 7 英寸平板电脑在技术上与 5 英寸手机属于同一组(大组)。虽然这两种设备的尺寸看起来彼此接近, 应用程序 UI 的空间量显着不同,用户交互的风格也是如此。因此,7" 和 5" 屏幕不应该总是使用相同的布局。为了让您可以为它们提供不同的布局两种屏幕,Android 现在允许您根据应用程序布局实际可用的宽度和/或高度(以 dp 单位指定)来指定布局资源。

例如,在您设计好要用于平板式设备的布局后,您可能会确定当屏幕宽度小于 600dp 时布局会停止正常工作。因此,此阈值成为您的平板电脑布局所需的最小尺寸。因此,您现在可以指定仅当应用程序的 UI 至少有 600dp 的宽度可用时才应使用这些布局资源。

您应该选择一个宽度并将其设计为您的最小尺寸,或者在完成后测试您的布局支持的最小宽度。

注意:请记住,与这些新尺寸 API 一起使用的所有数字都是与密度无关的像素 (dp) 值,并且您的布局尺寸也应始终使用 dp 单位定义,因为您关心的是系统后可用的屏幕空间量考虑屏幕密度(而不是使用原始像素分辨率)。有关与密度无关的像素的更多信息,请阅读本文档前面的术语和概念。使用新的大小限定符

表 2 总结了您可以根据布局可用空间指定的不同资源配置。与传统的屏幕尺寸组(小、正常、大和超大)。

注意:您使用这些限定符指定的尺寸不是实际的屏幕尺寸。相反,尺寸是针对活动窗口可用的宽度或高度(以 dp 为单位)。Android 系统可能会将部分屏幕用于系统 UI(例如屏幕底部的系统栏或顶部的状态栏),因此部分屏幕可能无法用于您的布局。因此,您声明的尺寸应该专门针对您的活动所需的尺寸——系统在声明它为您的布局提供多少空间时会考虑系统 UI 使用的任何空间。还要注意,尽管您的布局没有声明它,但操作栏被视为应用程序窗口空间的一部分,因此它减少了可用于布局的空间,您必须在设计中考虑到它。

表 2. 屏幕尺寸的新配置限定符(在 Android 3.2 中引入)。屏幕配置 限定符值 描述 minimumWidth swdp

示例:sw600dp sw720dp

屏幕的基本尺寸,由可用屏幕区域的最短尺寸表示。具体来说,设备的 minimumWidth 是屏幕可用高度和宽度中最短的(您也可以将其视为屏幕的“最小可能宽度”)。您可以使用此限定符来确保,无论屏幕的当前方向如何,您的应用程序的 UI 至少有 dps 的宽度可用。

例如,如果您的布局要求其屏幕区域的最小尺寸始终至少为 600 dp,那么您可以使用此限定符来创建布局资源 res/layout-sw600dp/。只有当可用屏幕的最小尺寸至少为 600dp 时,系统才会使用这些资源,而不管 600dp 边是用户感知的高度还是宽度。minimumWidth 是设备的固定屏幕尺寸特性;当屏幕的方向改变时,设备的 minimumWidth 不会改变。

设备的 minimumWidth 考虑了屏幕装饰和系统 UI。例如,如果设备在屏幕上有一些持久的 UI 元素,这些元素占据了沿着最小宽度轴的空间,系统会声明最小宽度小于实际屏幕尺寸,因为这些屏幕像素不适用于您的 UI。

这是通用屏幕尺寸限定符(small、normal、large、xlarge)的替代方案,它允许您为 UI 可用的有效尺寸定义一个离散数字。使用 minimumWidth 来确定一般屏幕尺寸很有用,因为宽度通常是设计布局的驱动因素。UI 通常会垂直滚动,但对水平所需的最小空间有相当严格的限制。可用宽度也是决定是为手机使用单窗格布局还是为平板电脑使用多窗格布局的关键因素。因此,您可能最关心每个设备上的最小可能宽度。可用屏幕宽度 wdp

示例: w720dp w1024dp

指定应使用资源的最小可用宽度(以 dp 为单位)——由值定义。当屏幕的方向在横向和纵向之间切换时,系统对应的宽度值会发生变化,以反映 UI 可用的当前实际宽度。

这对于确定是否使用多窗格布局通常很有用,因为即使在平板设备上,您通常也不希望纵向的多窗格布局与横向的多窗格布局相同。因此,您可以使用它来指定布局所需的最小宽度,而不是同时使用屏幕尺寸和方向限定符。可用屏幕高度 hdp

示例:h720dp h1024dp 等。

指定应使用资源的最小屏幕高度(以 dp 为单位)——由值定义。当屏幕的方向在横向和纵向之间切换时,系统对应的高度值会发生变化,以反映您的 UI 可用的当前实际高度。

使用它来定义布局所需的高度非常有用,就像 wdp 用于定义所需的宽度一样,而不是同时使用屏幕尺寸和方向限定符。但是,大多数应用程序不需要此限定符,因为 UI 经常垂直滚动,因此在可用高度方面更加灵活,而宽度则更加严格。

虽然使用这些限定符似乎比使用屏幕尺寸组更复杂,但一旦确定了 UI 的要求,它实际上应该更简单。当您设计您的 UI 时,您可能关心的主要事情是您的应用程序在手机式 UI 和使用多个窗格的平板电脑式 UI 之间切换的实际大小。这个切换的确切点将取决于您的特定设计——也许您的平板电脑布局需要 720dp 的宽度,也许 600dp 就足够了,或者 480dp,或者介于这些之间的某个数字。使用表 2 中的这些限定符,您可以控制布局更改的精确大小。

有关这些大小配置限定符的更多讨论,请参阅提供资源文档。配置示例

为了帮助您针对不同类型的设备进行一些设计,以下是典型屏幕宽度的一些数字:

320dp: a typical phone screen (240x320 ldpi, 320x480 mdpi, 480x800 hdpi, etc).
480dp: a tweener tablet like the Streak (480x800 mdpi).
600dp: a 7” tablet (600x1024 mdpi).
720dp: a 10” tablet (720x1280 mdpi, 800x1280 mdpi, etc).

使用表 2 中的尺寸限定符,您的应用程序可以使用您想要的任何宽度和/或高度数字在手机和平​​板电脑的不同布局资源之间切换。例如,如果 600dp 是您的平板电脑布局支持的最小可用宽度,您可以提供以下两组布局:

res/layout/main_activity.xml # 对于手机 res/layout-sw600dp/main_activity.xml # 对于平板电脑

在这种情况下,可用屏幕空间的最小宽度必须为 600dp,才能应用平板电脑布局。

对于您希望进一步自定义 UI 以区分尺寸(例如 7 英寸和 10 英寸平板电脑)的其他情况,您可以定义其他最小宽度布局:

res/layout/main_activity.xml # 适用于手机(小于 600dp 可用宽度) res/layout-sw600dp/main_activity.xml # 适用于 7 英寸平板电脑(600dp 宽和更大) res/layout-sw720dp/main_activity.xml

适用于 10 英寸平板电脑(720dp 宽和更大)

请注意,前两组示例资源使用“最小宽度”限定符 swdp,它指定屏幕两侧中最小的一侧,而与设备的当前方向无关。因此,使用 swdp 是一种通过忽略屏幕方向来指定可用于布局的整体屏幕尺寸的简单方法。

但是,在某些情况下,对您的布局可能很重要的是当前可用的宽度或高度。例如,如果您有两个并排的片段的双窗格布局,您可能希望在屏幕提供至少 600dp 的宽度时使用它,无论设备是横向还是纵向。在这种情况下,您的资源可能如下所示:

res/layout/main_activity.xml # 用于手机(小于 600dp 可用宽度) res/layout-w600dp/main_activity.xml # 多窗格(任何具有 600dp 可用宽度或更大的屏幕)

请注意,第二组使用“可用宽度”限定符 wdp。这样,一台设备实际上可能会使用两种布局,具体取决于屏幕的方向(如果可用宽度在一个方向上至少为 600dp,而在另一个方向上小于 600dp)。

如果您担心可用高度,那么您可以使用 hdp 限定符来做同样的事情。或者,如果您需要非常具体,甚至可以组合 wdp 和 hdp 限定符。

于 2012-03-27T05:07:02.560 回答
24

我认为在此线程上回复为时已晚。但我想分享我的想法或方法来解决不同分辨率设备上的文本大小问题。许多 android 开发者网站建议我们必须使用sp单位作为文本大小,它将处理不同分辨率设备的文本大小。但我总是无法得到想要的结果。因此,我从最近的 4-5 个项目中找到了一个我正在使用的解决方案,并且工作正常。根据我的建议,您必须为每个分辨率设备放置文本大小,这有点繁琐,但它会满足您的要求。每个开发者都必须听听像4:6:8:12 (h:xh:xxh:xxxh)这样的比例。现在在您的项目res文件夹中,您必须使用 dimens 文件创建 4 个文件夹,例如

  1. res/values-hdpi/dimens.xml
  2. res/values-xhdpi/dimens.xml
  3. res/values-xxhdpi/dimens.xml
  4. res/values-xxxhdpi/dimens.xml

现在在 dimens.xml 文件中,您必须放置文本大小。我正在向您展示values-hdpi 的代码,同样您必须为其他分辨率值/dimens.xml 文件放置代码。

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <dimen name="text_size">4px</dimen>
</resources>

对于其他分辨率,它类似于xhdpi:6px、xxhdpi:8px、xxxhdpi:12px。这是用我上面写的比率(3:4:6:8:12)计算的。让我们讨论具有上述比例的其他文本大小示例。如果您想在 hdpi 中采用 12px 的文本大小,那么在其他分辨率下将是

  1. 高清:12像素
  2. xhdpi : 18 像素
  3. xxhdpi : 24 像素
  4. xxxhdpi : 36px

这是为所有分辨率实现所需文本大小的简单解决方案。我在这里不考虑values-mdpi分辨率设备。如果有人想为此分辨率包含文本大小,那么 ration 就像3:4:6:8:12。如有任何疑问,请告诉我。希望它会帮助你的人。

于 2017-09-11T16:13:07.620 回答
15

有时,最好只有三个选项

 style="@android:style/TextAppearance.Small"

使用 small 和 large 来区分正常的屏幕尺寸。

<TextView
            android:id="@+id/TextViewTopBarTitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            style="@android:style/TextAppearance.Small"/>

对于正常情况,您不必指定任何内容。

<TextView
            android:id="@+id/TextViewTopBarTitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

使用它,您可以避免测试和指定不同屏幕尺寸的尺寸。

于 2015-01-21T09:06:31.103 回答
10

我按尺寸做了同样的事情并绘制了类似的东西(使用dp但仅用于文本和drawText())

XML:

   <dimen name="text_size">30sp</dimen>

代码:

   Paint p =new Paint();
       p.setTextSize(getResources().getDimension(R.dimen.text_Size));
于 2012-03-26T20:27:31.273 回答
9

每个人都可以使用下面提到的 android 库,这是使文本大小与几乎所有设备屏幕兼容的最简单方法。它实际上是在新的 android 屏幕尺寸配置限定符(在 Android 3.2 中引入)SmallestWidth swdp 的基础上开发的。

https://github.com/intuit/sdp

于 2018-05-22T01:09:20.573 回答
2

我知道已经很晚了,但这可能会对某人有所帮助......

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:autoSizeTextType="uniform"
        android:gravity="center_horizontal|bottom"
        android:text="Your text goes here!"
        android:layout_centerInParent="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHeight_percent="0.05"
        app:layout_constraintHorizontal_bias="0.50"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.50"
        app:layout_constraintWidth_percent="0.50" />
</androidx.constraintlayout.widget.ConstraintLayout>

另外,如果您想调整文本大小,请尝试更改

app:layout_constraintWidth_percent="0.50" 
app:layout_constraintHeight_percent="0.05"

就这样。

于 2020-12-08T16:54:00.630 回答
1

统一所有屏幕以显示相同的元素大小,包括字体大小: - 在一个屏幕大小上设计 UI,使用您在设计期间认为合适的任何大小,即 TextView 字体大小为 14dp,默认屏幕大小为 4'6 英寸。

  • 以编程方式计算其他手机的物理屏幕尺寸,即 5'2 英寸的其他手机/屏幕。

  • 使用公式计算 2 个屏幕之间的百分比差异。即 4'6 和 5'2 之间的百分比差异是多少。

  • 根据上面的公式计算2个TextView之间的像素差。

  • 获取 TextView 字体大小的实际大小(以像素为单位)并将像素差异(您之前计算的)应用于默认字体大小。

通过这种方式,您可以将动态纵横比应用于所有屏幕尺寸,效果非常好。您将在每个屏幕上拥有相同的布局和大小。

一开始可能有点棘手,但一旦你弄清楚了公式,就完全达到了目标。使用这种方法,您无需为了适应不同的屏幕尺寸而进行多种布局。

于 2018-04-20T20:30:38.183 回答
1

如果您有 API 26,那么您可以考虑使用autoSizeTextType

<Button
  app:autoSizeTextType="uniform" />

默认设置允许 TextView 的自动调整大小在水平轴和垂直轴上统一缩放。

https://developer.android.com/guide/topics/ui/look-and-feel/autosizing-textview

于 2019-08-07T10:40:05.357 回答
0

我认为您可以通过为每个屏幕尺寸添加多个布局资源来存档,例如:

res/layout/my_layout.xml             // layout for normal screen size ("default")
res/layout-small/my_layout.xml       // layout for small screen size with small text
res/layout-large/my_layout.xml       // layout for large screen size with larger text
res/layout-xlarge/my_layout.xml      // layout for extra large screen size with even larger text
res/layout-xlarge-land/my_layout.xml // layout for extra large in landscape orientation

参考: 1. http://developer.android.com/guide/practices/screens_support.html

于 2012-03-27T04:40:22.060 回答
0

您还可以使用weightSumlayout_weight属性来调整您的不同屏幕。

为此,您必须制作android:layout_width= 0dp 和android:layout_width=(无论您想要什么);

于 2019-07-08T07:49:47.163 回答
-1

正如@espinchi 从 3.2(API 级别 13)中提到的那样,大小组已被弃用。 屏幕尺寸范围是未来最受欢迎的方法。

于 2015-08-16T12:31:04.760 回答
-3

不要对尺寸进行硬编码。

对于灵活性和新的屏幕分辨率 - 最佳做法是将虚拟 TextView 放入布局中以获取 textSize:

<TextView
        android:id="@+id/dummyTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="gone"
        android:text="TextView" />

例如在您的代码中:

TextView testTextView = (TextView) rootView.findViewById(R.id.dummyTextView);
float textSize = testTextView.getTextSize();

保留textSize作为参考,您可以添加常数或百分比大小(通过计算)。

于 2013-08-06T10:19:20.733 回答