用力抱一下APP国际化

2023-11-11


APP国际化,说的直白应该也叫本土化或者本地化,如果你的应用上线到谷歌应用市场,那么应该做好本地化的支持,用来支持不同语言及地区的风俗习惯,当然也要结合公司拓展的海外市场需要,那么对于一款应用,至少应该做到多语言和多布局的支持。  
最近忙于阿拉伯语适配工作,自己便去搜罗和整理了一些,也踩过很多的坑,如果你的APP在做国际化支持,那么推荐你阅读下,这也许是篇值得参考的文章,若对你有所帮助的话,那就反手点个大大的赞哇!  


国际化资源


资源是指文本字符串、布局、声音、图形和你的Android 应用需要的任何其他静态数据。

  • res/drawable/(必需的目录,包含至少一个图形文件,用作 Google Play 上的应用图标)
  • res/layout/(必需的目录,包含定义默认布局的 XML 文件)
  • res/anim/(如果您有任何 res/anim-<qualifiers> 文件夹,则为必需)
  • res/xml/(如果您有任何 res/xml-<qualifiers> 文件夹,则为必需)
  • res/raw/(如果您有任何 res/raw-<qualifiers> 文件夹,则为必需)

当你的应用支持国际化,那么必须要为这些资源至少设置一套默认的资源,当应用在您没有提供特定于该语言区域的文本的语言区域中运行时,Android就会去加载一些默认的资源,所以默认资源很重要。通常默认资源被认为是你的app内部使用最多的资源,需要注意的是,在资源的加载过程中,语言区域几乎总是处于优先地位,是被系统优先加载的。  
除了语言区域可以作为本地化资源的区分之外,Android系统也为我们提供了两种布局方向区分,即ldrtlldltr,ldrtl 是指“布局方向从右到左”。ldltr 是指“布局方向从左到右”(默认的隐式值)。举个栗子:若我们使用阿拉伯语,则layout-ar是被优先加载的,而layout-ldrtl优先级则没有语言区域ar的优先级高,如果我们使用的是其他的RTL语言,譬如说波斯语,那么就会去加载layout-ldrtl下的资源。  

res/
    layout/
        main.xml (Default layout)
    layout-ar/
        main.xml (Specific layout for Arabic)
    layout-ldrtl/
        main.xml (Any "right-to-left" language, except
                  for Arabic, because the "ar" language qualifier
                  has a higher precedence.)


针对于其他资源,譬如drawable图片、anim动画、raw静态资源和xml的本地化同样可以通过语言区域作为划分,也可以通过布局方向作为区分,所以对于本地化来说我们可以结合多种方式灵活运用他们。AS创建Resource File或者Resource Directory系统已经提供选择语言和一些特殊的区域。如下图:


国际化字符串

 

  •  拒绝任何形式的硬编码字符串,所有字符串应该通过string.xml资源文件加载,便于本地化
 ../values-en/strings.xml 英语
 <string name="my_topic_btn">My Topic</string>
 ../values-ar/strings.xml 阿拉伯语
 <string name="my_topic_btn">موضوعي</string>
 ../values-fr/strings.xml 法语
 <string name="my_topic_btn">mon sujet</string>
 ../values-hi/strings.xml 印度语
 <string name = "my_topic_btn"> मेरा विषय</string>

 

  • 对于不应该被翻译的代码、占位符、特殊符号或名称,应该进行标记,不做翻译,可以使用 <xliff:g> 占位符标记,但是务必提供指定ID来说明用途
// 占位符最好不要被翻译,特别是阿拉伯语
 <string name="admission">
   تطبي <xliff:g id="xliff_admission">%1$s</xliff:g> للقبول
 </string>
// url连接地址不要做翻译
<string name="web_url">
  Visit us at <xliff:g id="main_web_url">http://my/app/home.html</xliff:g>
</string>
// 用户名不要做翻译
<string name="user_name">
  username: <xliff:g id="name">Herry</xliff:g>
</string>

LTR与RTL布局


我们一般的阅读习惯都是从左往右,即LTR(left to right),这是Android系统的默认支持的布局方式,除此之外,当`targetSdkVersion` 设为 17 或更高版本,则系统会激活和使用各种 RTL API,所谓的RTL即从右往左的布局,用来支持中东国家的阅读习惯,常见的语种有阿拉伯语、波斯语、希伯来语等等。  
Android控件已经大部分支持RTL布局了,但是一些自定义的控件需要自己做适配。通常情况只需要在`<application>`标签增加 `android:supportsRtl="true"`,就可启用RTL API来支持RTL布局,具体的适配方案后面会详细讲到。 

RTL布局预览


Android Studio默认已经为我们提供了对应语言区域的预览,打开预览的界面Locale for Preview,默认会显示Default(en-us),使用的布局为LTR,若我们使用到了阿拉伯语等RTL语言,预览可以选择对应的ar语或者RTL语言,如下图:  


伪语言区域


Android系统平台默认提供了两种伪语言区域,英语 (XA)和AR (XB),分别表示从左到右 (LTR) 和从右到左 (RTL) 显示的语言。即使我们不使用 RTL 语言,伪语言区域也可以帮助我们创建应用的 RTL 版本。 部分定制手机可能不存在这两种伪语言区域。   


英语 (XA):在基本英文界面文本中添加拉丁语重音符号,通过添加不带重音符号的文本扩展原始文本,并用方括号将每个消息单元括起来,以使扩展文本中的潜在问题暴露出来。潜在的问题可能是布局损坏和消息语法错误,表现为一个句子被分成多个部分,显示为多条由括号括住的消息。   
AR (XB):将从左到右显示的原始消息的文本方向设为从右到左的方向,它会颠倒原始消息中字符的顺序。  


要使用 Android 伪语言区域,必须运行 Android 4.3(API 级别 18)或更高版本,并在设备上启用开发者选项。在 Android Studio 中,可以通过以下配置添加到 build.gradle 文件来为特定应用启用伪语言区域.  

 android {
      ...
      buildTypes {
        debug {
          pseudoLocalesEnabled true
        }
      }


RTL布局,阿拉伯语的适配

 

  • 一些简要的属性及API
android:layoutDirection  the direction of layout drawing 设置组件的布局排列方向
android:textDirection the direction of the text 设置组件的文字排列方向
android:textAlignment  the alignment of the text 设置文字的对齐方式
getLayoutDirectionFromLocale()  the layout direction for a given Locale 获取指定地区的惯用布局方式
  •  启用系统的RTL支持,这个只需要在清单文件增加相关配置即可
<application  
 android:supportsRtl="true">
</application>

 

  • 全局替换xxxLeft/xxxRight为xxxStart/xxxEnd,可通过AS中选中Refactor->Add RTL Support

 

  • TextView和EditText控件的全局适配,可以通过主题theme指定全局的样式  
 <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- 阿拉伯语言适配-->
        <item name="android:textViewStyle">@style/TextViewStyle.TextDirection</item>
        <item name="editTextStyle">@style/EditTextStyle.Alignment</item>
    </style>

    <!--阿拉伯语适配文本-->
    <style name="TextViewStyle.RTL" parent="android:Widget.TextView">
        <item name="android:textDirection">locale</item>
    </style>

    <!--阿拉伯语适配编辑框-->
    <style name="EditTextStyle.RTL" parent="@android:style/Widget.EditText">
        <item name="android:textAlignment">viewStart</item>
        <item name="android:gravity">start|center_vertical</item>
        <item name="android:textDirection">locale</item>
    </style>

 

  • 适配图片,部分比较敏感的图片,比如箭头一些方向性的图标,需要创建翻转镜像。  

第一种方式:通过适配drawable资源目录,放置对应的翻转后的图片资源,比如:drawable-ldrtl-xhdpi,但是这样可能会增加额外的包体积大小。

..res
  ..drawable-ldrtl-xhdpi
    ..icon_logo.png
  ..drawable-ldrtl-xxhdpi
    ..icon_logo.png


第二种方式:如果是svg矢量图或者自定义的drawable,可以通过设置`android:autoMirrored="true"`属性,当系统检测到RTL布局时,会自动创建图片镜像。若是ImageView可以通过Drawable对象来创建镜像。 

// svg创建镜像
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="20dp"
    android:height="20dp"
    android:autoMirrored="true"
    android:viewportWidth="20"
    android:viewportHeight="20">
  <path
      android:pathData="M5.5,10l3,4l7,-8"
      android:strokeLineCap="round"/>
</vector>

// ImageView创建镜像
 Drawable drawable = ContextCompat.getDrawable(context, R.drawable.logo);
 // 设置所有的返回按钮支持RTL布局
 drawable.setAutoMirrored(true);
 imageView.setImageDrawable(drawable);

 

  • 仅设置`center_vertical`属性,最好能带上start/end等属性。
  • 动态设置setPadding应使用setPaddingRelative代替
  • 动态设置setCompoundDrawables应使用setCompoundDrawablesRelative代替,同样getCompoundDrawables应使用getCompoundDrawablesRelative代替
  • 动态设置setCompoundDrawablesWithIntrinsicBounds应使用setCompoundDrawablesRelativeWithIntrinsicBounds代替
  • leftMargin /.rightMargin 使用 setMarginStart/setMarginEnd代替
  • 某些自定义控件包含TextView或者Editext时,如果全局主题适配失效,那么最好需要xml中重写style
  • 自定义控件关于获取getX横坐标距离计算相关逻辑,需要动态判断是否是RTL布局来重新计算坐标和距离
// 当前布局是否为RTL布局,true RTL/false LTR
boolean isRtl = TextUtilsCompat.getLayoutDirectionFromLocale(Locale.getDefault()) == ViewCompat.LAYOUT_DIRECTION_RTL
if (isRtl) {
   // TODO 如果是阿拉伯语,重新计算横坐标,得到x的点击区域
   return event.getX() > getPaddingEnd() && (event.getX() < getPaddingEnd() + getCompoundDrawablesRelative()[2].getIntrinsicWidth());
   } else {
  return event.getX() > (getWidth() - getPaddingEnd() - getCompoundDrawablesRelative()[2].getIntrinsicWidth()) && (event.getX() < ((getWidth() - getPaddingEnd())));
  }
  • 抽屉布局openDrawer和closeDrawer包含的Gravity属性 需要通过GravityCompat替换。比如Gravity.LEFT需要用GravityCompat.START替代
// 替换前
drawerLayout.closeDrawer(Gravity.LEFT)
// 替换后
drawerLayout.closeDrawer(GravityCompat.START)
  • 双光标的现象,部分手机的输入框可能在RTL语言下,一段文字的左上角和右下角出现半段主光标和副光标,这属于正常现象,是为了多语言文字混编更好的体验,如果感觉不爽,可以通过layout资源重写一套布局来解决。
  • 字符串格式化一些列问题,像日期和阿拉伯数字格式化,String.format可以不使用默认的Local
 // 指定Local兼容RTL
 SimpleDateFormat sdf = new SimpleDateFormat(format,Locale.US);
 // 指定Local兼容RTL
 String.format(Locale.US, "%d", minutes)

 

  • 网页webView适配问题,可以通过前端的同学自己进行适配,主要使用dir属性指定rtl布局
<!DOCTYPE html>
<html dir="rtl">
<head> 
<meta charset="utf-8"> 
<title>RTL布局测试</title> 
</head>
<body>
<bdo>文本方向从右到左!</bdo>
</body>
</html>
  • 垂直LinearLayout控件使用weight属性偶尔会导致适配失效,建议用FrameLayout的layout_gravity属性控制,或者使用RelativeLayout
  • 使用RelativeLayout时,尽量指定`android:layout_alignParentStart`,否则大部分界面,譬如在列表RecyclerView中作为item存在时,可能会出现布局错乱,因为它不知道起始控件的位置
  • 对于ConstraintLayout布局,关于屏障Barrier控件的barrierDirection属性支持不友好,AS无法自动将left转换为start,需要自己手动适配
    <androidx.constraintlayout.widget.Barrier
        android:id="@+id/barrier"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:barrierDirection="start"
        app:constraint_referenced_ids="haha"/>

 

  • 通常TextView宽度若是match_parent,要为他设置android:textAlignment="viewStart/viewEnd"
  • 在多层Fragment或者部分界面局部控件突然适配失效的情况,需要在加载页面前重新进行语言适配
  • 使用到WebView控件,当应用内切换语言后,第一次加载会导致整个页面出现适配无效的情况,解决方案如下:
1.在基类的BaseActivity的setContentView方法之前重新设置语言
    public static void changeLanguage(Context context, String newLanguage) {
        Resources resources = context.getResources();
        Configuration configuration = resources.getConfiguration();
        // app locale
        Locale locale = getLocaleByLanguage(newLanguage);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            configuration.setLocale(locale);
        } else {
            configuration.locale = locale;
        }
        DisplayMetrics dm = resources.getDisplayMetrics();
        resources.updateConfiguration(configuration, dm);
        //保存当前语言
        ...
    }
2.在使用到WebView的界面,onCrate方法增加如下
 @Override
    public void onCreate(Bundle savedInstanceState) {
        // TODO 解决含有webView控件导致切换语言失效
        new WebView(this).destroy();
        super.onCreate(savedInstanceState);
    }


 最后


关于本地化,个人的建议就是杜绝任何形式的硬编码字符串资源,灵活的使用语言区域限定符和布局方向限定符,某些不应该被翻译的部分应当合理的使用标记符进行标记,部分图片尽量通过系统提供的镜像API进行适配,防止apk资源包变得越来越庞大,还有一些程序使用过程中动态的方法需要通过全局搜索进行整体替换,一些第三方库这个不属于自己能完全控制的范畴,可视情况而定,所以,如果你本身有很不错的开源项目,也应该考虑下国际化。另外我很懒的,所以喜欢这篇文章的话随手点个赞吧!

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用力抱一下APP国际化 的相关文章

  • Android EditText 和 addTextChangedListener

    我目前正在将数据库管理器移植到 Android 由于性能原因 我喜欢 仅更新已修改的属性 我尝试使用 addTextChangedListener 执行此操作 以便将修改后的条目添加到列表中 但我的程序从未输入其任何方法 EditText
  • 如何访问 Android 心率传感器原始数据? (反射光,不是心跳)

    心率传感器上的 android sdk 仅返回计算出的 bpm 我对此不感兴趣 我需要访问 Android 心率传感器原始数据 例如就反射值的强度而言将会很大 因为心率传感器基本上使用 LED 并测量随时间变化的反射率 如果可能 访问由任何
  • 用于 Kotlin 中单元测试的 BuildConfigField 模拟

    我正在尝试尽可能多地涵盖Kotlin Android 库我遇到了有关自定义 BuildConfig 变量的问题 更广为人知的是buildConfigField 我想模拟这个变量来测试两者true and false values 从 Gra
  • 通过代码在创建时突出显示 ListView 项目

    我想在创建 listView 时突出显示 ListView 的第一行 0 我尝试了不同的方法 就像您在注释代码中看到的那样 但没有任何效果 这很奇怪 因为 OnItemClickListener 中的突出显示工作正常 它通过 xml 选择器
  • Android ToggleButton 始终检查

    如果切换按钮处于选中或取消选中状态 我想存储在 SharedPreferences 中 toggle setOnCheckedChangeListener new OnCheckedChangeListener public void on
  • Android:如何暂停和恢复可运行线程?

    我正在使用 postDelayed 可运行线程 当我按下按钮时 我需要暂停并恢复该线程 请任何人帮助我 这是我的主题 protected void animation music6 music4 postDelayed new Runnab
  • 使用同一个侦听器的多个活动

    我有 4 个活动 它们都包含一个 xml 页脚 其中包含 4 个按钮 每个活动一个 我现在想为这些按钮设置 onclicklistener 它是页脚中的自制菜单 问题是 如何使用侦听器以便重用代码 我有两个想法 创建一个实现 onclick
  • 如何在 Android 应用程序中隐藏 Flutterwave API 密钥

    我正在构建一个 Android 应用程序 目前正在将 Flutterwave 集成到我的应用程序中以进行支付 建议我永远不要将 Flutterwave API 密钥放在我的应用程序上 那么我该如何隐藏这些键呢 我正在使用 Retrofit
  • 蓝牙 BLE Android 以最大吞吐量写入外设

    我们公司开发了一个具有蓝牙 BLE 的硬件单元 并且我们在 Nexus 7 2013 中有一个服务应用程序 我们希望使用它向该单元发送固件文件 文件最大可达 500kb BT芯片是德州仪器CC2540 我浏览了大量的页面 并扫描了 Stac
  • 4 天后,应用仍未在 Google Play 搜索中编入索引

    我已经在 4 天前在 google play 上发布了我的第一个应用程序 语音到短信 但我仍然无法通过其名称或开发人员名称在搜索中找到我的应用程序 我只能通过包名称或真实应用程序名称 但不带空格 找到我的应用程序 VoiceToSMS 链接
  • Play 商店中的应用描述更新

    我想更新应用程序的描述以及 Play 商店上的屏幕截图 但应用程序保持相同 即相同的版本号 我不想发布新应用程序 因为应用程序中没有任何更改 这可能吗 谷歌也会要求更新应用程序吗 您可以更新描述 也可以更改屏幕截图 您的应用程序将保持不变
  • 如何清除Android剪贴板?

    我发现的方法都不起作用 这是我尝试过的 1 使用clearPrimaryClip 的方法ClipboardManager class ClipboardManager clipboard ClipboardManager getSystem
  • 什么是 Android 测试协调器?

    谷歌最近发布了Android测试支持库1 0 读完后overview https android developers googleblog com 2017 07 android testing support library 10 is
  • Android 和 Google 地图内部片段以及其他控件和 viewpager

    我是android编程新手 我有一个带有 3 个页面 片段 的小应用程序 使用 pageradapter 和 viewpager 在它们之间滑动 其中一个页面包含复选框 和其他控件 和地图 我的问题是程序在启动时崩溃 Fragment co
  • 在光标所在行强制关闭!

    嘿 我正在尝试创建一个应用程序来查找存储在 SQlite 数据库中的 GPS 数据 但我面临一个问题 我构建了一个 DbAdapter 类来创建数据库 现在我尝试使用以下函数从另一个类获取所有数据上的光标 public Cursor fet
  • Toast 消息消失后​​完成活动吗?

    有谁知道 是否有可能对 Toast 消息执行某些操作 在我的情况下完成活动 将被关闭 您只需创建一个Thread持续时间只要Toast显示 然后您就可以完成您的Activity public void onCreate Bundle sav
  • 如何将 JSON 数据从 Android 发送到 php url?

    我想将登录信息从我的应用程序发送到 php url 因为这我的应用程序将崩溃 任何人都可以帮助我解决这个问题 这是我的服务器登录方法 我想将数据发送到此登录方法 Method public method login Parameters 3
  • 如何知道我的应用程序的活动计数?

    我的应用程序中有多项活动 请考虑以下案例 Activity A 调用 Activity B B 调用 C 当用户按后退键时 C 生成通知并转到 B 现在再次按后退 因此将显示 A 再次按后退键也会终止 A 并显示通知 现在 当用户按下通知图
  • onPrepareOptionsMenu 复制 ActionBar 中的项目

    当我使用 onPrepareOptionsMenu 添加菜单项时 该菜单项会在操作栏中复制其自身 我正在使用片段并在主要活动的 ActionBar 中创建初始菜单 如下所示 Override public boolean onCreateO
  • 调试android数据绑定?

    谁能告诉我如何调试或找到数据绑定生成的代码 从this https www youtube com watch v NBbeQMOcnZ0链接我发现它生成了所需的代码 我猜您正在寻找自动生成的绑定 java 文件 我也在寻找他们 最后我在这

随机推荐

  • matlab中的导函数驻点,Matlab用导数作定性分析

    Matlab用导数作定性分析 5 1知识要点 函数作图 用导数定性描述函数 clf x linspace 8 8 30 f x 3 2 4 x 1 plot x f fplot x 3 2 4 x 1 8 8 clf x sym x f x
  • 软件工程开发模式:从传统到现代的演进

    引言 软件工程开发模式是指导软件开发过程的重要框架 旨在提高软件开发的效率和质量 随着技术的不断进步 软件工程开发模式也在不断发展演变 以适应不同的项目需求和开发环境 本文将介绍传统软件工程开发模式和现代敏捷 精益和DevOps软件工程开发
  • Docker进阶学习:docker-compose的体验

    安装好docker compose后 我们要体验一下了解基础的操作和命令 搞一个官方demo python应用 计数器 redis 我先来一个官方文档地址 基本很多都是按照文档来的 建议尽量去官方文档来产看最新的 我这个可能也只是主要内容搬
  • Jmeter(二十一) - 从入门到精通 - JMeter断言 - 上篇(详解教程)

    1 简介 最近由于在搭建自己的个人博客可能更新的有点慢 断言组件用来对服务器的响应数据做验证 常用的断言是响应断言 其支持正则表达式 虽然我们的通过响应断言能够完成绝大多数的结果验证工作 但是JMeter还是为我们提供了适合多个场景的断言元
  • python获取列表的任意行任意列

    import numpy as np a 1 12 13 14 2 22 23 24 3 32 33 34 4 42 43 44 a np array a print 获取列表的任意列 print a 3 2 1 0 0 print 获取列
  • 2021年网络安全省赛--服务器内部信息获取解析(中职组)

    2021年省赛服务器内部信息获取解析 一 竞赛时间 180分钟 共计3小时 二 竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 1 收集服务器场景中的服务信息 并获取服务器中开放的端口号信息 将服务器端口号作为flag提交 如果有多
  • linux内核历史版本及网址介绍

    官网 https www kernel org 最新版本4 12 rc4 Protocol Location HTTP https www kernel org pub GIT https git kernel org RSYNC rsyn
  • esBuild + SWC 构建 TS 项目

    1 esBuild 介绍 在 esbuild 的官方介绍中打包 threejs 只需要 0 37 秒 Esbuild 是一个非常新的模块打包工具 它提供了与 Webpack Rollup Parcel 等工具 相似 的资源打包能力 却有着高
  • 两个3*3的卷积核替代5*5(三个3*3卷积核替代7*7)分析

    文章目录 为什么一个5x5的卷积核可以用两个3x3的卷积核来替代 一个5 5卷积 两个3 3卷积核 为什么一个7x7的卷积核可以用三个个3x3的卷积核来替代 一个7 7卷积 三个3 3卷积核 优点总结 为什么一个5x5的卷积核可以用两个3x
  • 输入一个字符串,把一个字符串的字符逆序输出

    package com qf day4 import java util Scanner public class Test29 public static void main String args 把一个字符串的字符逆序输出 Scann
  • 可能是最详细的React组件库搭建总结

    可能是最详细的React组件库搭建总结 概览 本文包含以下内容 prepare 组件库前期开发准备工作 eslint commit lint typescript等等 dev 使用docz进行开发调试以及文档编写 build umd cjs
  • TeamViewer账号未激活问题

    出现如下问题 解决步骤 1 点击重新发送电子邮件 2 网页上登录 3 QQ邮箱里面添加设备信任 4 返回登录页面再重新 刷新重新输入登录信息登录 然后重新发送电子邮件到qq邮箱 5 点击激活 6 登录 gt gt gt 不要现在登录 gt
  • JAVA各种加密与解密方式

    之前有兴趣研究了一下java的加密与解密的方法 发现市面上有好多种加密解密方式 在这里整理了一下 目录 1 BASE64加密 解密 2 MD5 Message Digest Algorithm 加密 3 DES Data Encryptio
  • 将 pip 的默认源修改为阿里源(Windows 版)

    背景 由于 python 自带的源下载速度非常慢 特别是安装一些库的时候 甚至有时会失败 临时替换 临时替换直接使用以下命令即可 pip install 包名 i 源地址 例如 pip install numpy i http mirror
  • Visual Studio无法打开源文件错误

    在写用Visual Studio跨平台Linux项目的时候 遇到了无法打开源文件错误 主要原因是include目录里面没有这些文件 解决方法是 把Linux的 usr include目录压缩下载在本地 zip r usr include z
  • js 导出excel详解

    一 需要安装 npm install xlsx style Blob js 和Export2Excel js 在网上搜都可以找到的 而Export2Excel我做了修改 代码如下 带 的都是我改动的地方 Export2Excel js es
  • SQL中CASE的用法

    在SQL中 CASE语句是一种条件表达式 用于根据条件执行不同的操作 它有两种形式 简单CASE表达式和搜索CASE表达式 简单CASE表达式的语法如下 CASE expression WHEN value1 THEN result1 WH
  • GEO数据下载及处理详细过程

    GEO2R 如果出现提示 请指定GEO系列加入和平台 单击 定义组 并输入您计划比较的样品组的名称 例如测试和控制 将样本分配给每个组 突出显示Sample行 然后单击组名称以将这些Samples分配给该组 使用样本元数据 标题 源和特征
  • C++ 强制类型转换(const_cast/reinterpret_cast)使用详解

    一 const cast用法 const cast lt new type gt expression 用于转换指针或引用 可以去掉类型的const属性 在c 参考文档网站上 const cast conversion cppreferen
  • 用力抱一下APP国际化

    APP国际化 说的直白应该也叫本土化或者本地化 如果你的应用上线到谷歌应用市场 那么应该做好本地化的支持 用来支持不同语言及地区的风俗习惯 当然也要结合公司拓展的海外市场需要 那么对于一款应用 至少应该做到多语言和多布局的支持 最近忙于阿拉