Изменить шрифт метки приложения при использовании ActionBarsherlock

Я пытаюсь изменить шрифт метки приложения (я использую ActionBarSherlock в качестве проекта библиотеки в своем приложении) и получаю ошибки.

Ниже приведен фрагмент кода, в котором я пытаюсь установить внешний шрифт, хранящийся в ресурсах, на метку приложения после setContentView().

mAppName = (TextView) findViewById(R.id.abs__action_bar_title);
Typeface face = Typeface.createFromAsset(getAssets(), "fonts/handsean.ttf");
mAppName.setTypeface(face);

Ниже приведена ошибка из logcat. Ошибка появляется в строке mAppName.setTypeface(face).

E/AndroidRuntime(18762): FATAL EXCEPTION: main
E/AndroidRuntime(18762): java.lang.RuntimeException: Unable to start activity  ComponentInfo{com.cheats/com.cheats.LandingPage}: java.lang.NullPointerException
E/AndroidRuntime(18762):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
E/AndroidRuntime(18762):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
E/AndroidRuntime(18762):    at android.app.ActivityThread.access$600(ActivityThread.java:141)
E/AndroidRuntime(18762):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
E/AndroidRuntime(18762):    at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(18762):    at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(18762):    at android.app.ActivityThread.main(ActivityThread.java:5039)
E/AndroidRuntime(18762):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(18762):    at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(18762):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
E/AndroidRuntime(18762):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
E/AndroidRuntime(18762):    at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime(18762): Caused by: java.lang.NullPointerException
E/AndroidRuntime(18762):    at com.cheats.LandingPage.onCreate(LandingPage.java:89)
E/AndroidRuntime(18762):    at android.app.Activity.performCreate(Activity.java:5104)
E/AndroidRuntime(18762):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
E/AndroidRuntime(18762):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)

Я нашел следующее объявление текстового представления для метки приложения в abs__action_bar_title_item.xml:

<TextView android:id="@+id/abs__action_bar_title"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:singleLine="true"
              android:ellipsize="end" />

Это правильный способ сделать это ИЛИ я что-то упустил? Может кто-нибудь посоветовать?

Спасибо за ваше время.


person Abhishek Sabbarwal    schedule 10.02.2013    source источник
comment
Пара проверок if(var == null) не повредит вашему коду, возможно, вы ссылаетесь на неправильную константу макета или ваш шрифт может быть не найден.   -  person Machinarius    schedule 10.02.2013
comment
@Machinarius: Я считаю, что это TextView, потому что, когда я пытался сделать с ним mAppName.setText(), в тексте ничего не изменилось. Теперь, после этого, я не уверен, как правильно получить доступ к textView из библиотеки sherlock? Или здесь требуется что-то другое? Есть ли у вас какие-либо предложения   -  person Abhishek Sabbarwal    schedule 10.02.2013
comment
Ну, я сам почти не пользовался Шерлоком, но я не думаю, что это связано с тем, что ты пользуешься библиотекой Шерлока. Вы уверены, что текстовое представление действительно там, где вы ожидаете? Кроме того, имейте в виду, что вы должны использовать findViewById и друзей после вызова setContentView, на всякий случай.   -  person Machinarius    schedule 10.02.2013
comment
@Machinarius: Ну, я почти уверен, что объявление, которое я разместил выше, используется в библиотеке для метки приложения. Также я делаю все findViewById и прочее после setContentView.   -  person Abhishek Sabbarwal    schedule 10.02.2013


Ответы (3)


После многих испытаний мне удалось получить ссылку на textView следующим образом, и теперь шрифт изменился:

int titleId = Resources.getSystem().getIdentifier("action_bar_title", "id", "android");
if(titleId == 0)
    titleId = com.actionbarsherlock.R.id.abs__action_bar_title;

mAppName = (TextView) findViewById(titleId);
Typeface face = Typeface.createFromAsset(getAssets(), "fonts/handsean.ttf");
mAppName.setTypeface(face);
person Abhishek Sabbarwal    schedule 10.02.2013

В Xamarin.Android (MonoDroid — С#):

Если у вас есть проблемы с получением null на TextView, это может быть связано с тем, что версия Android, приведенный выше код, работала для меня с Android 4.2, но не с 3.1.

Это сработало для меня:

TextView title = FindViewById<TextView>(Resources.GetIdentifier("action_bar_title", "id", "android"));
if (title == null) title = FindViewById<TextView>(Resource.Id.abs__action_bar_title);

if( title != null)
{
   Android.Graphics.Typeface face = Android.Graphics.Typeface.CreateFromAsset(Assets, "fonts/font.otf");
   title.SetTypeface(face, Android.Graphics.TypefaceStyle.Bold);
}
person charlesbock    schedule 16.01.2014

Решение, предоставленное Abhishek Sabbarwal, отлично работает (‹ 3.x и >= 4.x), но в случае Honeycomb ему не удается найти Textview, как указал charlesbock.

После отладки кажется, что эта строка дает положительный titleId, который еще не соответствует TextView.

int titleId = Resources.getSystem().getIdentifier("action_bar_title", "id", "android");

Однако, используя эту строку, TextView успешно найден

titleId = R.id.abs__action_bar_title;

Поэтому вот мой код, который работает для любой версии

int titleId = Resources.getSystem().getIdentifier("action_bar_title", "id", "android");
if(titleId == 0 || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB && Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH))
{
    titleId = R.id.abs__action_bar_title;
}

final TextView appName = (TextView) findViewById(titleId);
person ToYonos    schedule 03.02.2014