ขนาดแบบอักษรของ TextView ในแอปพลิเคชัน Android จะเปลี่ยนขนาดตัวอักษรจากการตั้งค่าดั้งเดิม


171

ฉันต้องการระบุขนาดข้อความของตัวเองในแอปพลิเคชันของฉัน แต่ฉันมีปัญหาในการทำเช่นนี้

เมื่อฉันเปลี่ยนขนาดตัวอักษรในการตั้งค่าอุปกรณ์ขนาดตัวอักษรของแอปพลิเคชันของฉันTextViewก็เปลี่ยนไปเช่นกัน


2
มันเป็นพฤติกรรมเริ่มต้นที่ถ้าคุณเปลี่ยนขนาดตัวอักษรของแบบอักษรเนทิฟอุปกรณ์ของคุณก็จะมีผลต่อขนาดตัวอักษรของแอปพลิเคชันของคุณ
Shreyash Mahajan

คุณสามารถหาคำตอบได้จากที่นี่stackoverflow.com/questions/16706076/…
Bhavesh Jethani

ใช้ sp สำหรับขนาดตัวอักษร ... เพราะ แต่ถูกปรับขนาดตามขนาดตัวอักษรของผู้ใช้ ใช้ dp สำหรับทุกอย่าง
รักสด

คำตอบ:


231

spที่จริงแล้วการตั้งค่าขนาดตัวอักษรมีผลกระทบเฉพาะในขนาด ดังนั้นสิ่งที่คุณต้องทำ - กำหนดtextSizeในdpแทนspแล้วการตั้งค่าจะไม่เปลี่ยนขนาดของข้อความใน app ของคุณ

นี่คือลิงค์ไปยังเอกสาร: ส่วนข้อมูล

อย่างไรก็ตามโปรดทราบว่าพฤติกรรมที่คาดหวังก็คือแบบอักษรในแอพทั้งหมดนั้นเคารพการตั้งค่าของผู้ใช้ มีสาเหตุหลายประการที่ผู้ใช้อาจต้องการปรับขนาดแบบอักษรและบางส่วนอาจเป็นทางการแพทย์ - ผู้ใช้ที่มีความบกพร่องทางสายตา การใช้ข้อความdpแทนspอาจนำไปสู่การเลือกปฏิบัติอย่างไม่เต็มใจต่อผู้ใช้แอปบางส่วนของคุณ

เช่น:

android:textSize="32dp"

12
ยาวขณะที่กลับผมอยากจะรู้ว่าถ้ามีกฎใด ๆ เมื่อฉันควรใช้และเมื่อฉันควรใช้sp dpผมได้รับการตอบสนองที่ดีจริงๆที่นี่: stackoverflow.com/questions/11638691/...
แซม

129

วิธีที่ง่ายที่สุดคือใช้สิ่งต่อไปนี้:

android:textSize="32sp"

หากคุณต้องการทราบข้อมูลเพิ่มเติมเกี่ยวกับtextSizeคุณสมบัติคุณสามารถตรวจสอบเอกสารของนักพัฒนาซอฟต์แวร์ Android


1
นี่คือเหตุผลที่ TS มีปัญหาโดยใช้ 'sp' แทน 'dp'
เด็กชาย

8
ฉันยังไม่รู้ว่าทำไมมี 100 upvotes เพราะถ้าเราใช้ sp สำหรับกำหนด textize ในแอปพลิเคชัน จากนั้นเราเปลี่ยนขนาดตัวอักษรในการตั้งค่า TextView ในแอปพลิเคชันก็เปลี่ยน
ฟาน Van Linh

สิ่งนี้ตอบคำถามได้อย่างไร
Siddarth G

48

ใช้dimensionประเภทของทรัพยากรเช่นเดียวกับที่คุณใช้stringทรัพยากร ( DOCS )

ในdimens.xmlไฟล์ของคุณให้ประกาศตัวแปรมิติของคุณ:

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <dimen name="textview_height">25dp</dimen>
  <dimen name="textview_width">150dp</dimen>
  <dimen name="ball_radius">30dp</dimen>
  <dimen name="font_size">16sp</dimen>
</resources>

จากนั้นคุณสามารถใช้ค่าเหล่านี้ดังนี้:

<TextView
   android:layout_height="@dimen/textview_height"
   android:layout_width="@dimen/textview_width"
   android:textSize="@dimen/font_size"/>

คุณสามารถประกาศที่แตกต่างกัน dimens.xmlไฟล์ที่แตกต่างกันสำหรับหน้าจอประเภทต่างๆ การทำเช่นนี้จะรับประกันลักษณะที่ต้องการของแอปของคุณบนอุปกรณ์ที่แตกต่างกัน

เมื่อคุณไม่ได้ระบุandroid:textSizeระบบจะใช้ค่าเริ่มต้น


1
ปัญหาไม่ใช่หน้าจอ มันเป็นขนาดตัวอักษรพื้นเมืองที่เลือกในการตั้งค่าการแสดงผล Android ซึ่งนำไปสู่ปัญหาที่กล่าวถึง
Himanshu Virmani

24

โปรดทราบว่าหากตั้งค่า textSize ไว้ในรหัสการโทรจะtextView.setTextSize(X)ตีความหมายเลข (X) เป็น SP ใช้setTextSize(TypedValue.COMPLEX_UNIT_DIP, X)ให้เป็นค่าที่ตั้งอยู่ในDP


13

ไม่ใช่เรื่องดีที่จะต้องระบุ DIP หรือ SP อีกครั้งด้วยรหัสเมื่อกำหนดไว้แล้วในไฟล์ dimen.xml

ฉันคิดว่าตัวเลือกที่ดีที่สุดคือการใช้ PX เมื่อใช้ค่า dimen.xml:

tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen.txt_size));

ด้วยวิธีนี้คุณสามารถเปลี่ยนจาก DP เป็น SP ได้หากต้องการในไฟล์ dimen.xml โดยไม่ต้องเปลี่ยนรหัสใด ๆ


6

วิธีง่ายๆในการป้องกันไม่ให้แอปทั้งหมดได้รับผลกระทบจากขนาดแบบอักษรของระบบคือการอัปเดตการกำหนดค่าโดยใช้กิจกรรมพื้นฐาน

//in base activity add this code.
public  void adjustFontScale( Configuration configuration) {

    configuration.fontScale = (float) 1.0;
    DisplayMetrics metrics = getResources().getDisplayMetrics();
    WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
    wm.getDefaultDisplay().getMetrics(metrics);
    metrics.scaledDensity = configuration.fontScale * metrics.density;
    getBaseContext().getResources().updateConfiguration(configuration, metrics);

}

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    adjustFontScale( getResources().getConfiguration());
}

1

สิ่งนี้อาจช่วยได้ เพิ่มรหัสในแอปพลิเคชันที่กำหนดเองหรือ BaseActivity ของคุณ

/**
 * 重写 getResource 方法,防止系统字体影响
 *
 * @return
 */
@Override
public Resources getResources() {
    Resources resources = super.getResources();
    if (resources != null && resources.getConfiguration().fontScale != 1) {
        Configuration configuration = resources.getConfiguration();
        configuration.fontScale = 1;
        resources.updateConfiguration(configuration, resources.getDisplayMetrics());
    }
    return resources;
}

อย่างไรก็ตาม Resource # updateConfiguration จะแสดงอยู่ใน API ระดับ 25 ซึ่งหมายความว่าจะไม่ได้รับการสนับสนุนในอนาคต


1

คุณสามารถใช้รหัสนี้:

android:textSize="32dp"

มันแก้ปัญหาของคุณ แต่คุณต้องรู้ว่าคุณควรเคารพการตัดสินใจของผู้ใช้ โดยการเปลี่ยนขนาดตัวอักษรจากการตั้งค่าอุปกรณ์จะไม่เปลี่ยนค่านี้ เพื่อที่ว่าทำไมคุณต้องใช้SPแทนDP ดังนั้นข้อเสนอแนะของฉันคือการตรวจสอบแอปของคุณด้วยขนาดแบบอักษรของระบบที่แตกต่างกัน (เล็ก, ปกติ, ใหญ่, ... )




0

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

resources.updateConfigurationเลิกใช้แล้วและมีข้อผิดพลาด (บน Oreo ฉันมีปัญหากับข้อความที่จัดรูปแบบ)


0

แทนที่getResources()ในกิจกรรม

กำหนดขนาดของ TextView เป็น sp เหมือนปกติ android:textSize="32sp"

override fun getResources(): Resources {
    return super.getResources().apply {
        configuration.fontScale = 1F
        updateConfiguration(configuration, displayMetrics)
    }
}

0

ใน Android 8 วิธีนี้ใช้งานได้สำหรับฉัน

เพิ่มรหัสนี้ในกิจกรรมพื้นฐาน

@Override
protected void attachBaseContext(Context newBase) {
    super.attachBaseContext(newBase);
    final Configuration override = new Configuration(newBase.getResources().getConfiguration());
    override.fontScale = 1.0f;
    applyOverrideConfiguration(override);
}

แหล่ง https://stackoverflow.com/a/57225687/7985871

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