관리 메뉴

드럼치는 프로그래머

[안드로이드] TextView 줄바꿈을 글자 단위로 하기 본문

★─Programing/☆─Android

[안드로이드] TextView 줄바꿈을 글자 단위로 하기

드럼치는한동이 2013. 11. 19. 11:06
이 글의 저작권은 CEnA에 있습니다. 퍼가실 때는 출처를 밝혀주세요.

안드로이드를 개발하다 보면 TextView에 여러 줄을 넣어야 할 때가 생긴다.
그렇지만 TextView란놈이 여러줄이 들어갈경우 공백단위로 줄바꿈이 되는 것이였다.
한글이 들어가고 여러줄이 있다보니 마지막이 너무 들숙 날숙 뒤면서 모양이 정말 엉망으로 보였다.

 

 

보이는 바와 같이 마지막 글자들은 단어가 길어질 경우 아래로 밀리면서 이쁘지 않은 라인을 형성하고 있다.

안드로이드 래퍼런스를 뒤져봐도 안드로이드 자체에 옵션이 없는 걸로 확인되었다.
그래서 구글링을 하게 되었지만...... 나의 검색 능력탓 인지는 모르겠으나 찾지를 못했다....

꽁수로 WebView를 실어서 HTML로 작성하는 방법도 있었다.
하지만 이곳에 WebView를 쓴다는건 내 마음이 허락치를 못했다.
그래서 자동으로 공백기준이 아닌 글자 기준으로 잘라주는 커스텀 TextView를 만들어 보기로 했다.

흠...조금 어려울꺼라 생각이 들었지만 의외로 쉽게 풀렸다. 주 핵심은 breakText 함수란 놈이였다. 

-----------------------------------------------------------

버그 패치 : 2011.08.15
ScrollView 안에서 표지 되지 않은 문제가 발견되어 수정되었습니다.
(ScrollView 에서는 부모 높이 계산을 할수 없어서 인지 높이를 0으로 가져와 TextView 정상적으로 표지 되지 않은 버그가 발견되어 수정하였습니다.)
예전 소스를 가지고 계신분은 다시 받아 가시는게 좋을듯 합니다. ^^
-------------------------------------------------------------
최적화 : 2011.08.21
기존소스를 최적화 하였습니다....군더더기를 좀 뺏네요 ^^
-------------------------------------------------------------
버그 패치 : 2011.08.27
Xml에서 사용할때 오류 나는 문제 수정되었습니다.
-------------------------------------------------------------

추가 : 2011.08.28
onDraw 할때 속성중 Padding 처리가 빠져 있어 추가되었습니다.^^

-------------------------------------------------------------

/**
 * 클래스설명 : 텍스트의 줄바꿈을 공백기준이 아닌 한글자 단위로 한다.
 * @version : 2011. 8. 06.
 * @author : CEnA - mibany
 * @분류 : 
 */
public class CTextView extends TextView {
private int mAvailableWidth = 0;
private Paint mPaint;
private List<String> mCutStr = new ArrayList<String>();

public CTextView(Context context) {
super(context);
}

public CTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}

private int setTextInfo(String text, int textWidth, int textHeight) {
// 그릴 페인트 세팅
mPaint = getPaint();
mPaint.setColor(getTextColors().getDefaultColor());
mPaint.setTextSize(getTextSize());

int mTextHeight = textHeight;

if (textWidth > 0) {
// 값 세팅
mAvailableWidth = textWidth - this.getPaddingLeft() - this.getPaddingRight();

mCutStr.clear();
int end = 0;
do {
// 글자가 width 보다 넘어가는지 체크
end = mPaint.breakText(text, true, mAvailableWidth, null);
if (end > 0) {
// 자른 문자열을 문자열 배열에 담아 놓는다.
mCutStr.add(text.substring(0, end));
// 넘어간 글자 모두 잘라 다음에 사용하도록 세팅
text = text.substring(end);
// 다음라인 높이 지정
if (textHeight == 0) mTextHeight += getLineHeight();
}
} while (end > 0);
}
mTextHeight += getPaddingTop() + getPaddingBottom();
return mTextHeight;
}

@Override
protected void onDraw(Canvas canvas) {
// 글자 높이 지정
float height = getPaddingTop() + getLineHeight();
for (String text : mCutStr) {
// 캔버스에 라인 높이 만큰 글자 그리기
canvas.drawText(text, getPaddingLeft(), height, mPaint);
height += getLineHeight();
}
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
int height = setTextInfo(this.getText().toString(), parentWidth, parentHeight);
// 부모 높이가 0인경우 실제 그려줄 높이만큼 사이즈를 놀려줌...
if (parentHeight == 0)
parentHeight = height;
this.setMeasuredDimension(parentWidth, parentHeight);
}

@Override
protected void onTextChanged(final CharSequence text, final int start, final int before, final int after) {
// 글자가 변경되었을때 다시 세팅
setTextInfo(text.toString(), this.getWidth(), this.getHeight());
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
// 사이즈가 변경되었을때 다시 세팅(가로 사이즈만...)
if (w != oldw) {
setTextInfo(this.getText().toString(), w, h);
}
}
}


그리 길지 않은 코드이다. 사용방법은 2가지가 있다. xml 에서 바로 사용하거나 java 코드에서 생성해서 사용해도 된다.

예를 들자면

<패키지명.CTextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/long_text" android:textColor="#00FF00" />

 

CTextView textView = new CTextView(this);
textView.setText(R.string.long_text);
LinearLayout layout = (LinearLayout)findViewById(R.id.mainview);
layout.addView(textView);

 


뭐 이런식이다.^^ 도움이 필요한 자에게 유용했으면 좋겠다.

이 글의 저작권은 CEnA에 있습니다. 퍼가실 때는 출처를 밝혀주세요.

 

[출처] http://docs.cena.co.kr/?mid=textyle&document_srl=42137

Comments