【问题标题】:Android Screen-size and Screen-density Image SelectionAndroid 屏幕尺寸和屏幕密度图像选择
【发布时间】:2014-05-14 20:06:45
【问题描述】:

我在尝试在不同尺寸的设备上使用多个水平图像时遇到问题。我有 7 个独立的 Ratingbars,每个都使用不同的自定义图像。我已经缩放了所有图像并将它们放入各自的 dpi 可绘制文件夹中。我遇到的问题是,在 xlarge mdpi 屏幕(下图左上角)上,它们非常适合,但是当我在较小的屏幕上查看它们时,整个 7 个评分栏太宽,无法容纳在范围内设备,如下图:

我已按照以下答案中的说明对图像进行了正确的缩放(基于 mdpi 的原始基本尺寸):https://stackoverflow.com/a/11581786/1634369

ldpi | mdpi | tvdpi | hdpi | xhdpi | xxhdpi | xxxhdpi
0.75 | 1    | 1.33  | 1.5  | 2     | 3      | 4

根据上面的缩放比例,以下是我所有的可绘制文件夹,显示了各自 dpi 文件夹中每个图像的尺寸(均基于 mdpi 比率):

然后为了显示每个评分栏,我为每个评分栏设置了一个选择器,它将使用默认的灰色图像和基于评分值的彩色图像。下面显示了我使用布局显示每个 Ratingbars 的代码。注意:我基于基本 mdpi 值的宽度和高度。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <RatingBar            
        android:numStars="1"
        android:rating="1"
        android:stepSize="0.01"
        android:isIndicator="true"
        android:layout_width="75dp"
        android:layout_height="77dp"
        android:layout_gravity="bottom"
        android:gravity="bottom"                                                          
        android:progressDrawable="@drawable/selector_a" />

    <RatingBar            
        android:numStars="1"
        android:rating="0.5"
        android:stepSize="0.01"
        android:isIndicator="true"
        android:layout_width="73dp"
        android:layout_height="114dp"
        android:layout_gravity="bottom"
        android:gravity="bottom"                                                          
        android:progressDrawable="@drawable/selector_b" />

    <RatingBar            
        android:numStars="1"
        android:rating="0.5"
        android:stepSize="0.01"
        android:isIndicator="true"
        android:layout_width="63dp"
        android:layout_height="132dp"
        android:layout_gravity="bottom"
        android:gravity="bottom"                                                          
        android:progressDrawable="@drawable/selector_c" />

    <RatingBar            
        android:numStars="1"
        android:rating="0.5"
        android:stepSize="0.01"
        android:isIndicator="true"
        android:layout_width="79dp"
        android:layout_height="145dp"
        android:layout_gravity="bottom"
        android:gravity="bottom"                                                          
        android:progressDrawable="@drawable/selector_d" />

    <RatingBar            
        android:numStars="1"
        android:rating="0.5"
        android:stepSize="0.01"
        android:isIndicator="true"
        android:layout_width="79dp"
        android:layout_height="161dp"
        android:layout_gravity="bottom"
        android:gravity="bottom"                                                          
        android:progressDrawable="@drawable/selector_e" />

    <RatingBar            
        android:numStars="1"
        android:rating="0.5"
        android:stepSize="0.01"
        android:isIndicator="true"
        android:layout_width="108dp"
        android:layout_height="168dp"
        android:layout_gravity="bottom"
        android:gravity="bottom"                                                          
        android:progressDrawable="@drawable/selector_f" />

    <RatingBar            
        android:numStars="1"
        android:rating="0.5"
        android:stepSize="0.01"
        android:isIndicator="true"
        android:layout_width="147dp"
        android:layout_height="189dp"
        android:layout_gravity="bottom"
        android:gravity="bottom"                                                          
        android:progressDrawable="@drawable/selector_g" />

</LinearLayout>

谁能帮助我确保无论评级栏显示在什么屏幕上,无论设备的密度如何,它看起来总是一样的(它在显示在顶部的 10.1 mdpi 屏幕上的样子显示所有不同屏幕的图像左侧?任何帮助将不胜感激。

非常感谢您花时间阅读这个问题。我已将代码放在 Github 上的以下位置:https://github.com/gbayo1/RatingBarScalingIssue.git

【问题讨论】:

  • 真的必须是完全相同的尺寸吗?较小的设备上的评级栏是否更小有关系吗?首先它应该更小,因为您在较小的设备上的空间更少。有没有理由让它在更大的设备上不应该更大?他们有屏幕空间,有理由浪费它吗?我想说的是:不要为您的Views 使用固定大小。请改用wrap_contentmatch_parent。您可以做很多事情来使您的布局与设备一起缩放。如果你告诉我它应该是什么样子,我可以帮助你。
  • 非常感谢您的评论。不,它不必看起来相同,只要它在不同的屏幕上清晰可读即可。它们不必具有相同的大小或占用相同的空间,只要它们看起来合理,这就是我所寻找的。当我尝试包装内容时,评分栏没有正确显示图像,这就是我使用固定尺寸的原因
  • 您希望它是什么样的?例如,我可以向您展示如何在屏幕上平均分配所有 RatingBars
  • 嗯,它应该显示一个进步。所以这是一个有100个关卡的游戏。第一个 RatingBar(在上述情况下为 A)可能代表前 5 个级别。因此,如果您完成第 1 级,您将获得 A 的 20%、第 2 级、A 的 40%,等等...然后第 2 个 RatingBar 可能代表接下来的 10 个级别,第 3 个 Ratingbar,接下来的 22 个级别,等等...所以每个 RatingBar 与其所代表的内容不成正比。一旦他们靠得很近,看起来还不错,用户基本上可以在整个游戏过程中看到并了解他们的进度

标签: android image scaling screen-size ratingbar


【解决方案1】:

您可以使用LinearLayoutlayout_weight 在屏幕上平均分配Views。要使layout_weight 工作,您必须将layout_width 设置为0dp。这是正常的,不要让自己对此感到困惑。如果您想垂直平均分布,则必须将layout_height 设置为0dplayout_weight 告诉LinearLayout View 应该与其他的相比有多大。在您的情况下,我们希望所有Views 均等分布,因此它们都需要具有相同的宽度。这就是为什么我们将所有Views 分配给相同的layout_weight - 1 的原因。您可以使用layout_weight 做更多事情,例如,如果您有两个视图,并且您希望左侧视图占据屏幕的三分之二,右侧视图占据屏幕的三分之一,您可以分配左侧视图一个layout_weight,共2个,右边一个layout_weight,共1个。

我已经相应地修改了你的布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent">


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

        <RatingBar
                android:numStars="1"
                android:rating="1"
                android:stepSize="0.01"
                android:isIndicator="true"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="wrap_content"
                android:progressDrawable="@drawable/selector_a"/>

        <RatingBar
                android:numStars="1"
                android:rating="0.5"
                android:stepSize="0.01"
                android:isIndicator="true"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="wrap_content"
                android:progressDrawable="@drawable/selector_b"/>

        <RatingBar
                android:numStars="1"
                android:rating="0.5"
                android:stepSize="0.01"
                android:isIndicator="true"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="wrap_content"
                android:progressDrawable="@drawable/selector_c"/>

        <RatingBar
                android:numStars="1"
                android:rating="0.5"
                android:stepSize="0.01"
                android:isIndicator="true"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="wrap_content"
                android:progressDrawable="@drawable/selector_d"/>

        <RatingBar
                android:numStars="1"
                android:rating="0.5"
                android:stepSize="0.01"
                android:isIndicator="true"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="wrap_content"
                android:progressDrawable="@drawable/selector_e"/>

        <RatingBar
                android:numStars="1"
                android:rating="0.5"
                android:stepSize="0.01"
                android:isIndicator="true"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="wrap_content"
                android:progressDrawable="@drawable/selector_f"/>

        <RatingBar
                android:numStars="1"
                android:rating="0.5"
                android:stepSize="0.01"
                android:isIndicator="true"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="wrap_content"
                android:progressDrawable="@drawable/selector_g"/>

    </LinearLayout>
</RelativeLayout>

我认为除了Ratingbars 之外,布局中最终还会有其他内容,这就是为什么我已经将所有内容都包装在RelativeLayout 中的原因。由于您的自定义progressDrawable,您可能会在评级栏的高度方面遇到一些问题,因为我将layout_height 更改为wrap_content。如果它不起作用或者您希望它们具有不同的高度,您可以为RatingBars 设置固定高度,但保持layout_width 不变。

附带说明:您在原始布局中拥有的所有layout_gravitygravity 元素基本上是无用的。要将所有RatingBars 与底部对齐,您只需要LinearLayout 本身上的android:gravity="bottom"

【讨论】:

  • 谢谢@XaverKapeller。在实现您的代码时,尽管它均匀地分布了评分栏,但它并没有显示完整的评分栏,这是最初的问题。使用您的代码时,所有评分栏图像都在底部和右侧被裁剪。现在显示每个评分栏的左上角,但缺少所有评分栏的下半部分和右半部分(评分栏图像越大,我丢失的图像右侧和底部越多)。
  • 这意味着progressDrawables 比实际的View 大。似乎RatingBar 在执行onMeasure() 时没有考虑其progressDrawable 的大小。我用默认的RatingBar 对其进行了测试,它运行良好。您可以调整图像或将RatingBar 子类化并修复onMeasure()。但是考虑到您在所有这些上投入了多少时间,我认为创建自定义视图可能更容易。 RatingBar 似乎根本不适合您的目的。
  • 我认为为此创建自定义视图的最简单方法是继承 ImageView 并以编程方式创建一个可绘制的图层列表,其中包含背景和进度可绘制,并在图层列表中使用填充获得进度效果。 ImageView 已经处理了所有 onMeasure() 业务,这将是最复杂的部分。
  • 是的,这就是我面临的问题,我只是无法让代表 RatingBar 的图像正确缩放。我实际上是在考虑您在使用权重和图像方面的建议,然后通过在默认值上填充/覆盖完整图像来计算进度。我会在周末尝试一下,让你知道我过得怎么样。这是我正在开发的应用程序的最后一部分,所以希望我能得到一些工作,否则我只需要使用文本来代替。但是某种评分量表会更具吸引力。感谢您的所有帮助。
  • 你的progressDrawable可能有问题,你能给我看看吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-05
  • 1970-01-01
  • 2012-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多