반응형
여러 국가의 언어를 사용하는 어플을 제작하기 위해서 여러 가지 방법이 있지만 앱 내부에서 설정을 만들고 싶으실 때 참고하시면 좋을 것 같습니다.
저는 Spinner를 사용해서 언어를 선택하고 원하는 언어로 설정되게 하는 예제를 만들어보겠습니다.
1. activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<Spinner
android:id="@+id/spinner"
android:layout_marginTop="50dp"
android:layout_marginBottom="50dp"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:spinnerMode="dropdown"
app:layout_constraintBottom_toTopOf="@+id/textView" />
<TextView
android:id="@+id/textView"
android:gravity="center"
android:textColor="@android:color/black"
android:textSize="20sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
android:spinnerMode="dropdown"
스피너의 아이템들이 밑으로 바로 출력되는 방식입니다.
android:spinnerMode="dialog"
스피너의 아이템들이 다이얼로그 형식으로 출력 되는 방식입니다.
2. strings.xml
<resources>
<string name="app_name">spinner</string>
<string name="hello">안녕</string>
<string name="korean">한국어</string>
<string name="english">영어</string>
<string name="chinese">중국어</string>
</resources>
영어, 중국어도 똑같이 추가해줍니다.
다른 국가의 언어를 추가하는 방식은 링크를 참고해주세요
3. MainActivity.java
package com.everyshare.spinner;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Locale;
public class MainActivity extends AppCompatActivity {
TextView textView;
Spinner spinner;
SharedPreferences sharedPreferences;
String locale;
int locale_number;
ArrayList<String> locales;
ArrayAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sharedPreferences = getSharedPreferences("shared",MODE_PRIVATE);
//버전 확인후 sharedpreferences에 locale키 값의 value값을 가져옵니다.
//값이 없을 경우 기본언어 설정
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
locale = sharedPreferences.getString("locale",getResources().getConfiguration().getLocales().get(0).getLanguage());
}else{
locale = sharedPreferences.getString("locale",Resources.getSystem().getConfiguration().locale.getLanguage());
}
//스피너 기본 선택값을 주기 위해서 해당 언어의 순서에 맞게 int값을 준비해줍니다.
switch (locale){
case "ko":{
locale_number = 0;
break;
}
case "en":{
locale_number = 1;
break;
}
case "zh":{
locale_number = 2;
}
}
textView = findViewById(R.id.textView);
//스피너로 설정한 언어에 맞는 언어로 TextView에 텍스트를 넣어줍니다.
textView.setText(getStringByLocal(this,R.string.hello,locale));
spinner = findViewById(R.id.spinner);
locales = new ArrayList<>();
//strings.xml에 있는 언어 가져와서 리스트에 추가
locales.add(getStringByLocal(this,R.string.korean,locale));
locales.add(getStringByLocal(this,R.string.english,locale));
locales.add(getStringByLocal(this,R.string.chinese,locale));
adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, locales);
spinner.setAdapter(adapter);
spinner.setSelection(locale_number);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
//선택한 아이템의 포지션이 현재 설정되어있는 언어의 포지션이 아닐 경우
if(position != locale_number){
switch (position){
case 0:{
locale = "ko";
break;
}
case 1:{
locale = "en";
break;
}
case 2:{
locale = "zh";
break;
}
}
//sharedpreferences를 생성
SharedPreferences.Editor editor = sharedPreferences.edit();
//sharedpreferences 안에 선택한 locale값 넣기
editor.putString("locale",locale);
//저장
editor.commit();
//어플 재시작
Intent intent = getBaseContext().getPackageManager()
.getLaunchIntentForPackage(getBaseContext().getPackageName());
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
finish();
startActivity(intent);
}
}
//아무것도 선택하지 않았을 경우
@Override
public void onNothingSelected(AdapterView<?> parent) {
spinner.setSelection(locale_number);
}
});
}
//선택한 언어에 맞는 String값을 반환합니다.
@NonNull
public static String getStringByLocal(Activity context, int resId, String locale) {
//버전에 따라서 언어를 설정해주는 방식이 다르기 때문에 분류해서 사용합니다.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
return getStringByLocalPlus17(context, resId, locale);
else
return getStringByLocalBefore17(context, resId, locale);
}
//젤리빈 버전 이상일 경우
@NonNull
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
private static String getStringByLocalPlus17(Activity context, int resId, String locale) {
Configuration configuration = new Configuration(context.getResources().getConfiguration());
configuration.setLocale(new Locale(locale));
return context.createConfigurationContext(configuration).getResources().getString(resId);
}
//젤리빈 버전 이하일 경우
private static String getStringByLocalBefore17(Context context, int resId, String language) {
Resources currentResources = context.getResources();
AssetManager assets = currentResources.getAssets();
DisplayMetrics metrics = currentResources.getDisplayMetrics();
Configuration config = new Configuration(currentResources.getConfiguration());
Locale locale = new Locale(language);
Locale.setDefault(locale);
config.locale = locale;
/*
* Note: This (temporarily) changes the devices locale! TODO find a
* better way to get the string in the specific locale
*/
Resources defaultLocaleResources = new Resources(assets, metrics, config);
String string = defaultLocaleResources.getString(resId);
// Restore device-specific locale
new Resources(assets, metrics, currentResources.getConfiguration());
return string;
}
}
스피너의 레이아웃은 안드로이드에서 기본으로 제공되는 레이아웃을 사용하도록 설정했습니다.
참고하실 부분은 onNothingSelected는 스피너를 선택한 후에 아이템을 선택하지 않고 다른 뷰를 터치하거나 뒤로 가기 등의 이벤트가 발생했을 때 작동하는 함수라고 생각하시면 될 것 같습니다.
저는 원래 기본값을 넣어주도록 코딩했습니다.
getStringBylocal 함수는 링크를 참고해서 만들었습니다.
반응형
'안드로이드 > 코드' 카테고리의 다른 글
[안드로이드] 웹뷰 사용하기 - WebView (2) | 2020.01.06 |
---|---|
[안드로이드] 커스텀 토스트(Toast), 스낵바(Snackbar) 사용하기 (0) | 2020.01.05 |
[안드로이드] 위험 권한 요청후 갤러리 사진 가져오기 (0) | 2020.01.03 |
[안드로이드] Volley, Json을 이용해서 로또 당첨번호 조회하기 (0) | 2020.01.02 |
[안드로이드] 위험 권한 요청, 확인 하기 (0) | 2019.12.27 |