แก้ไข : เป็นเวลานานแล้วและฉันต้องการเพิ่มสิ่งที่ฉันคิดว่าเป็นวิธีที่ดีที่สุดในการทำเช่นนี้และผ่าน XML ไม่น้อย!
ก่อนอื่นคุณจะต้องสร้างคลาสใหม่ที่แทนที่มุมมองที่คุณต้องการปรับแต่ง (เช่นต้องการปุ่มที่มีแบบอักษรที่กำหนดเองหรือไม่ขยายButton
) ลองทำตัวอย่าง:
public class CustomButton extends Button {
private final static int ROBOTO = 0;
private final static int ROBOTO_CONDENSED = 1;
public CustomButton(Context context) {
super(context);
}
public CustomButton(Context context, AttributeSet attrs) {
super(context, attrs);
parseAttributes(context, attrs); //I'll explain this method later
}
public CustomButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
parseAttributes(context, attrs);
}
}
ตอนนี้ถ้าคุณไม่มีให้เพิ่มเอกสาร XML ด้านล่างres/values/attrs.xml
และเพิ่ม:
<resources>
<!-- Define the values for the attribute -->
<attr name="typeface" format="enum">
<enum name="roboto" value="0"/>
<enum name="robotoCondensed" value="1"/>
</attr>
<!-- Tell Android that the class "CustomButton" can be styled,
and which attributes it supports -->
<declare-styleable name="CustomButton">
<attr name="typeface"/>
</declare-styleable>
</resources>
เอาล่ะด้วยวิธีนี้เราจะกลับไปที่parseAttributes()
วิธีการก่อนหน้านี้:
private void parseAttributes(Context context, AttributeSet attrs) {
TypedArray values = context.obtainStyledAttributes(attrs, R.styleable.CustomButton);
//The value 0 is a default, but shouldn't ever be used since the attr is an enum
int typeface = values.getInt(R.styleable.CustomButton_typeface, 0);
switch(typeface) {
case ROBOTO: default:
//You can instantiate your typeface anywhere, I would suggest as a
//singleton somewhere to avoid unnecessary copies
setTypeface(roboto);
break;
case ROBOTO_CONDENSED:
setTypeface(robotoCondensed);
break;
}
values.recycle();
}
ตอนนี้คุณพร้อมแล้ว คุณสามารถเพิ่มแอตทริบิวต์อื่น ๆ สำหรับอะไรก็ได้ (คุณสามารถเพิ่มอีกอันหนึ่งสำหรับ typefaceStyle - ตัวหนาตัวเอียง ฯลฯ ) แต่ตอนนี้เรามาดูวิธีใช้กัน:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res/com.yourpackage.name"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.yourpackage.name.CustomButton
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click Me!"
custom:typeface="roboto" />
</LinearLayout>
xmlns:custom
บรรทัดจริงๆสามารถเป็นอะไรก็ได้ แต่การประชุมเป็นสิ่งที่แสดงไว้ข้างต้น สิ่งที่สำคัญคือมันไม่เหมือนใครและนั่นคือเหตุผลที่ใช้ชื่อแพ็กเกจ ตอนนี้คุณใช้custom:
คำนำหน้าสำหรับแอตทริบิวต์ของคุณและandroid:
คำนำหน้าสำหรับแอตทริบิวต์ android
สิ่งสุดท้าย: หากคุณต้องการใช้สิ่งนี้ในลักษณะ ( res/values/styles.xml
) คุณไม่ควรเพิ่มxmlns:custom
บรรทัด เพียงอ้างอิงชื่อของแอตทริบิวต์โดยไม่มีคำนำหน้า:
<style name="MyStyle>
<item name="typeface">roboto</item>
</style>
(PREVIOUS ANSWER)
ใช้แบบอักษรที่กำหนดเองใน Android
สิ่งนี้น่าจะช่วยได้ โดยทั่วไปไม่มีวิธีทำใน XML และเท่าที่ฉันบอกได้ไม่มีวิธีที่ง่ายกว่าในการทำในโค้ด คุณสามารถมีเมธอด setLayoutFont () ที่สร้างแบบอักษรหนึ่งครั้งจากนั้นเรียกใช้ setTypeface () สำหรับแต่ละ คุณต้องอัปเดตทุกครั้งที่คุณเพิ่มรายการใหม่ลงในเค้าโครง สิ่งที่ต้องการด้านล่าง:
public void setLayoutFont() {
Typeface tf = Typeface.createFromAsset(
getBaseContext().getAssets(), "fonts/BPreplay.otf");
TextView tv1 = (TextView)findViewById(R.id.tv1);
tv1.setTypeface(tf);
TextView tv2 = (TextView)findViewById(R.id.tv2);
tv2.setTypeface(tf);
TextView tv3 = (TextView)findViewById(R.id.tv3);
tv3.setTypeface(tf);
}
แก้ไข : ดังนั้นฉันจึงได้ใช้สิ่งนี้ด้วยตัวเองและวิธีที่ฉันทำมันคือการสร้างฟังก์ชันเช่นนี้:
public static void setLayoutFont(Typeface tf, TextView...params) {
for (TextView tv : params) {
tv.setTypeface(tf);
}
}
จากนั้นใช้วิธีนี้จาก onCreate () และส่ง TextView ทั้งหมดที่คุณต้องการอัปเดต:
Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/BPreplay.otf");
//find views by id...
setLayoutFont(tf, tv1, tv2, tv3, tv4, tv5);
แก้ไข 9/5/12:
ดังนั้นเนื่องจากสิ่งนี้ยังคงได้รับการดูและโหวตฉันจึงต้องการเพิ่มวิธีที่ดีกว่าและสมบูรณ์กว่านี้:
Typeface mFont = Typeface.createFromAsset(getAssets(), "fonts/BPreplay.otf");
ViewGroup root = (ViewGroup)findViewById(R.id.myrootlayout);
setFont(root, mFont);
/*
* Sets the font on all TextViews in the ViewGroup. Searches
* recursively for all inner ViewGroups as well. Just add a
* check for any other views you want to set as well (EditText,
* etc.)
*/
public void setFont(ViewGroup group, Typeface font) {
int count = group.getChildCount();
View v;
for(int i = 0; i < count; i++) {
v = group.getChildAt(i);
if(v instanceof TextView || v instanceof Button /*etc.*/)
((TextView)v).setTypeface(font);
else if(v instanceof ViewGroup)
setFont((ViewGroup)v, font);
}
}
หากคุณส่งผ่านรูทของเค้าโครงของคุณมันจะตรวจสอบซ้ำTextView
หรือButton
มุมมอง (หรืออื่น ๆ ที่คุณเพิ่มเข้าไปในคำสั่ง if นั้น) ภายในเค้าโครงนั้นและตั้งค่าแบบอักษรโดยที่คุณไม่ต้องระบุด้วย ID แน่นอนว่าคุณต้องการตั้งค่าแบบอักษรเป็นทุกมุมมอง