Skip to content

Commit

Permalink
Implement language switcher
Browse files Browse the repository at this point in the history
- Add language switcher to demo internationalization in the sdc lib
- Vietnamese localization
  • Loading branch information
ndegwamartin committed Jun 17, 2021
1 parent d37c4c4 commit 646c736
Show file tree
Hide file tree
Showing 9 changed files with 260 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,111 @@

package com.google.android.fhir.datacapture.gallery

import android.app.Activity
import android.content.Context
import android.content.res.Configuration
import android.os.Bundle
import android.view.MenuItem
import android.view.View
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AppCompatActivity
import com.google.android.fhir.datacapture.gallery.databinding.ActivityMainBinding
import com.google.android.fhir.datacapture.gallery.utils.LanguageSwitcherUtils
import com.google.android.material.navigation.NavigationView
import java.util.Locale

class MainActivity : AppCompatActivity() {
class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
private lateinit var binding: ActivityMainBinding
private lateinit var drawerToggle: ActionBarDrawerToggle
private lateinit var languageList: List<LanguageSwitcherUtils.Language>

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)

languageList = LanguageSwitcherUtils.getLanguageList(this)

setUpNavigationView()
}

private fun refreshToSelectedLanguage(
language: LanguageSwitcherUtils.Language,
context: Activity
) {

getNavigationView().menu.findItem(R.id.switch_language).title = language.displayName

val sharedPref =
context?.getSharedPreferences(
BuildConfig.APPLICATION_ID.plus(this.javaClass.canonicalName),
Context.MODE_PRIVATE
)
?: return
with(sharedPref.edit()) {
putString(LanguageSwitcherUtils.SHARED_PREF_KEY_LANG, language.tag)
commit()
}

LanguageSwitcherUtils.refreshActivity(context)
}

override fun attachBaseContext(base: Context) {
val sharedPref =
base?.getSharedPreferences(
BuildConfig.APPLICATION_ID.plus(this.javaClass.canonicalName),
Context.MODE_PRIVATE
)
?: return
val languageTag =
sharedPref.getString(
LanguageSwitcherUtils.SHARED_PREF_KEY_LANG,
Locale.getDefault().toLanguageTag()
)
val newConfiguration: Configuration? = LanguageSwitcherUtils.setAppLocale(base, languageTag)
super.attachBaseContext(base)
applyOverrideConfiguration(newConfiguration)
}

override fun onNavigationItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.switch_language ->
LanguageSwitcherUtils.renderSelectLanguageDialog(this, languageList) { _, i ->
refreshToSelectedLanguage(languageList[i], this)
}
else -> false
}

return true
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {

if (drawerToggle.onOptionsItemSelected(item)) {
return true
}
return super.onOptionsItemSelected(item)
}

private fun setUpNavigationView() {

drawerToggle =
ActionBarDrawerToggle(
this,
binding.drawerLayout,
R.string.nav_app_bar_open_drawer_description,
R.string.nav_app_bar_navigate_up_description
)
binding.drawerLayout.addDrawerListener(drawerToggle)
drawerToggle.syncState()

supportActionBar?.setDisplayHomeAsUpEnabled(true)

val navigationView = getNavigationView()
navigationView.setNavigationItemSelectedListener(this)

navigationView.menu.findItem(R.id.switch_language).title = Locale.getDefault().displayName
}

private fun getNavigationView() = findViewById<View>(R.id.nav_view) as NavigationView
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.android.fhir.datacapture.gallery.utils

import android.app.Activity
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.content.res.Configuration
import android.content.res.Resources
import android.os.Build
import android.os.LocaleList
import android.widget.ArrayAdapter
import androidx.appcompat.app.AlertDialog
import com.google.android.fhir.datacapture.gallery.R
import java.util.Locale

object LanguageSwitcherUtils {

const val SHARED_PREF_KEY_LANG = "shared_pref_key_lang"

fun setAppLocale(context: Context, language: String?): Configuration? {
val res: Resources = context.resources
val configuration: Configuration = res.configuration
try {
val locale = Locale.forLanguageTag(language)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
configuration.setLocale(locale)
val localeList = LocaleList(locale)
LocaleList.setDefault(localeList)
configuration.setLocales(localeList)
context.createConfigurationContext(configuration)
} else {
configuration.locale = locale
res.updateConfiguration(configuration, res.displayMetrics)
}
} catch (e: Exception) {
e.printStackTrace()
}
return configuration
}

fun getLanguageList(activity: Activity): List<Language> {
return activity.resources.getStringArray(R.array.languages).toList().map {
Language(it, Locale.forLanguageTag(it).displayName)
}
}

fun refreshActivity(activity: Activity) {
val intent = Intent(activity, activity.javaClass)
activity.startActivity(intent)
}

fun renderSelectLanguageDialog(
context: Activity,
languageList: List<Language>,
listener: DialogInterface.OnClickListener
) {

val adapter: ArrayAdapter<Language> =
ArrayAdapter(context, android.R.layout.simple_list_item_1, languageList)

val builder: AlertDialog.Builder = AlertDialog.Builder(context)
builder.setTitle(context.getString(R.string.select_language))
builder.setIcon(R.drawable.outline_language_24)
builder.setAdapter(adapter, listener).create().show()
}
data class Language(val tag: String, val displayName: String) {
override fun toString() = displayName
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal"
>
<path
android:fillColor="@android:color/white"
android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM18.92,8h-2.95c-0.32,-1.25 -0.78,-2.45 -1.38,-3.56 1.84,0.63 3.37,1.91 4.33,3.56zM12,4.04c0.83,1.2 1.48,2.53 1.91,3.96h-3.82c0.43,-1.43 1.08,-2.76 1.91,-3.96zM4.26,14C4.1,13.36 4,12.69 4,12s0.1,-1.36 0.26,-2h3.38c-0.08,0.66 -0.14,1.32 -0.14,2s0.06,1.34 0.14,2L4.26,14zM5.08,16h2.95c0.32,1.25 0.78,2.45 1.38,3.56 -1.84,-0.63 -3.37,-1.9 -4.33,-3.56zM8.03,8L5.08,8c0.96,-1.66 2.49,-2.93 4.33,-3.56C8.81,5.55 8.35,6.75 8.03,8zM12,19.96c-0.83,-1.2 -1.48,-2.53 -1.91,-3.96h3.82c-0.43,1.43 -1.08,2.76 -1.91,3.96zM14.34,14L9.66,14c-0.09,-0.66 -0.16,-1.32 -0.16,-2s0.07,-1.35 0.16,-2h4.68c0.09,0.65 0.16,1.32 0.16,2s-0.07,1.34 -0.16,2zM14.59,19.56c0.6,-1.11 1.06,-2.31 1.38,-3.56h2.95c-0.96,1.65 -2.49,2.93 -4.33,3.56zM16.36,14c0.08,-0.66 0.14,-1.32 0.14,-2s-0.06,-1.34 -0.14,-2h3.38c0.16,0.64 0.26,1.31 0.26,2s-0.1,1.36 -0.26,2h-3.38z"
/>
</vector>
24 changes: 19 additions & 5 deletions datacapturegallery/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,34 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<androidx.constraintlayout.widget.ConstraintLayout
<androidx.drawerlayout.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity"
>

<androidx.fragment.app.FragmentContainerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
app:navGraph="@navigation/main_nav_graph"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/main_nav_graph"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header"
app:menu="@menu/nav_drawer_menu"
/>

</androidx.drawerlayout.widget.DrawerLayout>
9 changes: 9 additions & 0 deletions datacapturegallery/src/main/res/layout/nav_header.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8" ?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="160dp"
android:background="@color/purple_700"
>

</androidx.constraintlayout.widget.ConstraintLayout>
9 changes: 9 additions & 0 deletions datacapturegallery/src/main/res/menu/nav_drawer_menu.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8" ?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

<item
android:id="@+id/switch_language"
android:title="Language"
android:icon="@drawable/outline_language_24"
/>
</menu>
20 changes: 20 additions & 0 deletions datacapturegallery/src/main/res/values-vi/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!--
Copyright 2020 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<string name="app_name">Thư viện thu thập dữ liệu</string>
<string name="submit_button_text">Gửi</string>
<string name="select_language">Chọn ngôn ngữ</string>
</resources>
7 changes: 7 additions & 0 deletions datacapturegallery/src/main/res/values/languages.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<string-array name="languages">
<item>en</item>
<item>vi-VN</item>
</string-array>
</resources>
1 change: 1 addition & 0 deletions datacapturegallery/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@
<resources>
<string name="app_name">Data Capture Gallery</string>
<string name="submit_button_text">Submit</string>
<string name="select_language">Select Language</string>
</resources>

0 comments on commit 646c736

Please sign in to comment.