출처 : http://croute.me/392

예전에 한번 버튼의 클릭이벤트에 대해서 고찰한적이 있었습니다.
onClick()의 구현이 더 좋을까, OnClickListener 객체를 각각 생성해서 구현하는 것이 좋을까에 대한 내용이었습니다.
어쨋든 전 결론을 onClick()의 구현(implements)으로 내렸었죠.

( 버튼 클릭 이벤트 처리에 관한 고찰 : http://croute.me/326 )

이번에는 저번과는 조금 다른 고찰입니다.

수많은 버튼을 사용해야 하는 경우,
하나씩 아이디를 onClick()에서 siwtch 문 안에 case로 정의내려 처리하기는 너무 곤욕이죠. 휴...
그래서 이런 방법을 생각해 보았습니다.

향상된 for문과 배열을 이용하는 방법.

접기

주의 깊게 향상된 반복문(Enhanced For Loop)을 사용하라

향상된 반복문(때로 "for-each"로 알려진 반복문)은 Iterable 인터페이스를 구현한 컬렉션들을 위해 사용될 수 있습니다. 이러한 객체들로, 반복자는 hasNext() 와 next()을 호출하는 인터페이스를 만들기 위해 할당됩니다. ArrayList의 경우 여러분이 직접 탐색하는 것이 좋을 수 있습니다만, 다른 컬렉션들에서는 향상된 반복문 구문이 명시적인 반복자의 사용과 동등한 성능을 보여줍니다.

그럼에도, 다음 코드로 향상된 반복문의 만족스러운 사용법을 볼 수 있습니다:

public class Foo {
    int mSplat;
    static Foo mArray[] = new Foo[27];

    public static void zero() {
        int sum = 0;
        for (int i = 0; i < mArray.length; i++) {
            sum += mArray[i].mSplat;
        }
    }

    public static void one() {
        int sum = 0;
        Foo[] localArray = mArray;
        int len = localArray.length;

        for (int i = 0; i < len; i++) {
            sum += localArray[i].mSplat;
        }
    }

    public static void two() {
        int sum = 0;
        for (Foo a: mArray) {
            sum += a.mSplat;
        }
    }
}

zero() 는 반복되는 매 주기마다 정적 필드를 두 번 부르고 배열의 길이를 한번 얻습니다.

one() 은 참조를 피하기 위해 지역 변수로 모든 것을 끌어냈습니다.

two() 는 자바 언어의 1.5버전에서 소개된 향상된 반복문 구문을 사용합니다. 컴파일러에 의해 생성된 코드는 배열 참조와 배열의 길이를 지역 변수로 복사해주어, 배열의 모든 원소를 탐색하는데 좋은 선택이 될 수 있습니다. 주 루프 내에 추가적인 지역 읽기/저장이 만들어지고(명백하게 "a"에 저장), one()보다 쪼금 느리고 4 바이트 길어지게 하긴 합니다.

좀 더 명확하게 모든 것을 종합하자면: 향상된 반복문 구문은 배열과 잘 동작하지만, 추가적인 객체 생성이 있게 되는 Iterable 객체와 함께 사용할 때엔 조심해야 합니다.

접기



코드는 아래와 같습니다.


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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package me.croute.manybutton;
  
import java.util.ArrayList;
  
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
  
  
/**
 * 많은 버튼이 있을 때 클릭이벤트를 처리하기 위한 예제 코드 * 
 
 * @author croute
 * @since 2011.04.19
 */
public class ManyButtonExampleActivity extends Activity implements OnClickListener
{
    // 여러개의 버튼을 배열로 처리하기 위해 버튼에 대해 배열 선언을 함
    private Button[] mButton = new Button[6];
      
    // 각각 다르게 출력할 스트링을 넣어둘 리스트
    private ArrayList<String> mDataList; 
  
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
  
        mDataList = new ArrayList<String>();
          
        mButton[0] = (Button) findViewById(R.id.main_b_00);
        mButton[1] = (Button) findViewById(R.id.main_b_01);
        mButton[2] = (Button) findViewById(R.id.main_b_02);
        mButton[3] = (Button) findViewById(R.id.main_b_03);
        mButton[4] = (Button) findViewById(R.id.main_b_04);
        mButton[5] = (Button) findViewById(R.id.main_b_05);
  
        // 버튼들에 대한 클릭리스너 등록 및 각 버튼이 클릭되었을 때 출력될 메시지 생성(리스트)
        for(int i = 0 ; i < 6 ; i++)
        {
            // 버튼의 포지션(배열에서의 index)를 태그로 저장
            mButton[i].setTag(i);
              
            // 클릭 리스너 등록
            mButton[i].setOnClickListener(this);
              
            // 출력할 데이터 생성
            mDataList.add("하이" + i + "입니다");
        }
    }
  
    /* (non-Javadoc)
     * @see android.view.View.OnClickListener#onClick(android.view.View)
     */
    @Override
    public void onClick(View v)
    {
        // 클릭된 뷰를 버튼으로 받아옴
        Button newButton = (Button) v;
  
        // 향상된 for문을 사용, 클릭된 버튼을 찾아냄
        for(Button tempButton : mButton)
        {
            // 클릭된 버튼을 찾았으면 
            if(tempButton == newButton)
            {
                // 위에서 저장한 버튼의 포지션을 태그로 가져옴
                int position = (Integer)v.getTag();
                  
                // 태그로 가져온 포지션을 이용해 리스트에서 출력할 데이터를 꺼내서 토스트 메시지 출력
                Toast.makeText(this, mDataList.get(position), Toast.LENGTH_SHORT).show();
            }
        }
    }
}



각각의 버튼을 눌렀을 때 만들어 두었던 데이터대로 잘 출력이 되는군요.









아래는 위 예제에 대한 프로젝트 압출파일 입니다.



+ Recent posts