Michelle's Home

回望来时的路。。。


  • 首页

  • 归档

  • 分类

  • 标签

  • 关于

  • 搜索

android 学习笔记(1)—TextView 文本样式

发表于 2019-03-22 | 分类于 Android , TextView

在Android中,TextView中文本的样式
在Android中,TextView是一个非常重要的控件,用于显示文本,通常我们会在XML文件中使用android:text属性来设置文本,也可以在代码中通过调用textView.setText()方法来设置文本,这种方式设置的文本样式默认是使用robot字体的normal样式。有时因为需求,我们需要改变字体的样式,包括颜色、缩放、可点击性,删除线等,有时需要对TextView中所有的文本设置样式,有时只是需要更改其中某些字体的样式,下面针对不同的需要做下总结。

粗体

整体加粗

可以使用XML属性、styles、或者themes,也可以使用Spans或HTML标签
在XML文件中使用android:textStyle="bold"属性

1
2
3
4
5
6
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="32sp"
android:textStyle="bold"
/>

或在代码中修改Typeface

1
myTextView.setTypeface(Typeface.create(myTextView.getTypeface(),Typeface.BOLD));

或在代码中使用StyleSpan

1
2
3
SpannableString string = new SpannableString("Text with\nBullet point");
string.setSpan(new StyleSpan(Typeface.BOLD),0,string.length(),Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
myTextView.setText(string);

或在代码中使用HTML标签

1
2
String textBold = "<b>text bold</b>";
myTextView.setText(Html.fromHtml(textBold));

部分加粗

可以用HTML标签、Spans或者直接重写TextView的onDraw()方法绘制text。

单一样式 —— 单一样式用于整个TextView中文本

单一样式我们可以通过使用XML属性、styles、或者themes

使用XML属性

例如:将字体设为粗体,我们可以使用android:textStyle="bold"

1
2
3
4
5
6
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="32sp"
android:textStyle="bold"
/>

多种样式 —— 多种样式用于文本、字符或片段等

多种样式可以通过HTML标签、Spans或者自定TextView中text的绘制

使用HTML标签

Java:

1
2
String text = "My text <ul><li>bullet one</li><li>bullet two</li></ul>";
myTextView.setText(Html.fromHtml(text));

Kotlin:

1
2
val text = "My text <ul><li>bullet one</li><li>bullet two</li></ul>"
myTextView.text = Html.fromHtml(text)

使用Spans

Spans允许你实现多种样式的text
例如:您可以利用BulletSpan自定义文本边距、项目符号和项目符号颜色之间的间隙。从android p开始,你甚至可以设置BulletSpan的半径。
Java

1
2
3
4
5
6
7
8
9
10
SpannableString spannable = new SpannableString("My text \nbullet one\nbullet two");
spannable.setSpan(
new BulletSpan(gapWidthPx, accentColor),
/* start index */ 9, /* end index */ 18,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spannable.setSpan(
new BulletSpan(gapWidthPx, accentColor),
/* start index */ 20, /* end index */ spannable.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
myTextView.setText(spannable);

Kotlin

1
2
3
4
5
6
7
8
9
10
val spannable = SpannableString("My text \nbullet one\nbullet two")
spannable.setSpan(
BulletSpan(gapWidthPx, accentColor),
/* start index */ 9, /* end index */ 18,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
spannable.setSpan(
BulletSpan(gapWidthPx, accentColor),
/* start index */ 20, /* end index */ spannable.length,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
myTextView.text = spannable

在Android P中甚至可以设置BulletSpan的半径:
Java code:

1
2
3
4
5
6
7
8
9
10
SpannableString spannable = new SpannableString("My text \nbullet one\nbullet two");
spannable.setSpan(
new BulletSpan(gapWidthPx, accentColor),
/* start index */ 9, /* end index */ 18,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spannable.setSpan(
new BulletSpan(gapWidthPx, accentColor, bulletRadius),
/* start index */ 20, /* end index */ spannable.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
myTextView.setText(spannable);

Kotlin code:
Kotlin

1
2
3
4
5
6
7
8
9
10
val spannable = SpannableString("My text \nbullet one\nbullet two")
spannable.setSpan(
BulletSpan(gapWidthPx, accentColor),
/* start index */ 9, /* end index */ 18,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
spannable.setSpan(
BulletSpan(gapWidthPx, accentColor, bulletRadius),
/* start index */ 20, /* end index */ spannable.length,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
myTextView.text = spannable

单一样式和多种样式可以混合使用

1
2
3
4
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/blue"/>
1
2
3
4
5
6
val spannable = SpannableString(“Text styling”)
spannable.setSpan(
ForegroundColorSpan(Color.PINK),
0, 4,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
myTextView.text = spannable

非常好的文章
https://medium.com/androiddevelopers/spantastic-text-styling-with-spans-17b0c16b4568

一点想法

发表于 2019-03-21

       最近一直忙着整理之前堆积的东西,发现并没有想象中的那么顺利,感觉整理一个点很容易,可是想要扩展到面,把相关的内容都整理出来,还是非常不容易的,这让我突然想到,在开发产品的过程中,往往会发现,产品经理对某些功能定义不全,导致开发不下去的情况,或许并不是不认真或者不专业,只是在那个当下,他只能想到那么多了。现在的我也遇到了同样的问题,写博客时,当我想把所有的情况都考虑进去的时候,发现脑子一下不够用了,似乎怎么想,都觉得不够全面。不知道是不是整理方式的问题,如果不能大而全,那么点对点可好?采用遇到问题解决问题的方式,嗯,决定试试。

Android plurals源码分析

发表于 2019-03-21 | 分类于 Android , 源码分析

由于不同语言对数量的语法规则不同,所以引入了plurals这种资源,plurals中quality的值有zero,one,two,few,many,和other,当时我们发现,有时我们定义的有些quality在调用是并不能得到预期的结果,这是因为不是所有的语言都能支持所有的quality值,而在我们调用getQuantityString(@PluralsRes int id, int quantity)方式时,系统是怎么返回的,需要从源码着手去分析。

我们从Android 8.0中frameworks/base/core/java/android/content/res/Resources.java的代码入手:

阅读全文 »

android String用法汇总

发表于 2019-03-20 | 分类于 Android

[toc]

改变部分字符的颜色

TextSpannable

html

有时需要对TextView中的text做局部的样式改变,加粗或斜体等,由于Android可以兼容部分html标签,故可以在res/strings.xml文件中借助html标签去实现,常用的标签如下:

加粗字体
斜体字体
给字体加下划线
\n 换行
\u0020表示空格
\u2026表示省略号

例如我们要给部分字体加粗,可以这样写:

1
<string name="text_part_style">加粗<b>重点</b>两个字</string>

然后直接在xml文件中引用

1
2
3
4
5
6
7
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/abril_fatface"
android:text="@string/text_part_style"
android:textSize="30sp" />

也可以在代码中引用:

1
textView.setText(Html.fromHtml("Hello <b>World</b>,<font size=\"3\" color=\"red\">AnalysisXmlActivty!</font>"));

设置类似于html那样的效果。

有时Android不能很好的区分标签中的<和>,故需要用它们的实体代替&lt;代表<,&gt;代表>.
例如设置a>b,
html常用实体:
|显示结果 |描述 |实体名称 |实体编号|
|—|—|—|—|
| |空格 |\  |\ |
|< |小于号 |\< |\<|
|> |大于号 |\> |\>|
|& |和号 |\& |\&|
|” |引号 |\" |\"|
|’ |撇号 |\' (IE不支持) |\'|
|¢ |分(cent) |\¢ |\¢|
|£ |镑(pound) |\£ |\£
|¥ |元(yen) |\¥ |\¥
|€ |欧元(euro) |\€ |\€
|§ |小节 |\§ |\§
|© |版权(copyright) |\© |\©
|® |注册商标 |\® |\®
|™ |商标 |\™ |\™
|× |乘号 |\× |\×
|÷ |除号 |\÷ |\÷

占位符

Android支持以占位符的方式,定义字符串。
这里要先了解%n$d、%n$f和%n$s是和含义
举个例子:

1
<string name="old">%1$s今年%2$d岁了</string>

%1$s: %1表示第一个可替换的变量 $s表示变量是string型
%2$d: %2表示第二个可替换的变量 $d 表示变量是整型
还有一个$f表示的是浮点型,目前android支持者三种类型的变量
如果想要在变量前加空格的,拿整型举例:

1
<string name="old">%1$s今年%2$md岁了</string>

其中$md 中的m代表m个空格,其它的同理;
那么,如何在中使用%号呢?
有两个办法:

  1. 用%%来表示1个%,和转意符号 \ 的用法相同
  2. 如果你的字符串不需要格式化,可以在你的<string 标签上增加一个属性:formatted=”false”例如 <string name="test" formatted="false">% test %</string>即可。

在使用该字符串时,可以在运行时动态替换占位符号,例如:

1
2
String str =getResources().getString(R.string.old_);
String string = str.format(str, "李小姐",27);

xliff

什么是xliff,参见百度百科

在写xliff之前 一定要引用xliff的命名空间,不引用xliff是无效的:

1
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">

xliff例子:

1
<string name="old_"><xliff:g id="name">%1$s</xliff:g>今年<xliff:g id="age">%2$d</xliff:g>岁了</string>

代码中:

1
2
String str =getResources().getString(R.string.old_);
String string = str.format(str, "李小姐",27);

输出结果:

1
李小姐今年27岁了

xliff文件和普通文件的区别

1、具有命名空间xmlns:xliff=”urn:oasis:names:tc:xliff:document:1.2”,这个必须要有。
2、在标签中含有xliff:g标签。
xliff:g标签介绍:
属性id可以随便命名
属性example表示举例说明,可以省略
%n$ms:代表输出的是字符串,n代表是第几个参数,设置m的值可以在输出之前放置空格
%n$md:代表输出的是整数,n代表是第几个参数,设置m的值可以在输出之前放置空格,也可以设为0m,在输出之前放置m个0
%n$mf:代表输出的是浮点数,n代表是第几个参数,设置m的值可以控制小数位数,如m=2.2时,输出格式为00.00

plurals

由于不同的语言对数量的语法规定有不同的规则。 例如一小时是one hour, 两小时是two hours。 为了解决后缀的问题,Android引入了plurals 这种资源。

android对数量(单复数)进行处理 它支持zero,one,two,few,many,和other;可以理解plurals为一个数量集合的简单资源,它可以通过name的属性来访问(不是xml文件的name)。这样,你可以把plural资源和其他的简单资源一样放在同一个xml 文件里面,在同一个节点下。
quality的值和描述:

值 描述
zero 当前语言需要特别对待0
one 当前语言需要特别对待1
two 当前语言需要特别对待2
few 当前语言需要特别对待few/small,也就是小数量的
many 当前语言需要特别对待many/large,也就是大数量的
other 当前语言没有要求对特定资源进行特殊对待

在工程的values下建一个xml文件 ,或者放在strings文件里也可以:

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="utf-8"?>
<resources >
<plurals name="hour">
<item quantity="zero"> zero hour </item>
<item quantity="one"> one hour </item>
<item quantity="other"> %d hours </item>
</plurals>

</resources>

name 就是plurals的属性名,其中plurals的Item可以是一个或多个,这就是一个完整的plurals资源文件;(%d代表的是整数)
下面是如何使用资源文件:

1
2
Resources res = getResources();
String string = res.getQuantityString(R.plurals.hour,2,8);

其中,2对应的是quantity=“other”,8对应的是other中占位符的值,也就是几小时。

getQuantityString()方法介绍:

/**

 * Returns the string necessary for grammatically correct pluralization
 * of the given resource ID for the given quantity.
 * Note that the string is selected based solely on grammatical necessity,
 * and that such rules differ between languages. Do not assume you know which string
 * will be returned for a given quantity. See
 * <a href="{@docRoot}guide/topics/resources/string-resource.html#Plurals">String Resources</a>
 * for more detail.
 *
 * @param id The desired resource identifier, as generated by the aapt
 *           tool. This integer encodes the package, type, and resource
 *           entry. The value 0 is an invalid identifier.
 * @param quantity The number used to get the correct string for the current language's
 *           plural rules.
 *
 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
 *
 * @return String The string data associated with the resource,
 * stripped of styled text information.
 */
@NonNull
**public String getQuantityString(@PluralsRes int id, int quantity) throws NotFoundException {
    return getQuantityText(id, quantity).toString();
}**
/**
 * Formats the string necessary for grammatically correct pluralization
 * of the given resource ID for the given quantity, using the given arguments.
 * Note that the string is selected based solely on grammatical necessity,
 * and that such rules differ between languages. Do not assume you know which string
 * will be returned for a given quantity. See
 * <a href="{@docRoot}guide/topics/resources/string-resource.html#Plurals">String Resources</a>
 * for more detail.
 *
 * <p>Substitution of format arguments works as if using
 * {@link java.util.Formatter} and {@link java.lang.String#format}.
 * The resulting string will be stripped of any styled text information.
 *
 * @param id The desired resource identifier, as generated by the aapt
 *           tool. This integer encodes the package, type, and resource
 *           entry. The value 0 is an invalid identifier.
 * @param quantity The number used to get the correct string for the current language's
 *           plural rules.
 * @param formatArgs The format arguments that will be used for substitution.
 *
 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
 *
 * @return String The string data associated with the resource,
 * stripped of styled text information.
 */
@NonNull
**public String getQuantityString(@PluralsRes int id, int quantity, Object... formatArgs)
        throws NotFoundException {
}**

int id,是我们在string.xml里面写的plurals资源的id;int quantity,是数量的意思,也就是我们取具体item的判断依据,Object… formatArgs参数是占位符的值

但是当我们把quantity的值设为0时,程序并没有像我们期望的那样显示zero hour,这是因为程序运行的时候,具体取的那个item,是取决于当前语言对单复数等形式的定义的。具体可以参见Android plurals源码分析;

如果非要在英文中特殊处理zero的情况,可以借助下面要讲的MessageFormat

MessageFormat

1.在strings.xml文件中定义hour如下:

1
<string name="hour">{0,choice,0#zero hour|1#One hour|1<{0} hours}</string>

2.在代码中引用hour

1
String hour = MessageFormat.format(getSherlockActivity().getString(R.string.hour), number)

更多的例子:
例1:

1
2
3
4
5
6
7
8
9
10
11
12
double[] filelimits = {0,1,2};
String[] filepart = {"are no files","is one file","are {2} files"};
ChoiceFormat fileform = new ChoiceFormat(filelimits, filepart);
Format[] testFormats = {fileform, null, NumberFormat.getInstance()};
MessageFormat pattform = new MessageFormat("There {0} on {1}");
pattform.setFormats(testFormats);
Object[] testArgs = {null, "ADisk", null};
for (int i = 0; i < 4; ++i) {
testArgs[0] = new Integer(i);
testArgs[2] = testArgs[0];
System.out.println(pattform.format(testArgs));
}

例2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
ChoiceFormat fmt = new ChoiceFormat(
"-1#is negative| 0#is zero or fraction | 1#is one |1.0<is 1+ |2#is two |2<is more than 2.");
System.out.println("Formatter Pattern : " + fmt.toPattern());

System.out.println("Format with -INF : " + fmt.format(Double.NEGATIVE_INFINITY));
System.out.println("Format with -1.0 : " + fmt.format(-1.0));
System.out.println("Format with 0 : " + fmt.format(0));
System.out.println("Format with 0.9 : " + fmt.format(0.9));
System.out.println("Format with 1.0 : " + fmt.format(1));
System.out.println("Format with 1.5 : " + fmt.format(1.5));
System.out.println("Format with 2 : " + fmt.format(2));
System.out.println("Format with 2.1 : " + fmt.format(2.1));
System.out.println("Format with NaN : " + fmt.format(Double.NaN));
System.out.println("Format with +INF : " + fmt.format(Double.POSITIVE_INFINITY));

关于MessageFormat的详细用法可以参见Java的API:MessageFormat或Java中MessageFormat的使用
更多string的用法,可以参见android String 资源 你所不知道的

android 字体加载流程分析

发表于 2019-03-20 | 分类于 Android , 源码分析

https://blog.csdn.net/a282255307/article/details/76870441
文章中分析的和Android O源码并不匹配,需要具体看看5.0和8.0源码之间的差别
https://blog.csdn.net/xiao_nian/article/details/60766475

android Font,Typeface,FontFamily之间的差别

发表于 2019-03-20 | 分类于 Android , 字体

背景

Font和Typeface经常被错误的互换使用。然而它们之间却是有一些不同的。

Font

大约在十五世纪,当打印机手工打字时,他们必须从一个巨大的盒子里拿出真正的金属字母、数字和符号。如下图:
图1
图1

这个收集字符的容器可以被叫做Font
现在,font指的是包含各种字体的数字文件,而不是一盒金属字体。

阅读全文 »

android O 在xml文件中引用字体

发表于 2019-03-20 | 分类于 Android , 字体

背景

Android 8.0(API 26 Oreo)引入了可以在xml文件中配置字体的新功能,在这之前,如果要改变字体样式,需要将字体文件放入Asset文件中,并在代码代码中通过getAsset()的方式,动态改变字体的样式。如果想在4.1(API 16)及更高的版本上使用该功能,需要引用Support Library 26.

Android O在xml文件中配置字体

本地字体

直接在xml文件中引用字体

1.在res/文件夹下创建font文件夹,并将字体文件拷到font文件夹下,假设字体文件为:myfont.otf
2.在xml文件中通过android:fontFamily属性引用自定义的字体

1
2
3
4
5
6
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text View"
android:fontFamily="@font/myfont"/>

注:font文件名字只能由小写字母a-z,0-9,下划线_组成。

阅读全文 »

Markdown教程

发表于 2019-03-20 | 更新于 2019-10-09 | 分类于 Markdown

基础篇


标题

1
2
3
4
5
6
# 一级标题
## 二级标题
### 三级标题
#### 四级标题
##### 五级标题
###### 六级标题

一级标题

二级标题

三级标题

四级标题

五级标题
六级标题
阅读全文 »

android字体详解

发表于 2019-03-18 | 更新于 2019-10-09 | 分类于 Android , 字体

最近了解了一下字体,发现彻底解释明白这件事情真的很不容易。

android:fontWeight属性

值是int,范围是1~1000,系统默认字体的weight是400
常用属性值和通常的名字对应关系如下
| Value | Common weight name |
|——-|——————–|
|100 |thin
|200 |Extra Light(Ultra Light)
|300 |Light
|400 |Normal(Regular、Book、Roman)
|500 |Medium
|600 |Semi Bold(Demi Bold)
|700 |Bold
|800 |Extra Bold(Ultra Bold)
|900 |Black (Heavy)

注:为什么说是通常呢?因为在有些字库下是有差异的,比如在Adobe Typekit字库中对字重描述的划分列表中,它列出Heavy指的是800而不是900。另外,在我们日常使用的Photoshop和Sketch里面,Ultra Light是100,而Thin是200。

阅读全文 »

git子项目错误汇总

发表于 2019-01-17 | 更新于 2019-10-09 | 分类于 git

错误收集

clone代码报错-fatal: reference is not a tree: 85e5c187f03d9c10889dfbddd8adf4d87af2c71f

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ git clone --recursive -b src https://github.com/jnnjiang/jnnjiang.github.io.git blog
Cloning into 'blog6'...
remote: Enumerating objects: 803, done.
remote: Counting objects: 100% (803/803), done.
remote: Compressing objects: 100% (351/351), done.
remote: Total 803 (delta 289), reused 763 (delta 251), pack-reused 0
Receiving objects: 100% (803/803), 4.58 MiB | 661.00 KiB/s, done.
Resolving deltas: 100% (289/289), done.
Checking connectivity... done.
Submodule 'themes/next' (https://github.com/jnnjiang/hexo-theme-next.git) registered for path 'themes/next'
Cloning into 'themes/next'...
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 5364 (delta 0), reused 0 (delta 0), pack-reused 5363
Receiving objects: 100% (5364/5364), 5.09 MiB | 812.00 KiB/s, done.
Resolving deltas: 100% (3293/3293), done.
Checking connectivity... done.
fatal: reference is not a tree: 85e5c187f03d9c10889dfbddd8adf4d87af2c71f
Unable to checkout '85e5c187f03d9c10889dfbddd8adf4d87af2c71f' in submodule path 'themes/next'
阅读全文 »
12
江纳纳

江纳纳

一直忙于奔跑的孩纸,现在需要回头数数自己留下的脚印了。。。

15 日志
8 分类
9 标签
RSS
GitHub
© 2019 江纳纳
由 Hexo 强力驱动 v3.9.0
|
主题 – NexT.Pisces v6.7.0