findVIewById에 관하여
조회수 3742회
안녕하세요 안드로이드 코딩을 하다가 갑자기 궁금한 것이 생겨서 질문올려요!
그림을 보시면
작은 네모( 파란색으로 구분이 되어있는)들이 총 16개가 있는데 이 것들은 모두 TextView입니다. 그리고 빨간색 네모는 LinearLayout으로 구분한 것입니다.
빨간색 네모(총 4개)끼리는 연관이 없지만, 빨간색 네모 안에 있는 파란색 네모 4개끼리는 나름 연관이 있습니다.
이 화면을 하나의 Activity xml 파일 안에 전부 다 넣으면 복잡할 것 같고, 16개의 TextView에 id를 하나씩 부여하기에는 너무 많고 하여 밑의 코드처럼 include를 사용해서 파일을 분리시키고 id의 개수도 줄였습니다.
[horizontal.xml]
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<TextView
android:id="@+id/text_horizontal_1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center" />
<View //라인 구분을 위한 뷰
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="#ccc" />
<TextView
android:id="@+id/text_horizontal_2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center" />
</LinearLayout>
[vertical.xml]
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<include
android:id="@+id/vertical_1"
layout="@layout/horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" />
<View //라인 구분을 위한 뷰
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#ccc" />
<include
android:id="@+id/vertical_2"
layout="@layout/horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" />
</LenearLayout>
[content_main.xml]
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".MainActivity"
tools:showIn="@layout/activity_main">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="horizontal">
<include
android:id="@+id/main_11"
layout="@layout/vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" />
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="#000" />
<include
android:id="@+id/main_12"
layout="@layout/vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#000" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="horizontal">
<include
android:id="@+id/main_21"
layout="@layout/vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" />
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="#000" />
<include
android:id="@+id/main_22"
layout="@layout/vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
XML코드는 이런식으로 하였습니다.
이제 JAVA 코드로 가서
[MainAcitivity.java]
public static final int[] main_id = { R.id.main_11, R.id.main_12, R.id.main_21, R.id.main_22 }
public static final int[] vertical_id = { R.id.vertical_1, R.id.vertical_2 }
public static final int[] text_id = { R.id.text_horizontal_1, R.id.text_horizontal_2 }
View[] main_2by2 = new View[main_id.length];
public void setView() {
for ( int z = 0 ; z < main_id.length ; z++ ) {
main_2by2[z] = findViewById(main_id[z]);
for ( int x = 0 ; x < vertical_id.length ; x++ ) {
View[] vertical = new View[vertical_id.length];
vertical[x] = main_2by2[z].findViewById(vertical_id[x]);
for ( int y = 0 ; y < text_id.length ; y++ ) {
TextView[] text = new TextView[text_id.length];
text[y] = (TextView) vertical[x].findViewById(text_id[y]);
text[y].setText( z + "," + x + "," + y );
}
}
}
}
이런식의 참조를 하였습니다.
저 코드를 실행해 보면 화면에는
이렇게 나오게 됩니다.
데이터 들의 연관성들을 생각해서 저러한 3차원 배열 구조를 생각하게 되었습니다.
그런데 지금 findViewById를 코드상으로 적은 것은 3번 뿐이지만, for문을 돌다보면 빨간 네모(z), 세로(x), 텍스트뷰(y) 이렇게 해서 총 28번을 부르게 됩니다.
findViewById가 성능상으로 않좋다는 것을 들어본적이 있는데, 혹시 저러한 뷰 배치를 다르게 할 방법이 있을까요? 3차원 배열은 제가 xml코드나 java코드를 조금 줄여보고자 저렇게 한 것이므로 다른 방법이 있다면 추천 부탁드립니다!
또한 제가 지금 TextView들을 setView() 메소드를 벗어나면 참조를 할 수가 없는 형태로 되어있는데, 저 16개의 TextView의 텍스트 전체를 바꿀 일이 있다면 setView() 메소드를 다시 부르게 됩니다. 즉 findViewById를 다시 하는거지요.... 이게 굉장히 않좋다는 것은 알고 있는데, TextView를 TextView[][][] text = new TextView[4][ 2][ 2]; 이렇게 하면 메모리 상으로 좋지 않을 것 같아서 이렇게 하지 않았습니다.
findViewById를 다시 하는 것과 TextView[ 4 ][ 2][ 2]를 가지고 있는 것 어떤 것이 더 좋은 방법 일까요?
질문이 길어졌습니다...ㅠ 죄송합니다.. ㅠㅠ
-
(•́ ✖ •̀)
알 수 없는 사용자
1 답변
-
안드로이드에서 그리드 스타일의 뷰를 구성하기 위한 위젯들을 제공하는데요. 올려주신 코드처럼 직접 레이아웃을 구성하는 것도 방법이지만 안드로이드에서 제공하는 API를 활용하는 것이 시간적 비용, 가독성, 성능, 유지보수 측면에서 이점이 있을 것 같습니다.
GridLayout
- http://code.tutsplus.com/tutorials/android-user-interface-design-creating-a-numeric-keypad-with-gridlayout--mobile-8677
- http://sampleprogramz.com/android/gridlayout.php
GridView
RecyclerView(GridLayoutManager)
FlexboxLayout (최근에 공개)
그리고 성능은 findViewById의 호출이 문제가 될 수도 있고 아닐 수도 있을 것 같습니다. ListView나 RecyclerView에서는 그런 문제를 회피하기 위해서 ViewHolder 패턴이 존재하는 것은 사실이고요. 다만 직접 구현하신 뷰가 고정적이고 빈번하게 노출되거나 자주 업데이트 되지 않는다면 기준 자체가 모호해질 수 있습니다. 오히려 중첩된 뷰 구조를 플랫하게(평평하게) 펼치는 작업이 랜더링 성능에 더 효과적일 수도 있고, 그리드를 포함하는 하나의 커스텀 뷰를 만드는 것도 방법이 될 수 있습니다.
Hashcode에 findViewById 관련된 질답이 있어서 링크 남겼습니다.
-
(•́ ✖ •̀)
알 수 없는 사용자 -
(•́ ✖ •̀)
알 수 없는 사용자 - 〉
댓글 입력