앱내에서 언어를 설정하는 방법에 관하여...

1. values > string.xml / values-en > string.xml .... 이와 같이 res/values 디렉토리를 설정
2. 각 string name 을 동일하게 하고 번역된 내용을 다양하게 갖고 있는다.
3. 단말 시스템에서 언어 설정을 다른 국가로 변경하고 앱을 재실행.
4. 앱 내에서 아래와 같은 코드를 동작시키고 현재 액티비티 혹은 다른 액티비티로 전환
Locale locale = new Locale(character);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
activity.getResources().updateConfiguration(config, activity.getResources().getDisplayMetrics());
5. 3번의 경우 단말의 모든 다른 앱까지 영향을 받지만, 4번의 경우 현재 실행된 앱만 영향을 받으며, 앱을 종료후 재실행 시키게 되면,
기본적으로 시스템에서 설정한 내용으로 변경된다.

근데 문제는 과연 4번의 방법을 이용해서 액티비티를 재실행시키지 않고 화면에서 바로 변경하는 방법이 없을까 ?

사용자 입장에서 보면 당연히 언어전환하고 앱을 재실행 시키고 하는 액션은 불필요해 보인다.
그리고 개발자 입장에서 액티비티를 재실행 시키는건 아무래도 부담이 되는게 현실이다..ㅜㅜ

과연 그렇다면 액티비티를 재실행하지 않고 이벤트 만으로 언어전환이 가능할까?

일단은 가능하다 레이아웃에 간단한 작업을 해주고, 이후 아래의 제시된 메서드를 실행 할 경우 언어 전환은 간단하게 해결된다.

변경 방법 

1. 레이아웃 xml 파일을 열어서 텍스트가 사용된 위젯(TextView, Button, EditText ...) 을 찾아서 아래와 같은 형태로 변경
  android:text="@string/text1" << 이런형태로 존재하는 태그를 찾아서,
  android:tag="text1" << values 내부에 있는 string name 값을 값만 넣는다.

2. 위와 같이 변경한 뒤 버튼에 간단한 리스너를 걸고 아래의 메서드를 호출해보자
// 언어 설정 메소드
public static void setRefreshViewGroup(Context context, ViewGroup root) throws Exception {
for (int i = 0; i < root.getChildCount(); i++) {
View child = root.getChildAt(i);

if (child instanceof TextView) {
if (child.getTag() != null) {

if (((TextView) child).getText() != null && ((TextView) child).getText().toString().length() > 0) {
int stringId = getResourceId(context, child.getTag());
((TextView) child).setText(stringId);
// Log.i(TAG, "getText:" + ((TextView)
// child).getText());
}

if (((TextView) child).getHint() != null && ((TextView) child).getHint().toString().length() > 0) {
int hintId = getResourceId(context, child.getTag());
((TextView) child).setHint(hintId);

// Log.i(TAG, "getHint:" + ((TextView)
// child).getHint());
}
}
} else if (child instanceof ViewGroup)
setRefreshViewGroup(context, (ViewGroup) child);
}
}

public static int getResourceId(Context context, Object tag) {
return context.getResources().getIdentifier((String) tag, "string", context.getPackageName());
}

// 언어 설정 메소드
public static void setLocale(final Activity activity, String character) {
Locale locale = new Locale(character);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
activity.getResources().updateConfiguration(config, activity.getResources().getDisplayMetrics());

final ViewGroup vg = (ViewGroup) activity.getWindow().getDecorView().getRootView();

try {
setRefreshViewGroup(activity, vg);
} catch (Exception e) {
e.printStackTrace();
}

Log.i(TAG, "getLocale : " + Locale.getDefault().toString());
}

실제로 실행하는 메서드는 setLocale(activity, "en") 과 같은 형태로 호출 하도록 한다.

이렇게 되면 화면상에 존재하는 위젯들이 텍스트가 values-en>string.xml 내의 데이터로 변경되게 된다.

원리

view 내부에 존재하는 모든 view 를 검색하여 textview 를 걸러내어 해당 view 의 내용을 변경해준다.

주의 할 점

1. 아무래도 UI 를 사용하기 때문에 변경시 runtimeexception 이 발생할 수 있다. 그렇기 때문에 핸들러나 AsyncTask 를 이용하여 변경하기를 권장

2. ImageView 를 변경하는 방법도 있을것 같은데, 아직까지 시간이 없는 관계로 테스트를 많이 진행하지 못했다. 혹시나 위와 같은 형태에서 ImageView 까지 핸들링이 가능한 분이 계시다면 나중에 같이 공유하면 좋을듯 싶다.