У меня есть файл шрифта ttf в папке с ресурсами. Я знаю, как использовать его для текстовых просмотров:
Typeface externalFont=Typeface.createFromAsset(getAssets(), "fonts/HelveticaNeueLTCom-Lt.ttf");
textview1.setTypeface(externalFont);
Я определил внешний вид своего текста счетчика в собственном XML-файле (как обычно в Android):
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+android:id/text1"
style="?android:attr/spinnerItemStyle"
android:singleLine="true"
android:textColor="#ffffff"
android:gravity="center"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:ellipsize="marquee" />
Я просто не могу ссылаться на это текстовое представление из кода, я всегда получаю исключения с нулевым указателем. Например, я пробовал:
TextView spinner_text=(TextView)findViewById(R.id.text1);
spinner_text.setTypeface(externalFont);
Можно ли выбрать внешний шрифт даже для текста счетчика, определенного в его собственном xml?
Спасибо.
ИЗМЕНИТЬ с ответом:
Это работает:
String [] items = new String[2];
items[0]="Something1";
items[1]="Something2";
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
R.layout.spinaca, items) {
public View getView(int position, View convertView, ViewGroup parent) {
View v = super.getView(position, convertView, parent);
Typeface externalFont=Typeface.createFromAsset(getAssets(), "fonts/HelveticaNeueLTCom-Lt.ttf");
((TextView) v).setTypeface(externalFont);
return v;
}
public View getDropDownView(int position, View convertView, ViewGroup parent) {
View v =super.getDropDownView(position, convertView, parent);
Typeface externalFont=Typeface.createFromAsset(getAssets(), "fonts/HelveticaNeueLTCom-Lt.ttf");
((TextView) v).setTypeface(externalFont);
v.setBackgroundColor(Color.GREEN);
return v;
}
};
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
Может понадобиться добавить
import android.view.ViewGroup;
К вашему списку импорта вверху файла. По какой-то причине Eclipse не делает этого предложения, когда не распознает класс ViewGroup, задействованный в коде.
Ответы:
Вот что сработало для меня (используя идеи как из ответов CommonsWare, так и из ответов gsanllorente ):
private static class MySpinnerAdapter extends ArrayAdapter<String> { // Initialise custom font, for example: Typeface font = Typeface.createFromAsset(getContext().getAssets(), "fonts/Blambot.otf"); // (In reality I used a manager which caches the Typeface objects) // Typeface font = FontManager.getInstance().getFont(getContext(), BLAMBOT); private MySpinnerAdapter(Context context, int resource, List<String> items) { super(context, resource, items); } // Affects default (closed) state of the spinner @Override public View getView(int position, View convertView, ViewGroup parent) { TextView view = (TextView) super.getView(position, convertView, parent); view.setTypeface(font); return view; } // Affects opened state of the spinner @Override public View getDropDownView(int position, View convertView, ViewGroup parent) { TextView view = (TextView) super.getDropDownView(position, convertView, parent); view.setTypeface(font); return view; } }
Если вы, как и я, изначально заполнили Spinner, используя
ArrayAdapter.createFromResource()
и ресурс массива (как в документации Spinner ), вы бы использовали MySpinnerAdapter следующим образом:MySpinnerAdapter<String> adapter = new MySpinnerAdapter( getContext(), R.layout.view_spinner_item, Arrays.asList(getResources().getStringArray(R.array.my_array)) ); spinner.setAdapter(adapter);
источник
assignAdapterWithOptions(Spinner spinner, int textArrayResId)
метод, получающий контекстspinner.getContext()
и назначающий адаптер для счетчика внутри него (макеты счетчиков являются стандартными для всего моего приложения)Вы бы применили шрифт через свой собственный
SpinnerAdapter
, вgetView()
иgetDropDownView()
.источник
android.view.ViewGroup
, предположительноЕсли вы реализуете свой адаптер в другом файле, вы можете получить доступ к функции «getAssets ()» из конструктора адаптера, так как у вас есть контекст в качестве параметра.
public class YourItemAdapter extends ArrayAdapter<String> { int recurso; Typeface tf; public YourItemAdapter(Context _context, int _resource, List<String> _items) { super(_context, _resource, _items); recurso=_resource; tf=Typeface.createFromAsset(_context.getAssets(),"font/digital-7.ttf"); } @Override public View getView(int position, View convertView, ViewGroup parent) { //You can use the new tf here. TextView spinner_text=(TextView)findViewById(R.id.text1); spinner_text.setTypeface(tf); } }
источник
findViewById(R.id.text1)
похоже, не удалось найти TextView, хотя идентификатор был правильным. Некоторые другие проблемы в этом коде: 1) отсутствует оператор возврата вgetView()
, 2) неиспользуемое полеrecurso
, 3) некоторые проблемы со стилем, такие как присвоение имени переменнойspinner_text
(должно бытьspinnerText
). Вот что у меня сработало .Попробуйте создать custom_spinner.xml
<?xml version="1.0" encoding="utf-8"?> <com.xxxx.xxxx.CheckedTextViewC xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/text1" style="?android:attr/spinnerDropDownItemStyle" android:singleLine="true" android:layout_width="match_parent" android:layout_height="wrap_content" android:ellipsize="marquee" android:textAlignment="center" android:paddingTop="5dp" android:paddingBottom="5dp" android:textSize="18sp" />
Создайте собственный CheckedtextView, как это
import android.content.Context; import android.graphics.Typeface; import android.util.AttributeSet; import android.widget.CheckedTextView; public class CheckedTextViewC extends CheckedTextView { public CheckedTextViewC(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub } public CheckedTextViewC(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub } public CheckedTextViewC(Context context) { super(context); // TODO Auto-generated constructor stub } public void setTypeface(Typeface tf, int style) { if(!this.isInEditMode()){ Typeface normalTypeface = Typeface.createFromAsset(getContext().getAssets(), "font/Roboto-Light.ttf"); Typeface boldTypeface = Typeface.createFromAsset(getContext().getAssets(), "font/Roboto-Light.ttf"); if (style == Typeface.BOLD) { super.setTypeface(boldTypeface/*, -1*/); } else { super.setTypeface(normalTypeface/*, -1*/); } } } }
внедрить новый макет
adapter= new ArrayAdapter <String>(Menu.this,R.layout.custom_spinner, list);
источник
Это продолжение моего предыдущего ответа: https://stackoverflow.com/a/51100507/787399
Шаг 1: объявите item_spinner.xml
<?xml version="1.0" encoding="utf-8"?> <com.my_package.custom_views.FontTextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/tv_spinner" style="@style/App_TextViewStyleSmall" android:layout_gravity="start|bottom" android:layout_marginLeft="@dimen/dp_5" android:layout_marginStart="@dimen/dp_5" android:ellipsize="marquee" android:gravity="start|bottom" android:padding="@dimen/dp_10" android:singleLine="true" android:textAlignment="inherit" /> <!--declared in layout: item_spinner.xml--> <!-- removed attributes: android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="@color/text_grey_light" android:textSize="@dimen/sp_14" --> <!--style="?android:attr/spinnerItemStyle"-->
шаг 2: объявить item_spinner_dropdown.xml:
<?xml version="1.0" encoding="utf-8"?> <com.my_package.custom_views.FontTextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/tv_spinner" style="@style/App_TextViewStyleSmall" android:layout_gravity="start|bottom" android:layout_marginLeft="@dimen/dp_5" android:layout_marginStart="@dimen/dp_5" android:ellipsize="marquee" android:gravity="start|bottom" android:padding="@dimen/dp_10" android:singleLine="true" /> <!--declared in layout: item_spinner_dropdown.xml --> <!--removed: ?android:attr/dropdownListPreferredItemHeight--> <!--style="?android:attr/spinnerDropDownItemStyle"-->
Шаг 3: Используйте счетчик в макете:
<LinearLayout android:id="@+id/ll_my_spinner" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/fet_bus_entity" android:layout_marginTop="@dimen/dp_12" android:orientation="horizontal"> <com.my_package.custom_views.FontTextView style="@style/App_TextViewStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="start|bottom" android:gravity="start|bottom" android:text="@string/are_you_a" /> <Spinner android:id="@+id/sp_my_spinner" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/dp_5" android:layout_marginStart="@dimen/dp_5" android:layout_gravity="end|bottom" android:spinnerMode="dropdown" /> </LinearLayout>
[Примечание: идентификатор FontTextView одинаков как в макетах, так и в элементе счетчика и в раскрывающемся списке]
Шаг 4: используйте его в Activity / Fragment:
private void initSpinnerBusinessType(View rootView) { String[] ar_dd_bus_type = getResources().getStringArray(R.array.ar_dd_bus_type); List<String> lst_bus_type = Arrays.asList(ar_dd_bus_type); ArrayList<String> ar_bus_type = new ArrayList<>(lst_bus_type); //== ArrayAdapter<String> adapter = new ArrayAdapter<>(activity, R.layout.item_spinner, R.id.tv_spinner, ar_bus_type); adapter.setDropDownViewResource(R.layout .item_spinner_dropdown); //========= Spinner sp_my_spinner= rootView.findViewById(R.id.sp_my_spinner); sp_my_spinner.setAdapter(adapter); }
[для дальнейших указаний см. мой другой пост: https://stackoverflow.com/a/51077569/787399 и https://stackoverflow.com/a/22164007/787399 ]
источник
Пожалуйста, следуйте базовой настройке FontTextView, FontEditView, FontRadioButton, FontCheckBox и FontButton.
[Точный ответ после просмотра этого руководства см. На странице https://stackoverflow.com/a/51113022/787399 ]
Используйте пользовательский FontTextView в макете элемента ArrayAdapter, например:
public class FontEditText extends AppCompatEditText { // private String FONT = "fonts/roboto_regular.ttf"; public FontEditText(Context context) { super(context, null); // setFontFromAsset(context, null, R.style.DefaultFontTextView); // FONT = getContext().getString(R.string.font_roboto_regular); } public FontEditText(Context context, @Nullable AttributeSet attrs) { super(context, attrs); setFontFromAsset(context, attrs, R.attr.fetFontStyle); } public FontEditText(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); setFontFromAsset(context, attrs, defStyleAttr); } private void setFontFromAsset(Context context, AttributeSet attrs, int defStyle) { BaseActivity activity = (BaseActivity)((MyApplication) context.getApplicationContext()).getCurrentActivity(); FontAndLocaleManager fontAndLocaleManager = activity.getFontAndLocaleManager(); fontAndLocaleManager.setFontFromAsset(this, R.styleable.FontEditText, R.styleable.FontEditText_fetFontFace, attrs, defStyle); } }
используйте код:
public void setFontFromAsset(View view, int[] resViewStyleable, int resStyleableViewFontFace, AttributeSet attrs, int defStyle) { String strFont = null; Typeface tfFontFace = null; String strButton = FontButton.class.getCanonicalName(), strTextView = FontTextView.class.getCanonicalName(), strEditText = FontEditText.class.getCanonicalName(), strView = view.getClass().getCanonicalName(); try { if (view.isInEditMode()) { return; } //R.string.font_roboto_regular strFont = context.getString(R.string.font_roboto_regular); tfFontFace = Typeface.createFromAsset(context.getAssets(), strFont); //AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes //R.styleable.FontButton TypedArray a = context.obtainStyledAttributes(attrs, resViewStyleable, defStyle, 0); //R.styleable.FontButton_btFontFace String derivedFont = a.getString(resStyleableViewFontFace); a.recycle(); //== try { if (derivedFont != null) { Typeface derivedFontFace = Typeface.createFromAsset(context.getAssets(), derivedFont); if (strView.equals(strButton)) { ((FontButton) view).setTypeface(derivedFontFace); } else if (strView.equals(strTextView)) { ((FontTextView) view).setTypeface(derivedFontFace); } else if (strView.equals(strEditText)) { ((FontEditText) view).setTypeface(derivedFontFace); } return; } } catch (Exception e) { e.printStackTrace(); } } catch (Exception e) { e.printStackTrace(); } try { if (strFont != null && tfFontFace != null) { if (strView.equals(strButton)) { ((FontButton) view).setTypeface(tfFontFace); } else if (strView.equals(strTextView)) { ((FontTextView) view).setTypeface(tfFontFace); } else if (strView.equals(strEditText)) { ((FontEditText) view).setTypeface(tfFontFace); } } } catch (Exception e) { e.printStackTrace(); } }
Опишите стиль и атрибуты в соответствующих xmls:
<!--FontTextView--> <declare-styleable name="FontTextViewStyle"> <!-- Style of the FontTextView. --> <attr name="ftvFontStyle" format="reference"/> </declare-styleable> <declare-styleable name="FontTextView"> <!-- Font face of FontTextView. --> <attr name="ftvFontFace" format="reference"/> </declare-styleable>
а также
<!--FontTextView--> <style name="StyledFontTextView" parent="@android:style/Theme.Light"> <item name="ftvFontStyle">@style/DefaultFontTextView</item> </style> <style name="DefaultFontTextView"> <item name="ftvFontFace">@string/font_roboto_regular</item> </style>
определите еще несколько стилей:
<style name="App_TextViewStyle" parent="@android:style/Widget.TextView"> <item name="android:textColor">@color/text_grey</item> <item name="android:textSize">@dimen/sp_20</item> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">wrap_content</item> </style> <style name="App_TextViewStyleMedium" parent="@android:style/Widget.TextView"> <item name="android:textColor">@color/text_hint</item> <item name="android:textSize">@dimen/sp_18</item> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">wrap_content</item> </style> <style name="App_TextViewStyleSmall" parent="@android:style/Widget.TextView"> <item name="android:textColor">@color/text_grey_light</item> <item name="android:textSize">@dimen/sp_14</item> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">wrap_content</item> </style>
упомяните шрифты в вашем strings.xml:
... <string name="font_roboto_regular">fonts/roboto_regular.ttf</string> ...
и использовать в макетах для экономии кода и времени:
<com.mypackage.custom_views.FontTextView style="@style/App_TextViewStyleMedium" android:layout_gravity="start|bottom" android:gravity="start|bottom" app:fetFontFace="@string/font_roboto_regular" android:text="@string/are_you_a" />
На уровне Android 16 и выше все это упрощается, потому что теперь вы можете хранить TTF и другие ресурсы шрифтов в
/res/font
папке, а не в активах. Это удаляет большинство пользовательских классов, стилей и атрибутов, см.:Ресурсы шрифтов в Android
Удачного кодирования со стилем !! :-)
источник
Ребята, я нашел отличное решение, оборачиваю оригинальный адаптер хелпером вроде
Используйте этот класс SpinnerViewHelper и счастливого программирования с Android
new SpinnerViewHelper((Spinner)view.findViewById(R.id.labelSurveyNumber),(parent, v, position, id) -> UrduFontHelper.set(v));
Используется лямбда-выражение.
источник