imageView를 화면 조건에 따라 다양하게 변화를 주기 위해서는 code 내에서 동적으로 parameter를 변경해야 할 필요가 있습니다. 이 문서에서는 imageView의 margin을 코드에서 수정하는 방법을 정리하려고 합니다.
Xml로 조절하는 방법
layout xml 파일에서는 imageView의 margin은 다음과 같이 조절합니다.
<ImageView
android:id="@+id/iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"/>
LayoutParams
설정하는 parameter 의 공통점을 보면 layout_ 으로 시작하는 특성들입니다. layout_으로 시작하는 특성은 ViewGroup.LayoutParams 클래스에서 상속받습니다. LayoutParams 은 imageView와 같은 view 클래스가 배치되는 방식 즉 layout을 부모클래스에 알려주는 역할을 합니다. ViewGroup.LayoutParams 의 xml 특성은
android:layout_height
android:layout_width
2가지 입니다. 각각 높이와 폭을 조절하는 특성입니다. margin 특성은 ViewGroup.LayoutParams을 상속하는 ViewGroup.MarginLayoutParams 클래스에서 정의하고 있습니다.
android:layout_margin
android:layout_marginBottom
android:layout_marginEnd
android:layout_marginHorizontal
android:layout_marginLeft
android:layout_marginRight
android:layout_marginStart
android:layout_marginTop
andorid:layout_marginVertical
위, 아래, 좌, 우를 동일한 값으로 여백을 설정할 경우 : layout_margin
좌,우를 동일한 값으로 여백을 설정할 경우: layout_marginHorizontal
위, 아래를 동일한 값으로 여백을 설정할 경우: layout_marginVertical
위, 아래, 좌, 우는 각각 marginTop, marginBottom, marginLeft, marginRight 를 사용합니다.
marginStart와 marginEnd 는 시작하기 전, 끝나는 지점 이후 의 여백을 설정합니다.
marginStart와 marginLeft는 동일한 효과를 볼 수 있기는 하지만, 이는 한글이나 영어에서 그렇습니다.
우리 처럼 왼쪽에서 시작하여 오른쪽으로 문자를 쓰는 경우는 start와 left가 같지만,
오른쪽에서 왼쪽으로 문자를 쓰는 경우에는 start와 right가 같은 효과를 냅니다.
아랍어와 히브리어 등이 오른쪽에서 왼쪽으로 문자를 사용하는 방식입니다.
Code에서 여백 설정
LayoutParams 을 변경하여 code에서 여백을 설정합니다. ViewGroup.MarginLayoutParams 속성을 상속받는 클래스인 GridLayout.LayoutParams 나 ActionBar.LayoutParams, LinearLayout.LayoutParams, RelativeLayout.LayoutParams, FrameLayout.LayoutParams 등을 사용하여 imageView의 여백을 설정합니다.
아래 코드는 LinearLayout.LayoutParams 를 사용하여 여백을 설정하는 예입니다.
val layout = binding.layout
val parameter = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT
)
parameter.leftMargin = 10
parameter.rightMargin = 10
val newImageView = ImageView(context)
newImageView.layoutParams = parameter
newImageView.setImageResource(R.drawable.id)
layout.addView(newImageView)
먼저 LinearLayout.LayoutParams 객체를 생성합니다.
val parameter = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT
)
LinearLayout.LayoutParams을 폭과 높이 값을 넣어 생성했습니다. 생성하는 방법은 아래와 같이 6개가 있습니다.
LayoutParams(Context c, AttributeSet attrs)
LayoutParams(int width, int height)
LayoutParams(int width, int height, float weight)
LayoutParams(ViewGroup.LayoutParams p)
LayoutParams(ViewGroup.MarginLayoutParams source)
LayoutParams(LinearLayout.LayoutParams source)
폭과 높이에서 사용하는 int 값은 pixel 단위로 입력할 수 있습니다. ViewGroup.LayoutParams.MATCH_PARENT 와 ViewGroup.LayoutParams.WRAP_CONTENT 도 사용할 수 있습니다. MATCH_PARENT 부모 view 개체와 같은 크기로 설정됩니다. 이 경우 여백을 설정할 때 padding을 사용하는 것이 좋습니다. WRAP_CONTENT 은 내부 content의 크기 즉 imageView의 경우 image 크기에 충분한 크기로 설정됩니다.
생성한 LinearLayout.LayoutParams 객체의 속성을 추가로 수정하여 여백을 조절합니다. 앞서 생성한 LayoutParams 객체의 이름이 parameter이기 때문에 아래 코드와 같이 값들을 조절합니다.
parameter.leftMargin = 10
parameter.rightMargin = 10
여백 적용
val newImageView = ImageView(context)
newImageView.layoutParams = parameter
newImageView.setImageResource(R.drawable.id)
layout.addView(newImageView)
val newImageView = ImageView(context)
로 ImageView를 생성하고, 앞서 생성한 LayoutParams 을
newImageView.layoutParams = parameter
와 같은 방식으로 설정합니다.
newImageView.setImageResource(R.drawable.id)
는 drawable 폴더에 있는 id라는 이미지 파일을 imageView에 표시하도록 설정하는 code이며,
layout.addView(newImageView)
로 부모객체에 imageview를 추가합니다.
leftMargin = 10
에서 10은 10 pixel을 의미합니다.
parameter.setMarginStart(10)
parameter.setMarginEnd(10)
와 같이 한글에서는 setMargineStart와 setMargeinEnd 로 변경하여 사용할 수 도 있다. 입력하는 값은 pixel값입니다. 경우에 따라 pixel 값이 아니라 dp 값이 유리할 수 있습니다.
pixel 대신 dp 값 사용
dp 값을 pixel로 변화시키는 함수
private fun dpToPixel(input :Float):Int {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, input,
getResources().getDisplayMetrics()).toInt()
}
변환 함수를 사용하면
parameter.leftMargin = dpToPixel(10f)
parameter.rightMargin = dpToPixel(10f)