โหลดค่ามิติจาก res / values ​​/ dimension.xml จากซอร์สโค้ด


337

ฉันต้องการโหลดค่าตามที่เป็น ฉันมีสองdimension.xmlไฟล์หนึ่งและอีกคนหนึ่งใน/res/values/dimension.xml/res/values-sw360dp/dimension.xml

จากซอร์สโค้ดฉันต้องการทำอะไรเช่น

getResources().getDimension(R.dimen.tutorial_cross_marginTop);

สิ่งนี้ใช้ได้ แต่ค่าที่ฉันได้รับนั้นคูณด้วยตัวคูณความหนาแน่นของหน้าจอ (1.5 สำหรับ hdpi, 2.0 สำหรับ xhdpi ฯลฯ )

ฉันก็ลองทำดู

getResources().getString(R.dimen.tutorial_cross_marginTop);

นี้จะทำงานในหลักการ แต่ฉันได้รับสตริงที่ลงท้ายด้วย "จุ่ม" ...


1
ฉันสงสัยว่านี่เป็นข้อผิดพลาดใน Android หรือไม่เนื่องจาก Resources มีวิธีการgetDimensionPixelSize(int id)ที่ระบุว่าจะส่งคืนเป็น Pixel ดังนั้นgetDimension(int id)ควรกลับมาเป็น dp (หน่วยพึ่งพาอิสระ) ซึ่งจะพร้อมใช้งานเช่นกับ ViewsetPadding
Paul Verest

คำตอบ:


812

ใน dimens.xml ของฉันฉันมี

<dimen name="test">48dp</dimen>

ในรหัสถ้าฉันทำ

int valueInPixels = (int) getResources().getDimension(R.dimen.test)

สิ่งนี้จะคืน 72 ซึ่งเป็นรัฐเอกสารคูณด้วยความหนาแน่นของโทรศัพท์ปัจจุบัน (48dp x 1.5 ในกรณีของฉัน)

เหมือนกับเอกสารของรัฐ:

ดึงส่วนข้อมูลสำหรับ ID ทรัพยากรเฉพาะ การแปลงหน่วยขึ้นอยู่กับ DisplayMetrics ปัจจุบันที่เชื่อมโยงกับทรัพยากร

ดังนั้นถ้าคุณต้องการค่า dp ที่แน่นอนเหมือนกับใน xml เพียงแค่แบ่งมันด้วยความหนาแน่นของ DisplayMetrics

int dp = (int) (getResources().getDimension(R.dimen.test) / getResources().getDisplayMetrics().density)

dp จะเป็น 48 ตอนนี้


3
ฉันคิดว่าเอกสารไม่ชัดเจนเป็นพิเศษที่นี่ "การแปลงหน่วยขึ้นอยู่กับ DisplayMetrics ปัจจุบันที่เชื่อมโยงกับทรัพยากร" เมื่อทั้งหมดที่พวกเขาต้องการจะพูดก็คือพวกเขาแปลงเป็นพิกเซล
Trilarion

หากคุณกำลังจะยกเลิกการคูณตัวชี้วัดการแสดงผลคุณอาจเพียงกำหนดมิติของคุณใน px <dimen name = "test"> 48px </dimen> getDimension (R.dimen.test) จะกลับมา 48.
Michael Peterson

ไม่ทำงานสำหรับฉัน: stackoverflow.com/questions/55972518/…
อเล็กซ์

@Trilarion พวกเขาไม่เพียงแปลงเป็นพิกเซล พวกเขากำลังบอกว่าdpจะให้ค่าพิกเซลที่ปรับขนาดสัมพันธ์กับมาตราส่วนของวัตถุทรัพยากรที่ใช้ในการเรียกคืน เมื่อคุณได้รับวิธีการต่าง ๆ เพื่อรับทรัพยากรสิ่งนี้จะเกี่ยวข้องมากขึ้น เพื่อความง่ายคุณสามารถคิดว่ามันสัมพันธ์กับขนาดหน้าจอ นอกจากนี้ยังมีspหรือพิกเซลสัมพันธ์กับขนาดข้อความของระบบและpxหรือพิกเซลโดยตรง แต่ละคนแตกต่างกันและมีจุดประสงค์ที่แตกต่างกัน
รถเข็นที่ถูกทิ้งร้าง


17

Resourceชั้นนอกจากนี้ยังมีวิธีการgetDimensionPixelSize ()ซึ่งผมคิดว่าจะพอดีกับความต้องการของคุณ


24
นี่มันผิด! การแปลงตัวชี้วัดจะเกิดขึ้นในgetDimensionPixelSize()กรณีที่คุณสามารถอ้างถึงเอกสารที่ระบุอย่างชัดเจนว่า ส่งคืน Resource dimension value multiplied by the appropriate metric and truncated to integer pixels.
Muhammad Babar

นี่เป็นสิ่งที่ผิด การแปลงเมตริกเกิดขึ้นโดยใช้วิธีนี้เช่นกัน
Michael Peterson

14

สำหรับผู้ที่ต้องการประหยัดintค่าบางอย่างในทรัพยากรคุณสามารถทำสิ่งต่อไปนี้

integers.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <integer name="default_value">100</integer>
</resources> 

รหัส

int defaultValue = getResources().getInteger(R.integer.default_value);

2
ขอบคุณสำหรับสิ่งนี้คือสิ่งที่ฉันกำลังมองหาแม้ว่าอาจจะไม่ใช่สำหรับคนอื่น แต่วิธีนี้ทำให้ฉันได้รับข้อมูลเชิงลึกเกี่ยวกับส่วนอื่น ๆ ของรหัสของฉัน
JamisonMan111



2
    This works but the value I get is multiplied times the screen density factor
  (1.5 for hdpi, 2.0 for xhdpi, etc).

ฉันคิดว่ามันเป็นการดีที่จะได้รับค่าตามความละเอียด แต่ถ้าคุณไม่ต้องการทำสิ่งนี้ให้เป็น px .......

พิกเซลความหนาแน่นอิสระ (dp)

หน่วยพิกเซลเสมือนที่คุณควรใช้เมื่อกำหนดเค้าโครง UI เพื่อแสดงขนาดหรือตำแหน่งของเค้าโครงในแบบที่ไม่ขึ้นกับความหนาแน่น พิกเซลความหนาแน่นอิสระนั้นเทียบเท่ากับฟิสิคัลพิกเซลหนึ่งพิกเซลบนหน้าจอ 160 dpi ซึ่งเป็นความหนาแน่นพื้นฐานที่ระบบใช้สำหรับหน้าจอความหนาแน่น "ปานกลาง" ที่รันไทม์ระบบจะจัดการปรับขนาดของหน่วย dp ตามความจำเป็นbased on the actual density of the screen in use. The conversion of dp units to screen pixels is simple: px = dp * (dpi / 160). For example, on a 240 dpi screen, 1 dp equals 1.5 physical pixels.คุณควรใช้หน่วย dp เสมอเมื่อกำหนด UI ของแอปพลิเคชันของคุณเพื่อให้แน่ใจว่าการแสดง UI ของคุณบนหน้าจอที่มีความหนาแน่นแตกต่างกัน

ฉันคิดว่ามันเป็นการดีที่จะเปลี่ยนค่าตามความละเอียด แต่ถ้าคุณไม่ต้องการทำสิ่งนี้ให้ px .......

อ้างอิงลิงค์นี้

ตามนี้

DP

พิกเซลความหนาแน่นอิสระ - หน่วยนามธรรมที่ยึดตามความหนาแน่นทางกายภาพของหน้าจอ หน่วยเหล่านี้สัมพันธ์กับหน้าจอ 160 dpi (จุดต่อนิ้ว) ซึ่ง 1dp นั้นประมาณเท่ากับ 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.อัตราส่วนของพิกเซลต่อพิกเซลจะเปลี่ยนตามความหนาแน่นของหน้าจอ แต่ไม่จำเป็นต้องเป็นสัดส่วนโดยตรง การใช้หน่วย dp (แทนหน่วย px) เป็นวิธีง่ายๆในการทำให้ขนาดมุมมองในโครงร่างของคุณปรับขนาดอย่างถูกต้องสำหรับความหนาแน่นของหน้าจอที่แตกต่างกัน กล่าวอีกนัยหนึ่งมันให้ความสอดคล้องสำหรับขนาดจริงขององค์ประกอบ UI ของคุณในอุปกรณ์ต่าง ๆ

px

พิกเซล - สอดคล้องกับพิกเซลจริงบนหน้าจอ ไม่แนะนำให้ใช้หน่วยวัดนี้เนื่องจากการแสดงจริงอาจแตกต่างกันไปตามอุปกรณ์ อุปกรณ์แต่ละชิ้นอาจมีจำนวนพิกเซลต่อนิ้วที่แตกต่างกันและอาจมีพิกเซลทั้งหมดที่มีอยู่บนหน้าจอ


2

ใช้นามสกุล Kotlin

คุณสามารถเพิ่มส่วนขยายเพื่อทำให้กระบวนการนี้ง่ายขึ้น มันช่วยให้คุณเพียงแค่โทรcontext.dp(R.dimen. tutorial_cross_marginTop)เพื่อรับค่าโฟลต

fun Context.px(@DimenRes dimen: Int): Int = resources.getDimension(dimen).toInt()

fun Context.dp(@DimenRes dimen: Int): Float = px(dimen) / resources.displayMetrics.density

หากคุณต้องการจัดการโดยไม่มีบริบทคุณสามารถใช้Resources.getSystem():

val Int.dp get() = this / Resources.getSystem().displayMetrics.density // Float

val Int.px get() = (this * Resources.getSystem().displayMetrics.density).toInt()

ตัวอย่างเช่นบนอุปกรณ์ xhdpi ใช้24.dpเพื่อรับ 12.0 หรือ12.pxเพื่อรับ 24

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.