[안드로이드] Adapter에서 inflate하는 view의 layout_height가 무시될 때
안녕하세요. 개발자 드리머즈입니다.
RecyclerView에서 사용하는 Recycler.ViewHolder(Adapter)의 onCreateViewHolder()에서 생성되는 view의 android:layout_height="45dp" 속성이 무시되는 문제를 발견했습니다. 아래의 xml 코드에서 가장 상위에 위치한 RelativeLayout의 android:layout_height가 무시됐습니다.(마치 wrap_content처럼 동작함) RelativeLayout의 child view의 android:layout_height는 무시되지 않고 정상적으로 동작했습니다.
item_header_row.xml 또는 item_content_row.xml
1 2 3 4 5 6 7 | <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="45dp" > (...생략...) </RelativeLayout> | cs |
위의 xml이 inflate되는 Recycler.ViewHolder(Adapter)의 코드는 아래와 같았습니다.
1 2 3 4 5 6 7 8 9 10 11 | // Create new views (invoked by the layout manager) @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == ITEM_TYPE_HEADER) { View headerRow = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_header_row, null); return new ItemHeaderViewHolder(headerRow); // view holder for header items }else/* if (viewType == ITEM_TYPE_NORMAL)*/ { View normalView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_content_row, null); return new ItemContentViewHolder(normalView); // view holder for normal items } } | cs |
이 코드에 문제가 없는 줄 알았는데 그게 아니었습니다. 꺼림칙하게도 Android Studio에서 아래의 워닝?을 보여주고 있었습니다.
When inflating a layout, avoid passing in null as the parent view, since otherwise any layout parameters on the root of the inflated layout will be ignored.
해석을 하면,
레이아웃을 inflate할 때 parent view로 null을 넣는 것을 피하세요. 만약 그렇게 하지 않으면 inflate된 레이아웃의 root에 대한 모든 layout 파라미터들은 무시될 것이기 때문입니다.
이와 문제에 대한 설명이 있는 링크도 있습니다.(https://possiblemobile.com/2013/05/layout-inflation-as-intended/)
하지만 설명이 너무 길어 요점만 말하겠습니다.
1 2 | inflate(int resource, ViewGroup root) inflate(int resource, ViewGroup root, boolean attachToRoot) | cs |
inflate함수는 위의 두 종류가 존재하는데 1번째 함수를 사용하면서 2번째 인자에 null을 주면 inflate된 레이아웃의 root에 대한 모든 layout 파라미터들이 무시된다는 것입니다. 그래서 2번째 함수를 아래처럼 사용하면 됩니다.
1 2 3 4 5 6 7 8 9 10 11 | // Create new views (invoked by the layout manager) @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == ITEM_TYPE_HEADER) { View headerRow = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_header_row, parent, false); return new ItemHeaderViewHolder(headerRow); // view holder for header items }else/* if (viewType == ITEM_TYPE_NORMAL)*/ { View normalView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_content_row, parent, false); return new ItemContentViewHolder(normalView); // view holder for normal items } } | cs |
2번째 인자에는 적당한 값을 넣고(parent를 넣으면 됨) 3번째 인자를 false로 설정하는 것이 핵심입니다.
3번째 인자를 false로 지정하는 것은 2번째 인자를 사용하지 않겠다는 의미라서 2번째 인자는 중요하지 않은 것 같습니다.
이렇게 함수를 수정하고나니 무시되었던 android:layout_height="45dp" 속성이 정상적으로 적용됨을 확인했습니다.
댓글 영역