기존의 코드

 

1. HistoryPicturesAdapter : RecyclerView Adapter

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HistoryPicturesViewHolder {
        itemBinding = ItemHistoryPicturesBinding.inflate(LayoutInflater.from(parent.context))
        return HistoryPicturesViewHolder(itemBinding)
    }

 

 

2. RecyclerView가 포함된 main화면 xml

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/myMushHistory"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"

        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        android:orientation="horizontal"
        tools:listitem="@layout/item_history_pictures"
        >
    </androidx.recyclerview.widget.RecyclerView>

 

 

3. item_history_pictures (리사이클러 뷰 아이템 )

<FrameLayout
        android:layout_width="100dp"
        android:layout_height="100dp"
		...
        >
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
			...
            />
        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            ...
            />
    </FrameLayout>

 

구현하고자 한 디자인

구현하고자 한 디자인이다.

3(아이템)에서 FragmentLayout의 width와 height를 100dp로 고정하여 RecyclerView에 100dp(20dp 패딩)의 정사각형 이미지가 들어가게 만들고자 하였다.

 

 

실제 구동 시 화면

하지만 실제 구동 화면에서는 예상과는 다르게 고정되지 않은 직사각형의 화면 (wrap_content로 보임) 이 보인다.

이전에도 이런 상황이 있었는데, 원인은 viewholder의 LayoutInflater에 있었다.

 

 

 

 

 

 


 

LayoutInflater

LayoutInflater Docs

 

 

 

 

 

여기서 root의 LayoutParams를 제공한다는 말이 이해가 잘 가지 않았다.

'내 코드에서 FrameLayout의 width와 height가 이미 100으로 고정되어 있는데, 내부에서 match_parent를 사용한 TextView와 ImageView의 크기가 왜 100dp로 고정이 안되는 것일까'

 

이는 LayoutParams의 계층 구조에 대한 잘못된 이해로부터 생긴 문제였다.

 

 

 

 

ViewGroup.LayoutParams

레이아웃 Docs

 

 

그림 2에서 볼 수 있듯이, 상위 뷰 그룹이 각 하위 뷰의 레이아웃 매개변수를 정의합니다(하위 뷰 그룹 포함).

 

 

 

 

 LayoutParams가 xml상에서는 View에 속해 있는 것처럼 보이지만, 상위 ViewGroup의 LayoutParams에 정의된다는 것을 이해하면 앞서 본 설명이 이해가 된다.

FrameLayout(예제 xml 상 루트)의 LayoutParams가 부모에 속해 있어 전달이 되지 않았던 것이다.

예로 다음과 같은 코드는 기대와 같이 실행됨을 확인가능했다.

 

예제2

 

<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    >
    <data>
		...
    </data>
    <FrameLayout
        android:layout_height="0dp"
        android:layout_width="0dp"
        >
        <FrameLayout
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:padding="10dp"
            >
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                ...
                />
            <TextView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
               ...
                />
        </FrameLayout>
    </FrameLayout>
</layout>

 

해당 코드는 루트로 껍데기뿐인 프레임레이아웃을 하나 더 감싼 예제로 width와 height를 0dp로 설정한 모습이다.

동일하게 Binding.inflate(LayoutInflater.from(parent.context))으로 inflate 하면, root의 LayoutParams는 전달되지 않아 원래 기대한 뷰의 모습이 실행되는 것이 확인가능했다.

 

 

 

예제2 구동화면

 

예제2 코드는 LayoutParam의 계층 구조를 확인하기 위한 코드로

LayoutInflater.from(context).inflate(R.layout.layout_to_load, parent, false);

를 사용할 시 root의 LayoutParams가 제공되기에 앞선 예제2 코드와 같이 짤 필요는 없다.

 

 

 

 

추가적으로, attachRoot의 경우 true를 하면 inflate와 동시에 parent의 계층 구조에 속하게 되므로, viewholder에는 적합하지 않다. ( 해당 링크의 예시 코드를 보면 inflate 후 addView를 하여 뷰를 추가하는 것이 확인가능하며, attachRoot = ture인 경우 addView가 필요없음을 확인가능하다. )

 

 


 

 

 

수정된 1 어댑터 ( + 기존 Adapter Item XML )

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HistoryPicturesViewHolder {
        itemBinding = ItemHistoryPicturesBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return HistoryPicturesViewHolder(itemBinding)
    }

-> LayoutInflater.from(context).inflate(R.layout.layout_to_load, parent, false);

 

 

 

 

 

수정 후 구동화면

 

 

 

 


 

 

android - Why does LayoutInflater ignore the layout_width and layout_height layout parameters I've specified? - Stack Overflow

 

Why does LayoutInflater ignore the layout_width and layout_height layout parameters I've specified?

I've had severe trouble getting LayoutInflater to work as expected, and so did other people: How to use layoutinflator to add views at runtime?. Why does LayoutInflater ignore the layout parameter...

stackoverflow.com

 

 

 

레이아웃  |  Android 개발자  |  Android Developers

 

레이아웃  |  Android 개발자  |  Android Developers

레이아웃은 활동 또는 앱 위젯의 UI와 같은 사용자 인터페이스의 시각적 구조를 정의합니다. 두 가지 방법으로 레이아웃을 선언할 수 있습니다. Android 프레임워크를 통해 이 두 가지 메서드의 하

developer.android.com

LayoutInflater  |  Android Developers

 

LayoutInflater  |  Android Developers

 

developer.android.com

+ Recent posts