如何以编程方式将字体自定义字体设置为 Spinner 文本?
Posted
技术标签:
【中文标题】如何以编程方式将字体自定义字体设置为 Spinner 文本?【英文标题】:How to set font custom font to Spinner text programmatically? 【发布时间】:2011-07-25 21:43:52 【问题描述】:我的资产文件夹中有一个 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_
android:layout_
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 类时,它不会提出此建议。
【问题讨论】:
非常感谢朋友。。经过长时间的努力,我找到了这个。这终于拯救了我的一天 感谢您添加答案! 非常好的问题... 【参考方案1】:这对我有用(使用来自 CommonsWare's 和 gsanllorente's 答案的想法):
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;
如果您和我一样,最初使用 ArrayAdapter.createFromResource()
和数组资源(如 Spinner documentation)填充 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()
获取上下文并将适配器分配给其中的微调器(微调器布局与我的整个应用程序一致)
这对我有很大帮助。谢谢...@Jonik【参考方案2】:
您可以通过自己的自定义SpinnerAdapter
、getView()
和getDropDownView()
应用字体。
【讨论】:
我用我最新的问题编辑了我的问题,你能告诉我我做错了什么吗? Tnx @DixieFlatline:你需要为android.view.ViewGroup
添加一个导入,大概【参考方案3】:
如果你在另一个文件中实现你的适配器,你可以从适配器的构造函数中访问“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,尽管 ID 是正确的。此代码中的其他一些问题:1)getView()
中缺少 return 语句,2)未使用的字段 recurso
,3)一些样式问题,例如命名变量 spinner_text
(应该是 spinnerText
)。 Here's what worked for me.【参考方案4】:
试试这个创建自定义 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_
android:layout_
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);
【讨论】:
我认为这样会更好,因为你不必在适配器上弄脏你的手,你可以在你的应用程序的任何其他地方使用这个 CustomTextview。【参考方案5】:这是我之前回答的延续:https://***.com/a/51100507/787399
出于兼容性原因,您可以使用样式和自定义 针对 Android 中的小部件的类。虽然高于安卓水平 15、新增
/res/font
资源文件夹:Font Resources in Android
第 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_
android:layout_
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_
android:layout_
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_
android:layout_
android:layout_gravity="start|bottom"
android:gravity="start|bottom"
android:text="@string/are_you_a" />
<Spinner
android:id="@+id/sp_my_spinner"
android:layout_
android:layout_
android:layout_marginLeft="@dimen/dp_5"
android:layout_marginStart="@dimen/dp_5"
android:layout_gravity="end|bottom"
android:spinnerMode="dropdown" />
</LinearLayout>
[注意:FontTextView 的 id 在布局、微调项和下拉项中都是相同的]
第 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://***.com/a/51077569/787399 和 https://***.com/a/22164007/787399]
【讨论】:
【参考方案6】:请按照 FontTextView、FontEditView、FontRadioButton、FontCheckBox 和 FontButton 的基本定制。
[ 确切答案,看过本指南后,请看: https://***.com/a/51113022/787399]
在ArrayAdapter项布局中使用自定义FontTextView,像这样:
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();
在各自的 xml 中描述样式和属性:
<!--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
文件夹中,而不是资产中。这会删除大部分自定义类、样式和属性,请参阅:
Font Resources in Android
快乐的编码风格! :-)
【讨论】:
长答案,但一次工作。然后,这是一个可重复使用的。【参考方案7】:伙计们,我找到了一个很棒的解决方案,我用助手包装了原始适配器
使用此类 SpinnerViewHelper 并愉快地使用 Android 进行编程
new SpinnerViewHelper((Spinner)view.findViewById(R.id.labelSurveyNumber),(parent, v, position, id) -> UrduFontHelper.set(v));
使用了 Lambda 表达式。
【讨论】:
以上是关于如何以编程方式将字体自定义字体设置为 Spinner 文本?的主要内容,如果未能解决你的问题,请参考以下文章
以编程方式将 UILabel 字体设置为用户定义的运行时属性