オードリー・タン氏のPRにみる言語選択肢の表示文字

これ。

👉 東京都のコロナ対策サイト、台湾の“天才IT大臣”も改善に参加 オープンソースの取り組み、「胸アツ展開」と話題 - ITmedia NEWS 

👉 Fix language selector label for zh-TW (体 -> 體) by audreyt · Pull Request #827 · tokyo-metropolitan-gov/covid19 

❌ 繁体
⭕ 繁體

ということになります。

あれ、

「繁体」

のほうをよく見かけるような気がしませんか??

本当に「繁体」は間違い?

繁体字(はんたいじ、繁體字、拼音: fántǐzì)

特に中華人民共和国の一連の「文字改革」政策による簡体字(簡化字)との対比によりこう呼ぶ。現在では主に台湾のほか、中華人民共和国の特別行政区である香港・マカオで使用され、中華圏外の華人コミュニティーでも見られる。

👉 繁体字 - Wikipedia 

Google 翻訳のWEB版とアプリ版の選択肢をみてみます。

そうか、

サイトやアプリの「表示している言語」の設定で「言語の選択肢」の表示文字が変わるのですね!

👉 Google Language Codes - tomihasa 

4つの言語に関して、表示されるべき選択肢の文字を見ておきましょう。

hl=ja

英語
中国語(簡体)
中国語(繁体)
日本語

hl=en

English
Chinese (Simplified)
Chinese (Traditional)
Japanese

hl=zh_CN

英语
中文(简体)
中文(繁体)
日语

hl=zh_TW

英文
中文(簡體)
中文(繁體)
日文

オードリー・タン氏は、台湾の方なので、台湾向け言語表示としては

「中文(繁體)」

が選択肢に表示されるべき文字となるのでしょうか。

しかし、東京都のように選択肢の文字自体を表示言語に合わせて翻訳してないサイトもあります。

👉 都内の最新感染動向 | 東京都 新型コロナウイルス感染症対策サイト 

Android Pie 言語設定画面。

Android端末では、以前からこのような実装になっています。

フォントの事情がありますので、端末や文字によっては豆腐や文字化けなどに注意が必要です。

まとめ

呼称や表記でもめたりするネット上で

オードリー・タン氏の台湾愛を見たような気がします。


【MVVM】Flow vs LiveData

👉 Using LiveData & Flow in MVVM — Part I - ProAndroidDev 

Kotlin Flow の登場で盛り上がってきました。

どれにします? どの流れにします?

Repository

Result を返す。

Flow<Result>を返す。

ViewModel

Result を受けて、LiveData<Result> を渡す。

Flow<Result> を受けて、LiveData<Result> を渡す。


Fragment

LiveData<Result> を受け取る。

Flow<Result> を受け取る。


override fun onActivityCreated(savedInstanceState: Bundle?) {
  super.onActivityCreated(savedInstanceState)

  viewModel = ViewModelProviders.of(
      this,
      viewModelFactory
  ).get(WeatherForecastDataStreamFlowViewModel::class.java)

  // Consume data when fragment is started
  lifecycleScope.launchWhenStarted {

    // Since collect is a suspend function it needs to be called
    // from a coroutine scope
    viewModel.weatherForecast.collect {
      when (it) {
        Result.Loading -> {
          Toast.makeText(context, "Loading", Toast.LENGTH_SHORT).show()
        }
        is Result.Success -> {
          tvDegree.text = it.data.toString()
        }
        Result.Error -> {
          Toast.makeText(context, "Error", Toast.LENGTH_SHORT).show()
        }
      }
    }
  }
}

WeatherForecastDataStreamFlowFragment #L47-L75

まとめ

とはいえ、今はまだ、完全に LiveData は捨てれんよの。

👉 Kotlin で Result 
👉 Kotlin Flow vs Android LiveData - Stack Overflow 
👉 From RxJava 2 to Kotlin Flow: Threading - ProAndroidDev 

追記: ホットな Flow が登場したので以下。

👉 【MVVM】 Kotlin Flow で使える5つの利用パターン 


「Kotlinx Json」の登場でサードパーティJSONライブラリは不要となる。

JSONのライブラリ何を使ってますか?

👉 square/moshi: A modern JSON library for Kotlin and Java. 
👉 FasterXML/jackson: Main Portal page for the Jackson project 
👉 google/gson: A Java serialization/deserialization library to convert Java Objects into JSON and back 

これらは、Javaベースで書かれています。Kotlin は100%相互運用可能ですが微妙に期待しない挙動をします。


data class User(
    val name: String,
    val email: String,
    val age: Int = 13,
    val role: Role = Role.Viewer
)

enum class Role { Viewer, Editor, Owner }


{
    "name" : "John Doe",
    "email" : "[email protected]"
}


class JsonUnitTest {

    private val jsonString = """
            {
                "name" : "John Doe",
                "email" : "[email protected]"
            }
        """.trimIndent()

    @Test
    fun gsonTest() {
        val user = Gson().fromJson(jsonString, User::class.java)

        assertEquals("John Doe",user.name)
        assertEquals(null, user.role)
        assertEquals(0, user.age)

//      User(name=John Doe, 
//           [email protected], 
//           age=0, 
//           role=null)

    }

}

デフォルト値が期待通りにパースできません。

kotlinx.serialization が登場!!

JetBrains産です。間違いないでしょう。



👉 Kotlin/kotlinx.serialization: Kotlin multiplatform / multi-format serialization 

- クロスプラットフォーム
- 非リフレクション
- アノテーション @Serializable
- Kotlin v1.3.30+


@Serializable
data class User(
    val name: String,
    val email: String,
    val age: Int = 13,
    val role: Role = Role.Viewer
)

enum class Role { Viewer, Editor, Owner }

class JsonUnitTest {

    private val jsonString = """
            {
                "name" : "John Doe",
                "email" : "[email protected]"
            }
        """.trimIndent()

    @Test
    fun jsonTest() {
        val user = Json.parse(User.serializer(), jsonString)

        assertEquals("John Doe", user.name)
        assertEquals(Role.Viewer, user.role)
        assertEquals(13, user.age)

//      User(name=John Doe, 
//           [email protected], 
//           age=13, 
//           role=Viewer)

    }
}

Gson では無視されていたデフォルト値がきちんと使用されます。

以下のセットアップでどうぞ。


buildscript {
    ext.kotlin_version = '1.3.60'
    repositories { jcenter() }

    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
    }
}


apply plugin: 'kotlin' 
apply plugin: 'kotlinx-serialization'


repositories {
    jcenter()
}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.14.0" // JVM dependency
}

👉 Kotlinx Json vs Gson - Juraj Kušnier - Medium