시스템 폰트 크기 변경시 UI 이슈 대응하기

대부분의 안드로이드 사용자의 경우에는 폰트의 크기를 default 사이즈로 사용해서 특별히 문제가 없지만, 나이가 드신 분들이나 작은 글자의 인식이 불편해서 글자의 크기를 크게(최대로) 해서 보시는 분들도 있다. 이 경우에는 앱에서 이 경우를 대비해서 대응하지 않으면 글자의 위/아래가 잘리는 경우를 볼 수 있다.

우선 폰트의 크기를 설정 앱에서 변경해 보자. 갤럭시를 기준으로 살펴보면 Settings > Display > Font size and style 에서 아래와 같이 폰트의 크기를 변경할 수 있다.

다음으로, 위 화면과 같이 폰트의 크기를 최대로 변경한 경우, 앱에서 어떻게 보이는지 살펴보자. 예로 아래의 화면과 아래의 코드가 이 경우에 해당한다.

그리고, 위 화면을 보여주는 텍스트 뷰의 간략한 코드는 아래와 같다.

<TextView
android:id="@+id/fg_docs_item_detail"
android:layout_width="0dp"
android:layout_height="28dp"
..... />

다음으로, 이 문제를 해결하기 위한 방안을 살펴보자. 간단하게 UI(XML) 코드를 아래와 같이 개선하면 된다. android:layout_height은 글자 크기에 따라서 커질 수 있게 처리(wrap_content)하고, android:minHeight은 기존의 컴포넌트 크기로 고정한다. 그리고, 아래 UI를 포함하는 뷰 그룹(Linear, Relative, Fragme, Constraint)들도 아래와 같이 처리하면 안드로이드 시스템 폰트의 크기를 변경해도 앱 화면의 UI가 잘리지 않게 된다.

<TextView
android:id="@+id/fg_docs_item_detail"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:minHeight="28dp"
..... />

마지막으로, 위 코드를 적용한 앱의 화면을 아래에서 볼 수 있다. 이 화면에서는 글자가 커지긴 했지만, 잘리지 않고 잘 보이는 것을 알 수 있다.

안드로이드 음성 검색에서 언어 선택하기

안드로이드 앱에서 음성 검색(Voice Search)을 하는 방법을 아래와 같은 코드로 간단하게 실행할 수 있다.

private static final int SPEECH_REQUEST_CODE = 0;

// Create an intent that can start the Speech Recognizer activity
private void displaySpeechRecognizer() {
	Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
	intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
	// Start the activity, the intent will be populated with the speech text
	startActivityForResult(intent, SPEECH_REQUEST_CODE);
}

// This callback is invoked when the Speech Recognizer returns.
// This is where you process the intent and extract the speech text from the intent.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
	if (requestCode == SPEECH_REQUEST_CODE && resultCode == RESULT_OK) {
		List results = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
		String spokenText = results.get(0);
		// Do something with spokenText
	}
	super.onActivityResult(requestCode, resultCode, data);
}

위 코드는 https://developer.android.com/training/wearables/apps/voice 에서 확인 할 수 있고, 안드로이드 OS에 설정한 언어를 기반으로 인식한다. 위 코드를 실행하면 아래와 같이, 시스템 언어에 따라서 영어, 한국어를 인식하는 것을 알 수 있다.
 
– 안드로이드 OS 언어 설정에 따른 음성 검색 화면

이제 많은 앱들이 앱 자체에서 언어를 동적으로 변경할 수 있는 기능을 제공하고 있고, 이 경우에 안드로이드 OS의 언어 설정에 따른 음성 검색이 아니라 앱에서 사용하는 언어의 음성 검색이 필요하게 되었다.

위는 개인적으로 만들어서 서비스하는 오피스 리더 앱(https://play.google.com/store/apps/details?id=net.sjava.officereader) 에서 언어를 변경할 수 있는 화면이다. 이 상황에서 언어를 변경해도 음성 검색은 시스템의 언어를 기준으로 검색을 하기 때문에, 앱의 언어를 한국어로 변경했지만 음성 검색에서 영어를 인식언어로 사용하게 된다. 그래서, 특정 언어를 기준으로 인식을 요청하기 위해서는 아래의 파라미터 값에 언어와 나라의 값을 알려주면 된다.

intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, “ko-KR”);

그러나, 설정에서 변경하는 값이 언어이지, 나라 위치가 아니다. 그리고, 언어별로 사용할 수 있는 나라들이 많이 존재하는 경우가 일반적이기도 하다. 안드로이드 5.0.1의 로케일(https://github.com/championswimmer/android-locales)을 살펴보면, 조금씩 다른 경우가 많겠지만 한 언어를 사용하는 국가가 많다. 그래서, 앱에서 언어를 변경하는 경우, 그 언어의 대표 값을 인식할 수 있게 해서 음성 검색시 나라의 위치를 확인하지 않아도 동작해야 하고, 아래 코드로 앱에서 설정한 언어의 대표 언어를 가져와서 “-“를 추가해서, 대표 언어로 인식하게 할 수 있다.

// Create an intent that can start the Speech Recognizer activity
private void displaySpeechRecognizer(Context context) {
	Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
	intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
	LocaleList localeList = context.getResources().getConfiguration().getLocales();
	if(localeList.size() > 0) {
		String language = localeList.get(0).getLanguage();
		intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, language +"-");
	}
	// Start the activity, the intent will be populated with the speech text
	startActivityForResult(intent, SPEECH_REQUEST_CODE);
}

이제 위 코드를 사용하면, 앱에서 언어를 변경한 경우에 쉽게 변경한 언어에 맞게 음성 검색을 실행할 수 있다.