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

问题

目标是显示一个具有挤出效果的文本,它也应该使用不同的语言。看起来像这样的东西。

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

解决方案

允许创建一个扩展的类appcompattextview.并覆盖ondraw()方法

class upludeeffecttext @jvmoverloads构造函数(上下文:context,attrs:attributeetet?= null,defstyleattr:int = 0):appcompattextview(上下文,attrs,defstyleattr){.........覆盖有趣的ondraw(画布:画布:画布?){super.ondraw(canvas)}}

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

class upludeeffecttext @jvmoverloads构造函数(上下文:attracts= 10覆盖有趣的ondraw(画布:画布?){super.ondraw(canvas)paint.color = intrudecolor画布?.save()val dx = 1f val dy = -1f //通过换x和y多次绘制相同的文本(i在0...Extrudedepth){画布?.translate(dx,dy)layout.draw(canvas)} canvas?.restore()}}

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

dx = 1f向右移动

dx = -1f向左移动

dy = 1f向下移动

dy = -1f向上移动

`canvas.save()`帮助我们在我们执行任何操作之前保存画布的状态。画布?.restore()恢复画布的状态。布局是另一个财产textview.用于显示文本
现在,当我们完成绘制挤出效果时,我们需要使用原始颜色绘制我们的文本,然后向文本添加笔划。

val strokewidth = 2f val strokecolor = color.red override fun ondraw(画布:画布?){super.ondraw(canvas)val原装textcolor = paint.color paint.color = intrudecolor anvas?.save().......。//绘制原始颜色paint.setColor(OriginalTextColor)layout.draw(Canvas)//在文本paint.setcolor(strokecolor)paint.style = paint.style.stroke paint.strokewintth = strokewidth layout.draw(帆布)帆布?.restore()}

这一切都很伟大,但仍有一点问题。我们正在从左下角到右上角的对角线绘制挤出效果。“挤压事业”越大,“TextView”的风险越高,将从界限中绘制出来,并在右边和顶部边缘看。为了解决这个问题,我们需要为视图添加一些额外的填充,以确保没有任何切断。

class upludeeffecttext @jvmoverloads构造函数(上下文:attress,attributeet?= null,defstyleattr:int = 0):appcompattextview(上下文,attrs,defstyleattr){init {addExtrapaddattrattrattrattrattration {setPadding(PaddingStart,Paddingtop + extrudepth,Paddingend + extrudepth,PaddingBottom)}}}

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

Val Config = Context.Resources.Configuration val ISRTL = Config.LayoutDirection == View.Layout_Direction_RTL

我们可以使用ISRTL.标志以确定挤出方向(在我们的情况下,我们将从RTL的右下角绘制到左上角),并在哪个边缘设置填充。

class upludeeffecttext @jvmoverloads构造函数(上下文:attracts,attributeet?= null,defstyleattr:int = 0):appcompattextview(上下文,attrs,defstyleattr){override fun Ondraw(画布:画布?){super.ondraw(画布)。.... //基于RTL Val DX = IF(ISRTL)-1f else 1f val dy = -1f //在换x和y位置的多次绘制相同的文本(i在0..extrudepth){Canvas?.translate(dx,dy)layout.draw(canvas)} ......}私人乐趣addExtrapaddding(){val config = context.resources.configuration isrtl = config.layoutdirection == view.layout_direction_rtl如果(ISRTL.) { // in Right to left the start is on the right setPadding( paddingEnd + extrudeDepth, paddingTop + extrudeDepth, paddingStart, paddingBottom ) } else { setPadding( paddingStart, paddingTop + extrudeDepth, paddingEnd + extrudeDepth, paddingBottom ) } } }

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

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

188博金宝电子体育频道android {... buildtypes {debug {pseudolocalesenabled true}}

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

现在我们有一个textview.具有与任何语言配合使用的挤出效果,并且可以很容易地定位。我们仍然可以使用所有的textview.像Textize,FontFamily,LettersPacing,Linespacing,Gravity等的属性,并且它不会破坏我们的挤出效果。我们还可以为更多自定义添加一些自定义属性。以下是所有代码在一起和之前和之后

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

Class extrudeeffectText @jvmoverloads构造函数(上下文:attrations,attributeset?= null,defstyleattr:int = 0):appcompattextview(上下文,attrs,defstyleattr){var extrudepth:int = 0 set(value){field = value addextrapaddding()refreeshlayout()} var intrudecolor:int = color.black set(值){field = value refreshlayout()} var scrokewidth:float = 0f set(value){field = value freeheshlayout()} var strokecolor:int = color.whiteset(value){field = value freeheshlayout()} private var iSrtl:boolean = false init {addExtrapadding()context.theme.obtainstyledattributes(attrs,r.stylable.extrudefect,0,0).apply {try {extrudedepth = getint(r.stylable.extrudeeffect_extrudepth,0)extrudecolor = getColor(r.stylable.extrudefefect_extrudecolor,color.black)strokewidth = getfloat(r.stylable.extrudefect_textstrokewidth,0f)strokecolor = getColor(r.stylable.extrudefefect_textstrokecolor,color.white)}最后{Recycle()}}覆盖有趣的OnDraw(画布:可以vas?){super.ondraw(canvas)//保存原文颜色,因为textpaint会更改为绘制阴影和scroke val原装textcolor = paint.color paint.color = extrudecolor画布?.save()//考虑到填充集在视图val translatex = if(isrtl)paddingish evate yours paddingstart canvas?.translate(translatex.tofloat(),paddingtop.tofloat())//基于RTL Val DX = IF(ISRTL)-1f else 1f val更改提取方向dy = -1f //通过转换x和y位置多次绘制相同的文本(i在0..extrudepth){canvas?.translate(dx,dy)layout.draw(画布)} //绘制原始颜色的文本paint.setColor(OricalTextColor)layout.draw(画布)//添加文本Paint.setColor(strokecolor)paint.style = paint.style.stroke paint.strokewintth = strokewidth layout.draw(画布)//恢复原稿State Paint.Color = OriginalTextColor Paint.Style = Paint.Style.Fill?。restore()}私人有趣addExtrapadding(){val config = context.resources.configuration isRtl = config.layoutDirection == View.LAYOUT_DIRECTION_RTL if (isRtl) { // in Right to left the start is on the right setPadding( paddingEnd + extrudeDepth, paddingTop + extrudeDepth, paddingStart, paddingBottom ) } else { setPadding( paddingStart, paddingTop + extrudeDepth, paddingEnd + extrudeDepth, paddingBottom ) } } private fun refreshLayout() { invalidate() requestLayout() } } // src/main/res/values/attrs.xml       // in layout