TextView 내부 크기 구하기 - Rect, getPaint()

Posted by ITPangPang
2016. 10. 17. 23:22 안드로이드(android)/View


TextView 내부 크기 구하기

Rect, getPaint()


ㆍ 음 이번내용은 많이 쓰이지는 않을 것 같은데

    그래도 알고 있으면 은근히 도움되는 내용입니다.



ㆍ 제목 그대로 TextView 내부 크기를 구하는 방법입니다





먼저 시작하기전에

TextView 하나 놓고

시작하겠습니다.


TextView 하나 만들기


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.tistory.itpangpang.textviewex.MainActivity">

<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello World"
android:textColor="#FFFFFF"
android:background="#000000"/>
</RelativeLayout>


이렇게 하나 만들어 놓겠습니다.


여기서 우리가 일반적으로

TextView의 크기를 구하거나

또는 특정 View의 크기를

구할때는 getWidth, getHeight

쓰면 됩니다.


Log로 찍어보죠

public class MainActivity extends AppCompatActivity
{
TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView)findViewById(R.id.tv);

new Handler().postDelayed(new Runnable()
{
@Override
public void run()
{
Log.d("ITPANGPANG","TextView Width : "+tv.getWidth());
Log.d("ITPANGPANG","TextView Height : "+tv.getHeight());
}
},1000);
}
}


이렇게 하면 

Width,Height를

구할 수 있겠죠


딜레이를 준 이유는

안주면 0이 나오기 때문..


0이 나오는 이유는

View카테고리에서

화면 해상도구하기 ~라는글에서

잠깐 설명한 기억이 있네요



결과를 보면

잘 나온것 같습니다.


그런데 Text를 구체적으로

다루기에는

너무 애매합니다.


위에서 텍스트 몇자를 더 추가하고

똑같이 실행시켜 보면



3333을 추가했는데도

Width, Height값은

그대로 입니다.


자 그럼 TextView 내부

Text의 크기를 구하려면

어떻게 할까요?


Rect, getPaint를 이용하자


자 바로 TextView

안에 Text의 크기를 구하는

코드를 보겠습니다

public class MainActivity extends AppCompatActivity
{
TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView)findViewById(R.id.tv);
Rect realSize = new Rect();
tv.getPaint().getTextBounds(tv.getText().toString(), 0, tv.getText().length(), realSize);


Log.d("ITPANGPANG","TextView Width : "+realSize.width());
}
}


눈으로 훅 한번 

슬며시 보면


tv.getPaint

TextView에서 그려진 것중에


getTextBounds

Text의 Bounds (경계선 정도의 느낌이죠)



tv.getText().toString()

TextView 내부에 있는 모든

Text


0, tv.getText().length()

0 ->(즉 시작부터)

tv.getText().length() -> 텍스트의 길이만큼


realSize(Rect)

Rect -> Rectangular죠

사각형 모양으로 영역을 잡아라



뭐 이정도 뜻이 되겠네요

위에 사진의 빨간색 사각형

영역이라고 생각하시면 됩니다.


어쨋든 이렇게 

realSize(Rect)에 담은후에


그 담은 것을 측정하면 끝입니다!!


Hello World 3333

의 크기는 212입니다.


이번에는 3333을 제거하면

크기가 141로 줄어 든 것을

확인 할 수 있습니다



음,, 이걸 어디다가

써먹을지??는

너무 다양할 것 같아서


일단 써먹기전에 눈으로

보기좋게 조금이라도 꾸며보면


TextWatcher 일단 달기


글자가 늘어나거나

줄어들때마다


TextView 내부 전체 Text의

 크기도 실시간으로 알아보는

코드로 수정했습니다



자바 코드는

이런식으로

대충대충 작성했습니다.


public class MainActivity extends AppCompatActivity
{
TextView tv;
TextView tv2;
EditText et;
Rect realSize;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView)findViewById(R.id.tv);
tv2 = (TextView)findViewById(R.id.tv2);
realSize = new Rect();
et = (EditText)findViewById(R.id.et);
et.addTextChangedListener(new TextWatcher()
{
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after)
{
}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{
tv.setText(et.getText().toString());
tv.getPaint().getTextBounds(tv.getText().toString(), 0, tv.getText().length(), realSize);
tv2.setText(""+realSize.width());
}

@Override
public void afterTextChanged(Editable s)
{
}
});

}
}


음..

이걸로 뭘 해볼 수 있을까요?


갑자기 쓰려니 생각이 안나네요..


간단하게 TextSize를 실시간으로

바꿔보도록 하겠습니다.


TextView 한 줄을 넘지 않도록!!


음 위에 내용을 토대로

EditText에서 글을 입력했을때

TextView에 그대로 찍히는데

한줄이 넘어가면 Text의 크기를

줄여보도록 하겠습니다.



이런 느낌의 결과를

만들어보겠습니다


코드를 보면

public class MainActivity extends AppCompatActivity
{
TextView tv;
TextView tv2;
EditText et;
Rect realSize;
int defaultSize;
int i;

@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView)findViewById(R.id.tv);
tv2 = (TextView)findViewById(R.id.tv2);

new Handler().postDelayed(new Runnable()
{
@Override
public void run()
{
i = tv.getWidth();
}
},500);

defaultSize = 15;
tv.setTextSize(defaultSize);

realSize = new Rect();
tv.getPaint().getTextBounds(tv.getText().toString(), 0, tv.getText().length(), realSize);

et = (EditText)findViewById(R.id.et);
et.addTextChangedListener(new TextWatcher()
{
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after)
{
}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{
tv.setText(et.getText().toString());
tv.getPaint().getTextBounds(tv.getText().toString(), 0, tv.getText().length(), realSize);
tv2.setText(""+realSize.width());

if(realSize.width()>i)
{
defaultSize--;
tv.setTextSize(defaultSize);
}
}
@Override
public void afterTextChanged(Editable s)
{
}
});
}
}


음 아주 정리가 안된

지저분한 코드지만..


그래도 차례대로 보면

new Handler().postDelayed(new Runnable()
{
@Override
public void run()
{
i = tv.getWidth();
}
},500);

앱을 실행시키면 TextView

Width 값을 i에 저장합니다



defaultSize = 15;
tv.setTextSize(defaultSize);

여긴 Text의 기본

글씨크기를 정해줍니다.


if(realSize.width()>i)
{
defaultSize--;
tv.setTextSize(defaultSize);
}

EditText에 글자가 입력될때마다

비교해줍니다


Text의 Width값이

TextView의 Width값보다 크면

글씨크기를 하나씩 줄여줍니다.


여기까지만 대충 만들어 봤습니다.

사실 간단하게 쓰려고 했는데

생각보다 길어져서 귀찮은것도 있구 ㅠ.


만약 여기서 좀 더 

업그레이드 해서 글자크기를

키우기도 하려면


글자크기가 줄어들때

Text전체크기를 저장해놓고

다시 그 값이 되면 늘리던가

하면 되겠죠?


끝!