[英]android:scaleType=“center” doesn't do what I think it should: how does dp vs px work?
我正在嘗試完成必須可以想象的最簡單的事情。 我有菜單的背景圖片。 我希望在屏幕上顯示盡可能多的圖像,每個像素一個像素,並且沒有縮放比例。
據我所知,這正是scaleType =“ center”應該完成的工作。 不幸的是,無論我做什么,它都拒絕做我想要的事情,而只顯示圖像的一小部分。
為了用實數闡明,我在sw320dp drawables文件夾中有一個720x1280px的背景圖片,由我的sw320dp布局調用。 對於介於320x480px和720x1280px之間的任何屏幕尺寸,他們應該調用該布局並顯示該背景圖像的一部分。 因此,480x800px的Nexus One應該顯示圖像的480x800px的一部分。 為此,我有:
<ImageView
android:id="@+id/menuBackground"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="center"
app:srcCompat="@drawable/menubackground_w720" />
不幸的是,它不起作用。 取而代之的是,它僅顯示圖像的一小部分,大約等於320x480px,長寬比為正負。
經過很多的咒罵和扯掉頭發之后,我將可能性縮小為三種合理的理論:
假設第三個選項(即使為true)是“無法解決的”,那么如果有人可以告訴我這是一個還是兩個選項,並將我鏈接到適當的最新資源,我將不勝感激。 感謝您的協助!
我希望在屏幕上顯示盡可能多的圖像,每個像素一個像素,並且沒有縮放比例。
將圖像移到res/drawable-nodpi/
目錄。
經過很多的咒罵和扯掉頭發之后,我將可能性縮小為三種合理的理論:
- 我正在以一種愚蠢的方式做着非常,非常,非常簡單的錯誤。
- 我從根本上不了解dp的工作原理以及可擴展的布局。
- 這個世界是一場奇幻的,非理性的洛夫克拉夫特式的噩夢,其中沒有任何意義,我注定永遠在無望的瘋狂圈子中追逐自己的尾巴。
我認為#2可能是最接近真相的。 沒關系; 情況很復雜。
讓我們開始考慮以下圖像:
我在這里對其進行了調整,以使其在回答中不會占用大量空間,但是在我的計算機上為1000x1000像素。 每個黑色或白色正方形均為100x100像素。 這將使我們很容易推斷出應用程序中發生了什么。
接下來,我制作了一個非常簡單的應用程序:它只顯示200x200 dp的ImageView,而沒有其他顯示。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#eee">
<ImageView
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center"
android:scaleType="center"
android:src="@drawable/checkerboard"/>
</FrameLayout>
我將checkerboard.png
放入res/drawable/
目錄,然后運行該應用程序。 我的模擬器是Nexus 5X,(根據本網站 )其屏幕分辨率為1080x1920像素。 這是我看到的:
嗯 這導致了一些問題:
為什么200 dp寬的ImageView占據一半的屏幕?
dp單元的明確目的是使視圖在不同設備上的物理尺寸大致相同。 這里的挑戰之一是不同的設備可能具有不同的顯示密度 ; 一台手機可能具有適合於物理英寸的320像素的高分辨率顯示屏,而另一部手機可能具有僅適合於物理英寸的120像素的高分辨率顯示屏。
Android的基准是160 dpi。 在此密度下,1 dp == 1 px。 如果您的設備具有更高的密度,則1 dp等於大於1 px。 Nexus 5X的密度約為423 dpi,因此在我的布局中每1 dp使用約2.6像素。 因此,在此特定仿真器上,200x200 dp表示大約520x520像素。
但是,為什么我的.png只顯示200x200像素的圖像?
在不同設備上使事物具有相同物理尺寸的另一個挑戰是如何處理圖像。 我們僅向系統提供了一個checkerboard.png
文件,但我們知道ImageView在不同設備上將具有不同的像素尺寸。 剩下兩個選擇:
系統無法執行縮放。 如果可以,那么我在Nexus 5X上會看到大約520x520像素的圖像,但是仍然在運行Nexus One(252 dpi)的人只能看到大約315x315像素的圖像。 整個ImageView的物理尺寸大約相同,但是我們兩個人會看到完全不同的圖像內容。
或者,系統可以按比例放大圖像。 現在,它執行與圖像數據本身上dp到px相同的縮放比例。 完成此操作后,Nexus 5X和Nexus One都會看到200x200像素的圖像數據。 但是,在Nexus 5X上,縮放偽影會變得更糟,因為系統必須將圖像放大得更多才能滿足更高的顯示密度。
我該怎么解決?
這取決於您的最終目標。 如果您只想提供一個.png文件,並且希望系統不按比例放大文件(即,無論顯示密度如何,任何設備上的像素都應為1px,以顯示圖像的1px),則應移動。 png到res/drawable-nodpi/
目錄 。
https://developer.android.com/guide/topics/resources/providing-resources.html
nodpi
:可用於您不想縮放以匹配設備密度的位圖資源。
如果對示例應用程序執行此操作,則在運行它時會看到以下內容:
確實,我們看到了大約520x520像素的圖像。
另一方面,如果您希望每個用戶看到相同的物理圖像,但又希望避免縮放偽影,則應提供圖像文件的多種分辨率 。
考慮一下從Google的Material Icon存儲庫下載圖標的.png版本時會發生什么情況。 假設我們采用ic_face.png
。 您將獲得一個如下所示的目錄結構:
android/
drawable-mdpi/
ic_face_black_24dp.png (24x24 pixels)
drawable-hdpi/
ic_face_black_24dp.png (36x36 pixels)
drawable-xhdpi/
ic_face_black_24dp.png (48x48 pixels)
drawable-xxhdpi/
ic_face_black_24dp.png (72x72 pixels)
drawable-xxxhdpi/
ic_face_black_24dp.png (96x96 pixels)
這是在以不同的分辨率提供相同圖像的不同版本。 具有高顯示密度的設備將拍攝與其密度最接近的圖像,然后僅將其縮放到很小的數量。 這大大減少了縮放偽影。
https://developer.android.com/guide/topics/resources/providing-resources.html
https://developer.android.com/guide/practices/screens_support.html
嘗試使用
android:scaleType="centerCrop"
我在imageviews上遇到了同樣的問題,這每次都解決了我的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.