안드로이드 어플을 만들다보면 안드로이드 위젯(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;@Overridepublic 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(); } } } }} |
