188博金宝电子体育频道Android通过自定义TextView效果改进了本地化

我们已经开始使我们的应用程序更加国际化的过程友好。通常需要删除所有硬铺设的串并用参考替换它们string.xml只需要单独这样做将是翻译项目中的一个很好的起点。当然,在翻译的应用程序可以释放之前需要解决一堆不同的问题,如字符串格式,字符串串联,复数,图像中的文本等。
图像中的文本是我们在我们的翻译项目期间在Okcupid面临的问题。188bet金宝搏官网在某些情况下,图像中的文本可以只是一个更富有表现力的不同图像替换,并且不需要任何单词。但有时我们需要为文本添加一些特殊效果,以便它脱颖而出,也可以正确地定位。此帖子将显示应用于文本的挤出效果的示例,然后将其集成到应用程序中作为图像以及如何用常规替换textview.这很容易翻译。

这个问题

目标是显示一个具有挤压效果的文本,并且它还应该适用于不同的语言。就像这样。

一个解决方案是使用带有挤出效果的自定义字体,但这与不同语言的字符不合适。自定义字体必须指定应用字体时每个字符的样子。如果字体不处理该字符,则Android的默认字体将仅在该字符上使用。188博金宝电子体育频道此外,我们应该记住,一些亚洲语言没有传统的字母表,并将自定义字体应用于这些语言可能很困难。习俗textview.在我们的例子中,在文本后面绘制挤压效果是一个更好、更快、更可扩展的解决方案。我们对自定义也有更多的控制textview.它允许我们调整颜色、挤压方向和挤压深度。

解决方案

让我们创建一个延伸的类AppCompatTextView和覆盖onDraw ()方法

@JvmOverloads构造函数(
背景:背景下,
景色:attributeset?= null,
defStyleAttr: Int = 0
): AppCompatTextView(context, attrs, defStyleAttr) {
.........
覆盖有趣的ondraw(画布:画布?){super.ondraw(canvas)}

这里的想法是多次绘制相同的文本,每次绘制文本时移动x和y位置,以产生挤出效果。首先,我们会得到textview.描绘对象。这是一个定义要绘制的文本样式的对象,它负责更改文本大小、文本颜色、字体等。我们将使用一个油漆对象,改变文本颜色(所有其他文本属性将被保留),并只是绘制文本多次。

@JvmOverloads构造函数(
背景:背景下,
景色:attributeset?= null,
defStyleAttr: Int = 0
): AppCompatTextView(context, attrs, defStyleAttr) {
.....
val intrudecolor =颜色。黑色的
val extrudeDepth = 10

覆盖有趣的ondraw(画布:画布?){
Super.ondraw(画布)

油漆颜色= intrudecolor.
画布?.save()

val dx = 1f
val dy = -1f

//在换档x和y位置多次绘制相同的文本
for(我在0...ExtrudeDepth){
帆布?.translate(dx,dy)
布局.Draw(画布)

帆布? .restore ()

dxdy指定在这种情况下我们想要移动的距离是1像素。+/-迹象表明移动的方向。

dx = 1f向右移动

Dx = -1f向左移动

Dy = 1f向下移动

Dy = -1f向上移动

canvas.save ()帮助我们在进行任何操作(如翻译)之前保存画布的状态。帆布? .restore ()恢复画布的状态。布局是另一个特性textview.用于显示文本
现在,当我们完成了拉伸效果的绘制,我们需要用原始颜色绘制文本,然后给文本添加一个笔触。

val strokeWidth = 2f
val strokecolor =颜色。红色的

覆盖有趣的ondraw(画布:画布?){
Super.ondraw(画布)

val originalTextColor =油漆颜色
油漆
颜色= intrudecolor.
画布?.save()

........

//绘制原始颜色的文本
油漆
.setColor (originalTextColor)
布局.Draw(画布)

//在文本周围添加描边
油漆
.setcolor(strokecolor)
油漆风格= Paint.Style.STROKE
油漆strokeWidth= strokeWidth
布局.Draw(画布)

帆布? .restore ()

这一切都很伟大,但仍有一点问题。我们正在从左下角到右上角的对角线绘制挤出效果。更大的extrudeDepth风险越高textview.将被画出边界,在右边和顶部边缘看起来被切断了。为了解决这个问题,我们需要向视图添加一些额外的填充,以确保没有任何东西被截断。

@JvmOverloads构造函数(
背景:背景下,
景色:attributeset?= null,
defStyleAttr: Int = 0
): AppCompatTextView(context, attrs, defStyleAttr) {

init {
addExtraPadding ()


.....

私人乐趣addExtrapaddding(){
setPadding (
paddingStart
paddingTop+ extrudeDepth,
paddingEnd+ extrudeDepth,
paddingbottom.


我们还应该考虑到一些语言有从右到左的文本方向,所以我们需要添加更多的逻辑来处理这种情况。首先,让我们确定布局方向。这可以使用下面的代码片段来完成

Val Config = Context.Resources.Configuration
Val ISRTL = CONFIG.LAYOUTDirection == View.layout_direction_rtl

我们可以使用isRtl标记来确定挤压的方向(在本例中,RTL将从右下角到左上角绘制),以及在哪条边上设置填充。

@JvmOverloads构造函数(
背景:背景下,
景色:attributeset?= null,
defStyleAttr: Int = 0
): AppCompatTextView(context, attrs, defStyleAttr) {

覆盖有趣的ondraw(画布:画布?){
Super.ondraw(画布)
.....
//基于RTL改变挤出方向
val dx = if(isrtl)-1f else 1f
val dy = -1f

//在换档x和y位置多次绘制相同的文本
for(我在0...ExtrudeDepth){
帆布?.translate(dx,dy)
布局.Draw(画布)

......



私人乐趣addExtrapaddding(){
Val Config =.上下文资源配置
isRtl =配置。layoutDirection== view.layout_direction_rtl.
如果(isRtl) {
//在右向左开始是在右边
setPadding (
paddingEnd+ extrudeDepth,
paddingTop+ extrudeDepth,
paddingStart
paddingbottom.

其他}{
setPadding (
paddingStart
paddingTop+ extrudeDepth,
paddingEnd+ extrudeDepth,
paddingbottom.



这里有一些不同语言的例子。

我们还可以用Android伪本地化测试视图(更多信息)188博金宝电子体育频道这里),这在任何国际化项目中都非常有用。伪本地化将模拟应用程序有翻译的场景。通过添加

188博金宝电子体育频道android {
...
buildtypes {
调试{
pseudoLocalesEnabled真实

并将语言更改为英语(XA),串string.xml将以奇怪的字符更改为字符串。这些角色看起来像英文字母,但也有一些额外的符号。通过连接占位符文本将增加每个字符串的长度。硬码字符串不会改变。伪本地化允许开发人员找到与翻译相关的任何UI问题,并在添加了实际翻译之前发现任何硬编码字符串。

现在我们有一个textview.使用任何语言都可以使用的挤出效果,并且可以很容易地本地化。我们还可以用所有的textview.属性,如textSize, fontFamily,字母间距,行间距,重力等,它不会破坏我们的挤出效果。我们还可以添加一些自定义属性来进行更多的自定义。这里是所有的代码在一起和前后比较

想从事像这样很酷的项目吗?我们正在招聘Android工188博金宝电子体育频道程师!应用在今天https://www.188bet金宝搏官网okcupid.com/careers

左边是ImageView,右边是TextView
@JvmOverloads构造函数(
背景:背景下,
景色:attributeset?= null,
defStyleAttr: Int = 0
): AppCompatTextView(context, attrs, defStyleAttr) {

var extrudepth:int = 0
设定值) {
=值
addExtraPadding ()
refreshLayout ()

var extrudeColor: Int =颜色。黑色的
设定值) {
=值
refreshLayout ()


var strokeWidth:浮动= 0f
设定值) {
=值
refreshLayout ()

var strokeColor: Int =颜色。白色
设定值) {
=值
refreshLayout ()

私有var iSrtl:boolean = false

init {
addExtraPadding ()

context.theme.obtainstyldattributes(
景象,
R.styleable.ExtrudeEffect,
0,0
)。申请

尝试 {
extrudeDepth = getInt (R.styleable。ExtrudeEffect_extrudeDepth, 0)
(R.styleable extrudeColor =色鬼。ExtrudeEffect_extrudeColor Color.BLACK)
strokeWidth = getFloat (R.styleable。ExtrudeEffect_textStrokeWidth 0 f)
strokecolor = getColor(r.stylable.extrudeffect_textstrokecolor,color.white)
最后}{
回收()




覆盖有趣的ondraw(画布:画布?){
Super.ondraw(画布)

//保存原始文本颜色,因为TextPaint会更改为画影和笔划
val originalTextColor = paint.color
油漆。颜色= intrudecolor.

画布?.save()

//考虑视图上的填充设置
val translatex = if(isrtl)paddingise every addingstart
帆布?.translate(translatex.tofloat(),paddingtop.tofloat())

//基于RTL改变挤出方向
val dx = if(isrtl)-1f else 1f
val dy = -1f

//在换档x和y位置多次绘制相同的文本
for(我在0...ExtrudeDepth){
帆布?.translate(dx,dy)
layout.draw(画布)


//绘制原始颜色的文本
paint.setColor (originalTextColor)
layout.draw(画布)

//在文本周围添加描边
paint.setColor (strokeColor)
paint.style = paint.style.stroke.
paint.strokewidth = strokewidth.
layout.draw(画布)

//恢复原始状态
油漆。颜色= originalTextColor
油漆。风格= Paint.Style.FILL
帆布? .restore ()


私人乐趣addExtrapaddding(){
Val Config = Context.Resources.Configuration
isRtl =配置。布局Direction == View.LAYOUT_DIRECTION_RTL
如果(isRtl) {
//在右向左开始是在右边
setPadding (
Paddingend + extrudepth,
Paddingtop + inturedepth,
paddingStart,
paddingbottom.

其他}{
setPadding (
paddingStart,
Paddingtop + inturedepth,
Paddingend + extrudepth,
paddingbottom.




private fun refreshLayout() {
无效()
requestLayout ()


/ / src / main / res / / attrs.xml值
<声明 - Deactereable name =“extrudeeffect”>
= < attr name = " extrudeDepth "格式"整" / >
= < attr name = " extrudeColor "格式"参考|色" / >




/ /布局
< com.example.shadoweffect.ExtrudeEffectText
188博金宝电子体育频道android: layout_width = " wrap_content "
188博金宝电子体育频道android: layout_height = " wrap_content "
188博金宝电子体育频道android: textSize = " 20 sp”
188博金宝电子体育频道Android:TextColor =“#000”
188博金宝电子体育频道android:文本=“Hello world !”
应用:extrudeDepth =“7”
应用程序:extrudecolor =“@ color / coloraccent”
应用程序:TextStrokWidth =“2”
应用程序:textstrokecolor =“@ color /黄色”
188博金宝电子体育频道android: fontFamily = " @font / gt_america_black " / >

最初发表在118bet金博宝 2020年8月28日。

188bet金宝搏官网OkCupid科技博客

阅读来自工程团队的故事,这些故事每天连接着数百万人

188bet金宝搏官网OkCupid科技博客

阅读来自工程团队的故事,这些故事每天连接着数百万人

安东尼岛

写的

188博金宝电子体育频道Android开发者@OkCupid188bet金宝搏官网

188bet金宝搏官网OkCupid科技博客

阅读来自工程团队的故事,这些故事每天连接着数百万人