CHỈNH SỬA : Vì vậy, đã được một thời gian, và tôi muốn thêm những gì tôi nghĩ là cách tốt nhất để làm điều này, và thông qua XML không hơn không kém!
Vì vậy, trước tiên, bạn sẽ muốn tạo một lớp mới ghi đè bất kỳ Chế độ xem nào bạn muốn tùy chỉnh. (ví dụ: muốn một Nút có kiểu chữ tùy chỉnh? Mở rộng Button
). Hãy làm một ví dụ:
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);
}
}
Bây giờ, nếu bạn chưa có, hãy thêm tài liệu XML bên dưới res/values/attrs.xml
và thêm:
<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>
Được rồi, vậy là xong, hãy quay lại parseAttributes()
phương pháp trước đó:
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();
}
Bây giờ bạn đã sẵn sàng. Bạn có thể thêm nhiều thuộc tính hơn cho bất kỳ thứ gì (bạn có thể thêm một thuộc tính khác cho typefaceStyle - đậm, nghiêng, v.v.) nhưng bây giờ hãy xem cách sử dụng nó:
<?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>
Các xmlns:custom
dòng thực sự có thể được bất cứ điều gì, nhưng ước là những gì đang hiển thị ở trên. Điều quan trọng là nó là duy nhất và đó là lý do tại sao tên gói được sử dụng. Bây giờ bạn chỉ cần sử dụng custom:
tiền tố cho các thuộc tính của mình và android:
tiền tố cho các thuộc tính android.
Một điều cuối cùng: nếu bạn muốn sử dụng điều này trong một style ( res/values/styles.xml
), bạn không nên thêm xmlns:custom
dòng. Chỉ cần tham chiếu tên của thuộc tính không có tiền tố:
<style name="MyStyle>
<item name="typeface">roboto</item>
</style>
(PREVIOUS ANSWER)
Sử dụng kiểu chữ tùy chỉnh trong Android
Điều này sẽ giúp ích. Về cơ bản, không có cách nào để làm điều này trong XML, và theo như tôi có thể nói, không có cách nào dễ dàng hơn để làm điều đó trong mã. Bạn luôn có thể có một phương thức setLayoutFont () tạo kiểu chữ một lần, sau đó chạy setTypeface () cho mỗi phương thức. Bạn chỉ cần cập nhật nó mỗi khi bạn thêm một mục mới vào bố cục. Một cái gì đó như dưới đây:
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);
}
CHỈNH SỬA : Vì vậy, tôi chỉ cần tự mình thực hiện một cái gì đó như thế này, và cách tôi thực hiện nó là tạo ra một hàm như thế này:
public static void setLayoutFont(Typeface tf, TextView...params) {
for (TextView tv : params) {
tv.setTypeface(tf);
}
}
Sau đó, chỉ cần sử dụng phương thức này từ onCreate () và chuyển tất cả các TextView bạn muốn cập nhật:
Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/BPreplay.otf");
//find views by id...
setLayoutFont(tf, tv1, tv2, tv3, tv4, tv5);
CHỈNH SỬA 9/5/12:
Vì vậy, vì điều này vẫn đang nhận được lượt xem và phiếu bầu, tôi muốn thêm một phương pháp tốt hơn và hoàn thiện hơn:
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);
}
}
Nếu bạn chuyển nó vào thư mục gốc của bố cục, nó sẽ kiểm tra đệ quy TextView
hoặc các Button
chế độ xem (hoặc bất kỳ người nào khác mà bạn thêm vào câu lệnh if đó) trong bố cục đó và đặt phông chữ mà bạn không cần phải chỉ định chúng theo ID. Tất nhiên, điều này giả sử bạn muốn đặt phông chữ cho mọi chế độ xem.