리플렉션(Reflection)을 활용한 안드로이드 위젯 매핑(Mapping) 간소화 하기
안드로이드 어플을 만들다보면 안드로이드 위젯(Widget)을 매핑하는 코드를 작성합니다.
위젯이 3~4개 정도면 쉽게 작성할 수 있지만 복잡한 액티비티(Activity)의 경우는 십여개가 넘는 위젯이 존재하고 아래와 같은 코드의 반복이 일어납니다.
자바의 리플렉션을 활용하면 아래의 코드를 간소화 할 수 있습니다.
1
2
3
4
| EditText trackEditText = (EditText) findViewById(R.id.title); EditText artistEditText = (EditText) findViewById(R.id.artist); EditText albumEditText = (EditText) findViewById(R.id.album); TextView pathTextView = (TextView) findViewById(R.id.path); |
리플렉션을 활용하여 자바 객체의 필드를 모두 가져온 후 activity.getResources().getIdentifier(identifierString, “id”, activity.getPackageName()) 메소드를 활용하여 R.java 에 정의된 id 값을 추출 후 이 값으로 다시 findViewById 메소드로 View를 다시 조회하여 해당 객체를 필드에 값을 주입(Injection)하는 단계를 거칩니다.
이 방법의 전제는 위젯의 id 값과 필드의 이름이 일치한다는 규칙을 정한 것이여서 사용하려면 유의해야 합니다. 하단의 XML의 id값과 필드명을 유심히 살펴보세요~
src/org/softwaregeeks/needletagger/Editor.java
1
2
3
4
5
6
7
8
9
10
11
| private EditText trackEditText; private EditText artistEditText; private EditText albumEditText; private TextView pathTextView; @Override public void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.editor); UIHelper.mappingViews( this ); } |
res/layout/editor.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| <? xml version = "1.0" encoding = "utf-8" ?> < LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android" android:layout_width = "fill_parent" android:layout_height = "fill_parent" > < EditText android:id = "@+id/trackEditText" android:layout_width = "fill_parent" android:layout_height = "wrap_content" /> < EditText android:id = "@+id/artistEditText" android:layout_width = "fill_parent" android:layout_height = "wrap_content" /> < EditText android:id = "@+id/albumEditText" android:layout_width = "fill_parent" android:layout_height = "wrap_content" /> < TextView android:id = "@+id/pathTextView" android:layout_width = "fill_parent" android:layout_height = "wrap_content" /> </ LinearLayout > |
실제 리플렉션을 활용하여 매핑하는 메소드는 다음과 같습니다. 그럼 도움이 되셨길 바랍니다~ :D
org/softwaregeeks/framework/android/util/UIHelper.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
| package org.softwaregeeks.framework.android.util; import java.lang.reflect.Field; import android.app.Activity; import android.view.View; import android.widget.TextView; public class UIHelper { public static void mappingViews(Object object) { if ( !(object instanceof Activity) ) return ; Activity activity = (Activity)object; Field[] fields = activity.getClass().getDeclaredFields(); for (Field field : fields) { String identifierString = field.getName(); int identifier = activity.getResources().getIdentifier(identifierString, "id" , activity.getPackageName()); if ( identifier == 0 ) continue ; View findedView = activity.findViewById(identifier); if ( findedView == null ) continue ; if ( findedView.getClass() == field.getType() ) { try { field.setAccessible( true ); field.set(object, findedView); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } } } } |
// 사용하려면 필드명과 id를 일치시켜야됨..
// 편해지려면 익숙해져야지 될것 같다.
// 원글: http://blog.softwaregeeks.org/archives/616#more-616
본 블로그는 페이스북 댓글을 지원합니다.