Câu trả lời:
Tôi đồng ý rằng điều này không hoàn toàn được hỗ trợ, nhưng đây là những gì tôi đã làm. Bạn có thể sử dụng chế độ xem tùy chỉnh cho thanh hành động của mình (nó sẽ hiển thị giữa biểu tượng và các mục hành động của bạn). Tôi đang sử dụng chế độ xem tùy chỉnh và tôi đã tắt tiêu đề gốc. Tất cả các hoạt động của tôi kế thừa từ một hoạt động duy nhất, có mã này trong onCreate:
this.getActionBar().setDisplayShowCustomEnabled(true);
this.getActionBar().setDisplayShowTitleEnabled(false);
LayoutInflater inflator = LayoutInflater.from(this);
View v = inflator.inflate(R.layout.titleview, null);
//if you need to customize anything else about the text, do it here.
//I'm using a custom TextView with a custom font in my layout xml so all I need to do is set title
((TextView)v.findViewById(R.id.title)).setText(this.getTitle());
//assign the view to the actionbar
this.getActionBar().setCustomView(v);
Và bố cục xml của tôi (R.layout.titleview trong đoạn mã trên) trông như thế này:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent" >
<com.your.package.CustomTextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:textSize="20dp"
android:maxLines="1"
android:ellipsize="end"
android:text="" />
</RelativeLayout>
Bạn có thể làm điều này bằng cách sử dụng một TypefaceSpan
lớp tùy chỉnh . Nó vượt trội so với customView
cách tiếp cận được chỉ ra ở trên vì nó không bị hỏng khi sử dụng các yếu tố Action Bar khác như mở rộng chế độ xem hành động.
Việc sử dụng một lớp như vậy sẽ trông giống như thế này:
SpannableString s = new SpannableString("My Title");
s.setSpan(new TypefaceSpan(this, "MyTypeface.otf"), 0, s.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// Update the action bar title with the TypefaceSpan instance
ActionBar actionBar = getActionBar();
actionBar.setTitle(s);
Lớp tùy chỉnh TypefaceSpan
được thông qua bối cảnh Hoạt động của bạn và tên của một kiểu chữ trong assets/fonts
thư mục của bạn . Nó tải tập tin và lưu trữ một Typeface
thể hiện mới trong bộ nhớ. Việc thực hiện đầy đủ TypefaceSpan
là đơn giản đáng ngạc nhiên:
/**
* Style a {@link Spannable} with a custom {@link Typeface}.
*
* @author Tristan Waddington
*/
public class TypefaceSpan extends MetricAffectingSpan {
/** An <code>LruCache</code> for previously loaded typefaces. */
private static LruCache<String, Typeface> sTypefaceCache =
new LruCache<String, Typeface>(12);
private Typeface mTypeface;
/**
* Load the {@link Typeface} and apply to a {@link Spannable}.
*/
public TypefaceSpan(Context context, String typefaceName) {
mTypeface = sTypefaceCache.get(typefaceName);
if (mTypeface == null) {
mTypeface = Typeface.createFromAsset(context.getApplicationContext()
.getAssets(), String.format("fonts/%s", typefaceName));
// Cache the loaded Typeface
sTypefaceCache.put(typefaceName, mTypeface);
}
}
@Override
public void updateMeasureState(TextPaint p) {
p.setTypeface(mTypeface);
// Note: This flag is required for proper typeface rendering
p.setFlags(p.getFlags() | Paint.SUBPIXEL_TEXT_FLAG);
}
@Override
public void updateDrawState(TextPaint tp) {
tp.setTypeface(mTypeface);
// Note: This flag is required for proper typeface rendering
tp.setFlags(tp.getFlags() | Paint.SUBPIXEL_TEXT_FLAG);
}
}
Chỉ cần sao chép lớp trên vào dự án của bạn và triển khai nó trong onCreate
phương thức hoạt động của bạn như được hiển thị ở trên.
textAllCaps
thuộc tính được đặt thành true trên TextView bên dưới (ví dụ: thông qua một chủ đề), thì phông chữ tùy chỉnh sẽ không xuất hiện. Đây là một vấn đề đối với tôi khi tôi áp dụng kỹ thuật này cho các mục tab thanh hành động.
assets/fonts/
. Nếu bạn chỉ ném các tệp .ttf / .otf dưới các tài sản và không nằm trong thư mục con, bạn nên sửa đổi dòng mã sau cho phù hợp : String.format("fonts/%s", typefaceName)
. Tôi đã mất 10 phút cố gắng để tìm ra nó. Nếu bạn không, bạn sẽ nhận đượcjava.lang.RuntimeException: Unable to start activity ComponentInfo{com.your.pckage}: java.lang.RuntimeException: native typeface cannot be made
int titleId = getResources().getIdentifier("action_bar_title", "id",
"android");
TextView yourTextView = (TextView) findViewById(titleId);
yourTextView.setTextColor(getResources().getColor(R.color.black));
yourTextView.setTypeface(face);
Từ Thư viện hỗ trợ Android v26 + Android Studio 3.0 trở đi, quá trình này đã trở nên dễ dàng như một cái búng tay !!
Thực hiện theo các bước sau để thay đổi phông chữ của Tiêu đề Thanh công cụ:
res > font
theo phông chữ trong XMLTrong res > values > styles
, dán sau đây ( sử dụng trí tưởng tượng của bạn ở đây! )
<style name="TitleBarTextAppearance" parent="android:TextAppearance">
<item name="android:fontFamily">@font/your_desired_font</item>
<item name="android:textSize">23sp</item>
<item name="android:textStyle">bold</item>
<item name="android:textColor">@android:color/white</item>
</style>
Chèn một dòng mới trong thuộc tính Thanh công cụ của bạn app:titleTextAppearance="@style/TextAppearance.TabsFont"
như hiển thị bên dưới
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:titleTextAppearance="@style/TitleBarTextAppearance"
app:popupTheme="@style/AppTheme.PopupOverlay"/>
Thưởng thức kiểu chữ Tiêu đề Actionbar tùy chỉnh !!
Các Thư pháp thư viện cho phép của bạn thiết lập một phông chữ tùy chỉnh thông qua các chủ đề ứng dụng, mà cũng sẽ áp dụng cho thanh hành động.
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<item name="android:textViewStyle">@style/AppTheme.Widget.TextView</item>
</style>
<style name="AppTheme.Widget"/>
<style name="AppTheme.Widget.TextView" parent="android:Widget.Holo.Light.TextView">
<item name="fontPath">fonts/Roboto-ThinItalic.ttf</item>
</style>
Tất cả những gì cần thiết để kích hoạt Thư pháp là gắn nó vào ngữ cảnh Hoạt động của bạn:
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(new CalligraphyContextWrapper(newBase));
}
Thuộc tính tùy chỉnh mặc định là fontPath
, nhưng bạn có thể cung cấp thuộc tính tùy chỉnh của riêng bạn cho đường dẫn bằng cách khởi tạo nó trong lớp Ứng dụng của bạn với CalligraphyConfig.Builder
. Cách sử dụng android:fontFamily
đã được khuyến khích.
Đây là một hack xấu xí nhưng bạn có thể làm điều đó như thế này (vì action_bar_title bị ẩn):
try {
Integer titleId = (Integer) Class.forName("com.android.internal.R$id")
.getField("action_bar_title").get(null);
TextView title = (TextView) getWindow().findViewById(titleId);
// check for null and manipulate the title as see fit
} catch (Exception e) {
Log.e(TAG, "Failed to obtain action bar title reference");
}
Mã này dành cho các thiết bị sau GINGERBREAD nhưng điều này có thể dễ dàng được mở rộng để hoạt động với thanh hành động Sherlock.
PS Dựa trên nhận xét @pjv có cách tốt hơn để tìm id tiêu đề thanh hành động
final int titleId =
Resources.getSystem().getIdentifier("action_bar_title", "id", "android");
Mã sau sẽ làm việc cho tất cả các phiên bản. Tôi đã kiểm tra điều này trong một thiết bị có bánh gừng cũng như trên thiết bị JellyBean
private void actionBarIdForAll()
{
int titleId = 0;
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB)
{
titleId = getResources().getIdentifier("action_bar_title", "id", "android");
}
else
{
// This is the id is from your app's generated R class when ActionBarActivity is used for SupportActionBar
titleId = R.id.action_bar_title;
}
if(titleId>0)
{
// Do whatever you want ? It will work for all the versions.
// 1. Customize your fonts
// 2. Infact, customize your whole title TextView
TextView titleView = (TextView)findViewById(titleId);
titleView.setText("RedoApp");
titleView.setTextColor(Color.CYAN);
}
}
sử dụng thanh công cụ mới trong thư viện hỗ trợ thiết kế thanh hành động của riêng bạn hoặc sử dụng mã bên dưới
Inflating Textview không phải là một lựa chọn tốt, hãy thử Trình xây dựng chuỗi Spannable
Typeface font2 = Typeface.createFromAsset(getAssets(), "fonts/<your font in assets folder>");
SpannableStringBuilder SS = new SpannableStringBuilder("MY Actionbar Tittle");
SS.setSpan (new CustomTypefaceSpan("", font2), 0, SS.length(),Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
actionBar.setTitle(ss);
sao chép dưới lớp
public class CustomTypefaceSpan extends TypefaceSpan{
private final Typeface newType;
public CustomTypefaceSpan(String family, Typeface type) {
super(family);
newType = type;
}
@Override
public void updateDrawState(TextPaint ds) {
applyCustomTypeFace(ds, newType);
}
@Override
public void updateMeasureState(TextPaint paint) {
applyCustomTypeFace(paint, newType);
}
private static void applyCustomTypeFace(Paint paint, Typeface tf) {
int oldStyle;
Typeface old = paint.getTypeface();
if (old == null) {
oldStyle = 0;
} else {
oldStyle = old.getStyle();
}
int fake = oldStyle & ~tf.getStyle();
if ((fake & Typeface.BOLD) != 0) {
paint.setFakeBoldText(true);
}
if ((fake & Typeface.ITALIC) != 0) {
paint.setTextSkewX(-0.25f);
}
paint.setTypeface(tf);
}
}
ActionBar actionBar = getSupportActionBar();
TextView tv = new TextView(getApplicationContext());
Typeface typeface = ResourcesCompat.getFont(this, R.font.monotype_corsiva);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, // Width of TextView
RelativeLayout.LayoutParams.WRAP_CONTENT); // Height of TextView
tv.setLayoutParams(lp);
tv.setText("Your Text"); // ActionBar title text
tv.setTextSize(25);
tv.setTextColor(Color.WHITE);
tv.setTypeface(typeface, typeface.ITALIC);
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
actionBar.setCustomView(tv);
typeface.ITALIC
với Typeface.ITALIC
không có cảnh báo thành viên tĩnh
Nếu bạn muốn đặt kiểu chữ cho tất cả các TextView trong toàn bộ Hoạt động, bạn có thể sử dụng một cái gì đó như thế này:
public static void setTypefaceToAll(Activity activity)
{
View view = activity.findViewById(android.R.id.content).getRootView();
setTypefaceToAll(view);
}
public static void setTypefaceToAll(View view)
{
if (view instanceof ViewGroup)
{
ViewGroup g = (ViewGroup) view;
int count = g.getChildCount();
for (int i = 0; i < count; i++)
setTypefaceToAll(g.getChildAt(i));
}
else if (view instanceof TextView)
{
TextView tv = (TextView) view;
setTypeface(tv);
}
}
public static void setTypeface(TextView tv)
{
TypefaceCache.setFont(tv, TypefaceCache.FONT_KOODAK);
}
Và kiểu chữ:
import java.util.TreeMap;
import android.graphics.Typeface;
import android.widget.TextView;
public class TypefaceCache {
//Font names from asset:
public static final String FONT_ROBOTO_REGULAR = "fonts/Roboto-Regular.ttf";
public static final String FONT_KOODAK = "fonts/Koodak.ttf";
private static TreeMap<String, Typeface> fontCache = new TreeMap<String, Typeface>();
public static Typeface getFont(String fontName) {
Typeface tf = fontCache.get(fontName);
if(tf == null) {
try {
tf = Typeface.createFromAsset(MyApplication.getAppContext().getAssets(), fontName);
}
catch (Exception e) {
return null;
}
fontCache.put(fontName, tf);
}
return tf;
}
public static void setFont(TextView tv, String fontName)
{
tv.setTypeface(getFont(fontName));
}
}
Tôi vừa thực hiện các thao tác sau bên trong hàm onCreate ():
TypefaceSpan typefaceSpan = new TypefaceSpan("font_to_be_used");
SpannableString str = new SpannableString("toolbar_text");
str.setSpan(typefaceSpan,0, str.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
getSupportActionBar().setTitle(str);
Tôi đang sử dụng Thư viện hỗ trợ, nếu bạn không sử dụng chúng, tôi đoán bạn nên chuyển sang getActionBar () thay vì getSupportActionBar ().
Trong Android Studio 3, bạn có thể thêm phông chữ tùy chỉnh theo hướng dẫn này https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html và sau đó sử dụng phông chữ mới được thêm vào của bạn trong " font_to_be_use "
Để thêm vào câu trả lời của @ Sam_D, tôi đã phải làm điều này để làm cho nó hoạt động:
this.setTitle("my title!");
((TextView)v.findViewById(R.id.title)).setText(this.getTitle());
TextView title = ((TextView)v.findViewById(R.id.title));
title.setEllipsize(TextUtils.TruncateAt.MARQUEE);
title.setMarqueeRepeatLimit(1);
// in order to start strolling, it has to be focusable and focused
title.setFocusable(true);
title.setSingleLine(true);
title.setFocusableInTouchMode(true);
title.requestFocus();
Có vẻ như quá mức - tham khảo v.findViewById (R.id.title)) hai lần - nhưng đó là cách duy nhất nó sẽ cho phép tôi làm điều đó.
Để cập nhật câu trả lời đúng.
Thứ nhất: đặt tiêu đề thành false, bởi vì chúng tôi đang sử dụng chế độ xem tùy chỉnh
actionBar.setDisplayShowTitleEnabled(false);
Thứ hai: tạo titleview.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent" >
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:textSize="20dp"
android:maxLines="1"
android:ellipsize="end"
android:text="" />
</RelativeLayout>
Cuối cùng:
//font file must be in the phone db so you have to create download file code
//check the code on the bottom part of the download file code.
TypeFace font = Typeface.createFromFile("/storage/emulated/0/Android/data/"
+ BuildConfig.APPLICATION_ID + "/files/" + "font name" + ".ttf");
if(font != null) {
LayoutInflater inflator = LayoutInflater.from(this);
View v = inflator.inflate(R.layout.titleview, null);
TextView titleTv = ((TextView) v.findViewById(R.id.title));
titleTv.setText(title);
titleTv.setTypeface(font);
actionBar.setCustomView(v);
} else {
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle(" " + title); // Need to add a title
}
TẢI XUỐNG FILE FILE: vì tôi đang lưu trữ tệp vào đám mây nên tôi có liên kết trên đó để tải xuống.
/**downloadFile*/
public void downloadFile(){
String DownloadUrl = //url here
File file = new File("/storage/emulated/0/Android/data/" + BuildConfig.APPLICATION_ID + "/files/");
File[] list = file.listFiles();
if(list == null || list.length <= 0) {
BroadcastReceiver onComplete = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
try{
showContentFragment(false);
} catch (Exception e){
}
}
};
registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(DownloadUrl));
request.setVisibleInDownloadsUi(false);
request.setDestinationInExternalFilesDir(this, null, ModelManager.getInstance().getCurrentApp().getRegular_font_name() + ".ttf");
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);
} else {
for (File files : list) {
if (!files.getName().equals("font_name" + ".ttf")) {
BroadcastReceiver onComplete = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
try{
showContentFragment(false);
} catch (Exception e){
}
}
};
registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(DownloadUrl));
request.setVisibleInDownloadsUi(false);
request.setDestinationInExternalFilesDir(this, null, "font_name" + ".ttf");
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);
} else {
showContentFragment(false);
break;
}
}
}
}
Không có textview tùy chỉnh được yêu cầu!
Đầu tiên, vô hiệu hóa tiêu đề trong toobar trong mã java của bạn: getSupportActionBar (). SetDisplayShowTitleEnabled (false);
Sau đó, chỉ cần thêm một TextView bên trong thanh công cụ:
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:textSize="18sp"
android:fontFamily="@font/roboto" />
</android.support.v7.widget.Toolbar>
Hãy thử sử dụng cái này
TextView headerText= new TextView(getApplicationContext());
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.WRAP_CONTENT);
headerText.setLayoutParams(lp);
headerText.setText("Welcome!");
headerText.setTextSize(20);
headerText.setTextColor(Color.parseColor("#FFFFFF"));
Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/wesfy_regular.ttf");
headerText.setTypeface(tf);
getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
getSupportActionBar().setCustomView(headerText);
Chúng ta cần sử dụng các phản xạ để đạt được điều này
final int titleId = activity.getResources().getIdentifier("action_bar_title", "id", "android");
final TextView title;
if (activity.findViewById(titleId) != null) {
title = (TextView) activity.findViewById(titleId);
title.setTextColor(Color.BLACK);
title.setTextColor(configs().getColor(ColorKey.GENERAL_TEXT));
title.setTypeface(configs().getTypeface());
} else {
try {
Field f = bar.getClass().getDeclaredField("mTitleTextView");
f.setAccessible(true);
title = (TextView) f.get(bar);
title.setTextColor(Color.BLACK);
title.setTypeface(configs().getTypeface());
} catch (NoSuchFieldException e) {
} catch (IllegalAccessException e) {
}
}
THỬ CÁI NÀY
public void findAndSetFont(){
getActionBar().setTitle("SOME TEST TEXT");
scanForTextViewWithText(this,"SOME TEST TEXT",new SearchTextViewInterface(){
@Override
public void found(TextView title) {
}
});
}
public static void scanForTextViewWithText(Activity activity,String searchText, SearchTextViewInterface searchTextViewInterface){
if(activity == null|| searchText == null || searchTextViewInterface == null)
return;
View view = activity.findViewById(android.R.id.content).getRootView();
searchForTextViewWithTitle(view, searchText, searchTextViewInterface);
}
private static void searchForTextViewWithTitle(View view, String searchText, SearchTextViewInterface searchTextViewInterface)
{
if (view instanceof ViewGroup)
{
ViewGroup g = (ViewGroup) view;
int count = g.getChildCount();
for (int i = 0; i < count; i++)
searchForTextViewWithTitle(g.getChildAt(i), searchText, searchTextViewInterface);
}
else if (view instanceof TextView)
{
TextView textView = (TextView) view;
if(textView.getText().toString().equals(searchText))
if(searchTextViewInterface!=null)
searchTextViewInterface.found(textView);
}
}
public interface SearchTextViewInterface {
void found(TextView title);
}