我想在我的Android应用程序中使用Font Awesome的图标集。我有一些TextView
来设置这些图标。我不想使用任何png图像。我的Textview就是这样 - >
<TextView
android:id="@+id/userLogin"
android:text="Login Now"
android:clickable="true"
android:onClick="login"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
不,我想在“立即登录”文本前添加一个图标。怎么做?
答案 0 :(得分:12)
您可以关注此answer。
首先从here下载fontawesome.ttf。并将文件放在 asset / fontawesome.ttf 。
中然后创建一个FontAwesome
类,它实际上代表FontAwesome
的文本视图。
public class FontAwesome extends TextView {
public FontAwesome(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public FontAwesome(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public FontAwesome(Context context) {
super(context);
init();
}
private void init() {
//Font name should not contain "/".
Typeface tf = Typeface.createFromAsset(getContext().getAssets(),
"fontawesome.ttf");
setTypeface(tf);
}
}
现在您可以根据需要使用Fontawesome类,并按照cheatsheet.获取图标的Unicode。
所以,你的textview会是这样的。
<PACKAGE_NAME.Fontawesome
android:id="@+id/userLogin"
android:text=" Login Now"
android:clickable="true"
android:onClick="login"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
答案 1 :(得分:6)
以下是要遵循的步骤:
public class FontManager {
public static final String ROOT = "fonts/",
FONTAWESOME = ROOT + "fontawesome-webfont.ttf";
public static Typeface getTypeface(Context context, String font) {
return Typeface.createFromAsset(context.getAssets(), font);
}
}
4。现在使用下面的代码
对您的textview使用字体真棒Typeface iconFont = FontManager.getTypeface(getApplicationContext(), FontManager.FONTAWESOME);
tvIcon1 = (TextView) findViewById(R.id.tvIcon1);
tvIcon2 = (TextView) findViewById(R.id.tvIcon2);
tvIcon3 = (TextView) findViewById(R.id.tvIcon3);
tvIcon1.setTypeface(iconFont);
tvIcon2.setTypeface(iconFont);
tvIcon3.setTypeface(iconFont);
您可以在我的博文here中获取完整的源代码。
答案 2 :(得分:4)
您可以使用FontAwesome,只需在String.xml中声明
<resources>
<string name="fa_icon_areachart"></string>
<string name="fa_icon_piechart"></string>
<string name="fa_icon_linechart"></string>
</resources>
答案 3 :(得分:2)
您还可以从Font Awesome导入原始矢量图像,并在Android Studio中创建新的Vector Asset的帮助下将它们作为drawable导入:
转到已安装Font Awesome
的文件夹..... / fontawesome-PRO-版本#/高级选项/原始SVG
在那里你会找到4个文件夹:品牌,灯光,常规和实体。
所有图标均可在这4个文件夹中作为分隔的矢量图像使用
要导入图标,请转到资源,右键单击并选择新建 - &gt;矢量资产。将打开一个对话框。选择“本地文件”作为选项,然后选择要导入的矢量图像(路径)。将从图像文件中减去图像的名称。
然后您可以通过简单地使用复合TextView解决您的问题,如下所示:
<TextView
android:drawableStart="@drawable/my_imported_fontawesome_login_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Login Now"
android:gravity="center_vertical"/>
此解决方案的一个优点是,您只需要导入您真正需要的图标,而不需要完整或更多字体的开销,因为图标分为4种字体。
答案 4 :(得分:1)
由于在我的Android项目中没有真正舒适的方法来包含FontAwesome,
我创建了一个Github Repository,该帮助使用FontAwesome和 Kotlin而非Java 。
存储库可帮助您动态在FontAwesome类型(solid
,regular
和brands
)之间进行切换。动态示例(see code):
我从这里的所有答案中学到了很多东西,所以谢谢大家!我希望这个答案对您也有帮助!
答案 5 :(得分:1)
如果有人想以编程方式分配字体值,那么我就是这样做的。 创建资产文件夹(如果不存在),然后将ttf文件放入文件夹
Typeface type = Typeface.createFromAsset(getContext().getAssets(), "fonts/fa_solid_900.ttf");
tvHeart.setTypeface(type);
tvHeart.setText(Html.fromHtml(""));
答案 6 :(得分:1)
首先创建您的字体资源目录
下载 FontAwesome TTF 文件
在 font 文件夹中添加您的字体文件
创建您的图标字典:
strings_fa_brands.xml
strings_fa_regular.xml
strings_fa_solid.xml
<resources>
<string name="fa_regular_sun"></string>
<string name="fa_regular_surprise"></string>
<string name="fa_regular_thumbs_up"></string>
</resources>
在布局 XML 文件中,将 text
和 fontFamily
属性设置为您想要的图标
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/fa_regular_thumbs_up"
android:fontFamily="@font/fa-regular-400"/>
答案 7 :(得分:0)
使用Typeface,您可以直接通过代码
进行设置 mTypeFace = FontCache.get("font/GFont.ttf", getActivity());
mButtonQkView.setTypeface(mTypeFace);
mButtonQkView.setText(String.valueOf((char) 0xe907));
要将字体图标设置为Leftdrawable,首先使用TextDrawable类从字体图标生成drawable
TextDrawable gIcon = new TextDrawable(this);
gIcon.setTextSize(TypedValue.COMPLEX_UNIT_DIP, size);
gIcon.setTextAlign(Layout.Alignment.ALIGN_CENTER);
gIcon.setTypeface(FontCache.get(getString(R.string.icomoon), this));
gIcon.setText(String.valueOf((char) 0xe907));
gIcon.setTextColor(getResources().getColor(color));
并将其设置为左侧可绘制
mButtonQkView.setCompoundDrawablesWithIntrinsicBounds(gIcon, null, null, null);
TextDrawable类的代码
public class TextDrawable extends Drawable {
/* Platform XML constants for typeface */
private static final int SANS = 1;
private static final int SERIF = 2;
private static final int MONOSPACE = 3;
/* Attribute lists to pull default values from the current theme */
private static final int[] themeAttributes = {
android.R.attr.textAppearance
};
private static final int[] appearanceAttributes = {
android.R.attr.textSize,
android.R.attr.typeface,
android.R.attr.textStyle,
android.R.attr.textColor
};
/* Resources for scaling values to the given device */
private Resources mResources;
/* Paint to hold most drawing primitives for the text */
private TextPaint mTextPaint;
/* Layout is used to measure and draw the text */
private StaticLayout mTextLayout;
/* Alignment of the text inside its bounds */
private Layout.Alignment mTextAlignment = Layout.Alignment.ALIGN_NORMAL;
/* Optional path on which to draw the text */
private Path mTextPath;
/* Stateful text color list */
private ColorStateList mTextColors;
/* Container for the bounds to be reported to widgets */
private Rect mTextBounds;
/* Text string to draw */
private CharSequence mText = "";
public TextDrawable(Context context) {
super();
//Used to load and scale resource items
mResources = context.getResources();
//Definition of this drawables size
mTextBounds = new Rect();
//Paint to use for the text
mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.density = mResources.getDisplayMetrics().density;
mTextPaint.setDither(true);
int textSize = 15;
ColorStateList textColor = null;
int styleIndex = -1;
int typefaceIndex = -1;
//Set default parameters from the current theme
TypedArray a = context.getTheme().obtainStyledAttributes(themeAttributes);
int appearanceId = a.getResourceId(0, -1);
a.recycle();
TypedArray ap = null;
if (appearanceId != -1) {
ap = context.obtainStyledAttributes(appearanceId, appearanceAttributes);
}
if (ap != null) {
for (int i = 0; i < ap.getIndexCount(); i++) {
int attr = ap.getIndex(i);
switch (attr) {
case 0: //Text Size
textSize = a.getDimensionPixelSize(attr, textSize);
break;
case 1: //Typeface
typefaceIndex = a.getInt(attr, typefaceIndex);
break;
case 2: //Text Style
styleIndex = a.getInt(attr, styleIndex);
break;
case 3: //Text Color
textColor = a.getColorStateList(attr);
break;
default:
break;
}
}
ap.recycle();
}
setTextColor(textColor != null ? textColor : ColorStateList.valueOf(0xFF000000));
setRawTextSize(textSize);
Typeface tf = null;
switch (typefaceIndex) {
case SANS:
tf = Typeface.SANS_SERIF;
break;
case SERIF:
tf = Typeface.SERIF;
break;
case MONOSPACE:
tf = Typeface.MONOSPACE;
break;
}
setTypeface(tf, styleIndex);
}
/**
* Return the text currently being displayed
*/
public CharSequence getText() {
return mText;
}
/**
* Set the text that will be displayed
* @param text Text to display
*/
public void setText(CharSequence text) {
if (text == null) text = "";
mText = text;
measureContent();
}
/**
* Return the current text size, in pixels
*/
public float getTextSize() {
return mTextPaint.getTextSize();
}
/**
* Set the text size. The value will be interpreted in "sp" units
* @param size Text size value, in sp
*/
public void setTextSize(float size) {
setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
}
/**
* Set the text size, using the supplied complex units
* @param unit Units for the text size, such as dp or sp
* @param size Text size value
*/
public void setTextSize(int unit, float size) {
float dimension = TypedValue.applyDimension(unit, size,
mResources.getDisplayMetrics());
setRawTextSize(dimension);
}
/*
* Set the text size, in raw pixels
*/
private void setRawTextSize(float size) {
if (size != mTextPaint.getTextSize()) {
mTextPaint.setTextSize(size);
measureContent();
}
}
/**
* Return the horizontal stretch factor of the text
*/
public float getTextScaleX() {
return mTextPaint.getTextScaleX();
}
/**
* Set the horizontal stretch factor of the text
* @param size Text scale factor
*/
public void setTextScaleX(float size) {
if (size != mTextPaint.getTextScaleX()) {
mTextPaint.setTextScaleX(size);
measureContent();
}
}
/**
* Return the current text alignment setting
*/
public Layout.Alignment getTextAlign() {
return mTextAlignment;
}
/**
* Set the text alignment. The alignment itself is based on the text layout direction.
* For LTR text NORMAL is left aligned and OPPOSITE is right aligned.
* For RTL text, those alignments are reversed.
* @param align Text alignment value. Should be set to one of:
*
* {@link Layout.Alignment#ALIGN_NORMAL},
* {@link Layout.Alignment#ALIGN_NORMAL},
* {@link Layout.Alignment#ALIGN_OPPOSITE}.
*/
public void setTextAlign(Layout.Alignment align) {
if (mTextAlignment != align) {
mTextAlignment = align;
measureContent();
}
}
/**
* Sets the typeface and style in which the text should be displayed,
* and turns on the fake bold and italic bits in the Paint if the
* Typeface that you provided does not have all the bits in the
* style that you specified.
*
*/
private void setTypeface(Typeface tf, int style) {
if (style > 0) {
if (tf == null) {
tf = Typeface.defaultFromStyle(style);
} else {
tf = Typeface.create(tf, style);
}
setTypeface(tf);
// now compute what (if any) algorithmic styling is needed
int typefaceStyle = tf != null ? tf.getStyle() : 0;
int need = style & ~typefaceStyle;
mTextPaint.setFakeBoldText((need & Typeface.BOLD) != 0);
mTextPaint.setTextSkewX((need & Typeface.ITALIC) != 0 ? -0.25f : 0);
} else {
mTextPaint.setFakeBoldText(false);
mTextPaint.setTextSkewX(0);
setTypeface(tf);
}
}
/**
* Return the current typeface and style that the Paint
* using for display.
*/
public Typeface getTypeface() {
return mTextPaint.getTypeface();
}
/**
* Sets the typeface and style in which the text should be displayed.
* Note that not all Typeface families actually have bold and italic
* variants, so you may need to use
* {@link #setTypeface(Typeface, int)} to get the appearance
* that you actually want.
*/
public void setTypeface(Typeface tf) {
if (mTextPaint.getTypeface() != tf) {
mTextPaint.setTypeface(tf);
measureContent();
}
}
/**
* Set a single text color for all states
* @param color Color value such as {@link Color#WHITE} or {@link Color#argb(int, int, int, int)}
*/
public void setTextColor(int color) {
setTextColor(ColorStateList.valueOf(color));
}
/**
* Set the text color as a state list
* @param colorStateList ColorStateList of text colors, such as inflated from an R.color resource
*/
private void setTextColor(ColorStateList colorStateList) {
mTextColors = colorStateList;
updateTextColors(getState());
}
/**
* Optional Path object on which to draw the text. If this is set,
* TextDrawable cannot properly measure the bounds this drawable will need.
* You must call {@link #setBounds(int, int, int, int) setBounds()} before
* applying this TextDrawable to any View.
*
* Calling this method with <code>null</code> will remove any Path currently attached.
*/
public void setTextPath(Path path) {
if (mTextPath != path) {
mTextPath = path;
measureContent();
}
}
/**
* Internal method to take measurements of the current contents and apply
* the correct bounds when possible.
*/
private void measureContent() {
//If drawing to a path, we cannot measure intrinsic bounds
//We must resly on setBounds being called externally
if (mTextPath != null) {
//Clear any previous measurement
mTextLayout = null;
mTextBounds.setEmpty();
} else {
//Measure text bounds
double desired = Math.ceil(Layout.getDesiredWidth(mText, mTextPaint));
mTextLayout = new StaticLayout(mText, mTextPaint, (int) desired,
mTextAlignment, 1.0f, 0.0f, false);
mTextBounds.set(0, 0, mTextLayout.getWidth(), mTextLayout.getHeight());
}
//We may need to be redrawn
invalidateSelf();
}
/**
* Internal method to apply the correct text color based on the drawable's state
*/
private boolean updateTextColors(int[] stateSet) {
int newColor = mTextColors.getColorForState(stateSet, Color.WHITE);
if (mTextPaint.getColor() != newColor) {
mTextPaint.setColor(newColor);
return true;
}
return false;
}
@Override
protected void onBoundsChange(Rect bounds) {
//Update the internal bounds in response to any external requests
mTextBounds.set(bounds);
}
@Override
public boolean isStateful() {
/*
* The drawable's ability to represent state is based on
* the text color list set
*/
return mTextColors.isStateful();
}
@Override
protected boolean onStateChange(int[] state) {
//Upon state changes, grab the correct text color
return updateTextColors(state);
}
@Override
public int getIntrinsicHeight() {
//Return the vertical bounds measured, or -1 if none
if (mTextBounds.isEmpty()) {
return -1;
} else {
return (mTextBounds.bottom - mTextBounds.top);
}
}
@Override
public int getIntrinsicWidth() {
//Return the horizontal bounds measured, or -1 if none
if (mTextBounds.isEmpty()) {
return -1;
} else {
return (mTextBounds.right - mTextBounds.left);
}
}
@Override
public void draw(@NonNull Canvas canvas) {
final Rect bounds = getBounds();
final int count = canvas.save();
canvas.translate(bounds.left, bounds.top);
if (mTextPath == null) {
//Allow the layout to draw the text
mTextLayout.draw(canvas);
} else {
//Draw directly on the canvas using the supplied path
canvas.drawTextOnPath(mText.toString(), mTextPath, 0, 0, mTextPaint);
}
canvas.restoreToCount(count);
}
@Override
public void setAlpha(int alpha) {
if (mTextPaint.getAlpha() != alpha) {
mTextPaint.setAlpha(alpha);
}
}
@Override
public int getOpacity() {
return mTextPaint.getAlpha();
}
@Override
public void setColorFilter(ColorFilter cf) {
if (mTextPaint.getColorFilter() != cf) {
mTextPaint.setColorFilter(cf);
}
}
}
答案 8 :(得分:0)
类似的代码,但是变化很小。
使用AppCompatTextView,因为当您使用TextView时,会收到如下警告:
此自定义视图应改为扩展android.support.v7.widget.AppCompatTextView
因此,请使用AppCompatTextView。如果使用AppCompatTextView而不是TextView会更好:
import android.graphics.Typeface;
import android.support.v7.widget.AppCompatTextView;
import android.content.Context;
import android.util.AttributeSet;
public class FontAwesome extends AppCompatTextView{
public FontAwesome(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public FontAwesome(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public FontAwesome(Context context) {
super(context);
init();
}
private void init() {
//Font name should not contain "/".
Typeface tf = Typeface.createFromAsset(getContext().getAssets(),
"fontawesome.ttf");
setTypeface(tf);
}
}
答案 9 :(得分:0)
以前的情况还可以,但是可以想象您需要基于从api获得的数据动态生成的菜单项。 在获取页面模型之前,我们现在不应该在每个项目中使用确切的图标。 当然,我们可以像前面所示那样将所有FA图标放入String资源,但是也可以按名称插入FA图标
开始吧
添加FA字体库: 实施'com.mikepenz:fontawesome-typeface:5.9.0.0-kotlin@aar'
添加ext lib图标:
实施“ com.mikepenz:iconics-core:4.0.2”
执行验证码(kotlin):
//add class property in your activity
private lateinit var navView: NavigationView
//find your navigation view on activity onCreate
navView = findViewById(R.id.event_details_nav_view)
//call your updateNavigation(pages) function when you received data with menu items. i.e. Page is a data object with Id, Name, faIcon (it's name)
//add function where we create menu items based on pages model
fun updateNavigation(pages: List<Page>) {
pages.forEach {
navView.menu.add(0, it.id, 0, it.name)
.apply {
IconsHelper.getFontAwesomeIcon(
this,
name,
24,
R.color.nav_drawer_item_icon_color_default
).let {
menuItem.icon = it
}
}
}
}
所有的魔力都在IconHelper中,让我们开始吧
//添加IconHelper.kt并将其粘贴在那里
import android.content.Context
import com.mikepenz.iconics.Iconics.findFont
import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.utils.colorInt
import com.mikepenz.iconics.utils.sizeDp
object IconsHelper {
private const val defaultIconName = "faw_question_circle"
fun getFontAwesomeIcon(context: Context, name: String, size: Int, color: Int): IconicsDrawable {
return when(name.isEmpty()) {
true ->
getIcon(defaultIconName, size, color, context)
false -> {
normalizeIconName(name)
.let {
when(iconExists(context, it)) {
true ->
getIcon(it, size, color, context)
false ->
getIcon(IconsHelper.defaultIconName, size, color, context)
}
}
}
}
}
private fun getIcon(name: String, size: Int, color: Int, context: Context): IconicsDrawable {
return IconicsDrawable(context, name)
.apply {
sizeDp(size)
colorInt(color)
}
}
private fun normalizeIconName(name: String): String {
name
.replaceFirst("fa", "faw")
.replace("-", "_")
.let {
return when(it.contains("sliders")) {
true ->
"faw_sliders_h"
false ->
it
}
}
}
private fun iconExists(context: Context, icon: String): Boolean {
try {
findFont(icon.substring(0, 3), context)
.let {
it!!.getIcon(icon)
}
return true
} catch (e: Exception) {
print(e)
}
return false
}
}
p.s。看一下normalizeIconName()函数,也许您不需要它。
答案 10 :(得分:0)
首先,在 build.gradle 中包含 fontawesome 并同步您的项目。
dependencies {
// font awesome
implementation 'info.androidhive:fontawesome:0.0.5'
}
使用它?
<info.androidhive.fontawesome.FontTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/fa_calendar_check_solid"
android:textColor="@color/icon_color"
android:textSize="@dimen/icon_size"
app:solid_icon="true" />
solid_icon:
要显示实心图标,请将此值设置为 true。
brand_icon:
要显示品牌图标,请将此值设置为 true。