728x90
오늘은 drawableStart 속성을 활용해 뷰의 옆에 이미지를 넣었을때 그 이미지의 크기를 뷰의 글자 크기에 맞춰 자동으로 조절되게 만들어 보겠습니다.
1.drawableStart에 활용할 이미지를 만들어 둡니다. 이번에 활용할 이미지는 아래와 같이 만들었습니다.
2.activity_main.xml을 다음과 같이 작성해줍니다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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=".MainActivity"
android:orientation="vertical">
<com.example.drawablestart_example.AutoSizeDrawableEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:inputType="text"
android:hint="입력하는 곳"
android:drawableStart="@drawable/outline_images"
android:drawablePadding="3dp"
android:textSize="20sp"/>
</LinearLayout>
=> 이때 com.example.drawablestart_example.AutoSizeDrawableEditText 태그의 com.example.drawablestart_example 부분은 아래에 만들 AutoSizeDrawableEditText 클래스의 패키지 명으로 입력해주세요.
3.커스텀 edittext 클래스를 다음과 같이 작성해줍니다.
public class AutoSizeDrawableEditText extends androidx.appcompat.widget.AppCompatEditText {
//drawablestart 이미지의 높이를 무시하고 해당 Edittext 뷰의 텍스트 높이와 패딩값만을 활용하여 높이를 계산처리해서 보여주는 뷰이며 너비는 무조건 부모뷰의 너비 match_parent 값으로 가져오게 처리했습니다.
public AutoSizeDrawableEditText(Context context) {
super(context);
}
public AutoSizeDrawableEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public AutoSizeDrawableEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//drawablestart 이미지의 높이를 무시하고 해당 텍스트뷰의 텍스트 높이와 패딩값만을 활용하여 높이를 계산처리 로직
// 상위 클래스(즉 원래의 edittext 측정방식)의 측정을 주석처리 합니다.
// 지금 이 뷰는 너비는 무조건 match_parent 이고 높이는 이 뷰의 텍스트 높이 + 패딩값 이기 때문에 super.onMeasure()를 사용하지 않았습니다.
//super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// 부모로부터 제공된 너비 크기입니다, 즉 match_parent를 통해 측정된 부모뷰의 너비 값을 가져옵니다.
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
Paint.FontMetrics fontMetrics = getPaint().getFontMetrics();
// 절대값을 사용하여 텍스트 영역 높이를 계산합니다.
float textHeight = Math.abs(fontMetrics.top) + Math.abs(fontMetrics.bottom);
// 패딩을 포함한 최종 높이를 계산합니다.
int desiredHeight = (int) (textHeight + getPaddingTop() + getPaddingBottom());
// 최종 측정된 너비와 높이를 설정합니다. 너비는 상위 레이아웃의 측정 결과를 사용하고, 높이는 계산된 값을 사용합니다.
setMeasuredDimension(widthSize, desiredHeight);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// 뷰의 높이가 결정된 후 drawableStart의 크기를 조절합니다.
// => 위의 onMeasure()를 활용하여 텍스트와 패딩값을 기준으로한 높이를 결정, 상위 레이아웃의 너비로 결정 한 뒤에 아래의 adjustDrawableSize()를 활용하여 이미지 사이즈를 텍스트 영역의 높이에 맞춰 설정합니다
adjustDrawableSize();
}
private void adjustDrawableSize() {
Drawable[] drawables = getCompoundDrawables();
// drawableStart가 있는지 확인하는 절차입니다.
if (drawables[0] != null) {
Paint.FontMetrics fontMetrics = getPaint().getFontMetrics();
// 절대값을 사용하여 텍스트 영역 높이를 계산합니다
float textHeight = Math.abs(fontMetrics.top) + Math.abs(fontMetrics.bottom);
Drawable drawableStart = drawables[0];
float intrinsicWidth = drawableStart.getIntrinsicWidth();
float intrinsicHeight = drawableStart.getIntrinsicHeight();
// 텍스트 영역 높이 기준으로 비율을 계산합니다 => 텍스트 영역 높이에 비교하여 이미지 실제 높이는 몇분의 몇으로 할지 설정
float scaleFactor = textHeight / intrinsicHeight;
// (텍스트 높이에 맞게 설정한 비율)에 맞게 너비값 계산합니다, int값 변환
int drawableWidth = (int) (intrinsicWidth * scaleFactor);
// 텍스트 높이 값을 int값으로 변환합니다.
int drawableHeight = (int) textHeight;
//위의 너비, 높이 값을 활용해 이미지를 설정해줍니다.
drawableStart.setBounds(0, 0, drawableWidth, drawableHeight);
setCompoundDrawables(drawableStart, drawables[1], drawables[2], drawables[3]);
}
}
}
=> 너비는 상위 레이아웃의 너비를 가져오고 높이는 텍스트의 글자 높이에 맞춰 계산 처리되도록 간단히 만들었습니다.
흐름을 간단히 말씀드리겠습니다..
1. onMeasure()에서 텍스트의 높이 와 패딩값에 맞춰 뷰의 높이를 결정합니다.
2. onSizeChanged() 에서 1에 의해 측정된 높이에 맞춰 이미지의 사이즈를 설정합니다.
실행결과
=>뷰의 textSize 속성에 맞춰 크기가 자동 조절된 drawableStart 이미지가 보이게 됩니다. 만약 textSize를 sp로 설정했다면 기기의 글자 크기 조절 설정 따라 이미지 역시 크기가 변화합니다.
'안드로이드 자바' 카테고리의 다른 글
[JAVA][Android] 네이버 회원 프로필 조회 API 사용하기 (2) | 2024.06.02 |
---|---|
[JAVA][Android] 네이버 로그인 API 사용하기 (0) | 2024.05.15 |
[JAVA][Android] ChatGPT API로 챗봇 만들기 - (2) 리사이클러뷰 만들기 (0) | 2024.05.09 |
[JAVA][Android] ChatGPT API로 챗봇 만들기 - (1) ChatGPT API 사용하기 (0) | 2024.05.03 |
[JAVA][Android] SharedPreferences에 객체 저장하기 (0) | 2024.04.27 |