PROGRAMMING WORKSHOP

Android|
Implements 라는 키워드의 이해와 활용

앞페이지에서 처음 부터 버튼을 너무 많이 만들어서 질려 버리고
포기하시는 분도 있을 것 같은 걱정이 된다
그러나 악착같은 분들은 걱정없이 달려 들 것이고..
아마도 VBA에 어느 정도 이력이 나신 분들은..의아하게 생각하는 것이 있었을 것이다
아니 버튼 마다 이벤트프로시져(CallBack 메소드)를 일일이 달아주는 것은
너무 많은 중복이 되는 것이 아닌가????
Java가 무지하게 효율적인 언어라고 들었는데 뭔가..좀 그렇다!!라는 생각!!
을 갖였다면 무지하게 다행스럽고 신나는 일
그래서 앞페이지의 내용을 좀 똑똑하게 정리 해 보자
똑같이 하면 재미없으니까..버튼 두개를 달아서 하나를 크릭하면
바탕색이 빨강색으로, 두번째버튼을 크릭하면 바탕색이 노랑색으로
바뀌는 지극히 간단하지만 이벤트프로시져(CallBack 메소드)를 이해하기 위한 것이다
한가지는 앞페이지에서 한 방법,
다른 한 방법은 개선된 프로그래머다운 방법

관심을 갖을 것은
버튼 개체를 만드는 것
화면바탕에 접근 하는 것
색상을 넣는 것
이벤트를 한곳에 몰아 버리는 방법

Implements라고 하는 키워드에 익숙하게 된다
본래 Implements는 좀더 길게 이야기 하면 Implements of Interface라고 하는 말이 된다
Implements는 무언가 시행하다, 실천하다라는 의미의 단어다
그러니까 Interface를 사용하겠다는 이야기가 된다
이것은 Java 뿐만아니라 모든 프로그래밍에서 통하는 키워드이다
VBA에는 없지만, 백프로 개체지향적인 VB.Net, C++, Java등에서는 기본적인 키워드인 것이다
이것을 지금 깊이 설명하기에는 골에 지진이 날수가 있지만..
개체지향프로그래밍에서 3개의 컨셉이 있고

Encapsulation---모든 것을 캡슐속에 감싸고 있는 것
Inheritance----개체끼리의 상속성..다른 개체에 이미 있는 것을 또 만들 필요없다, 상속하여 사용한다
polymorphism----다형성..하나의 개체로 하위개체와 연계하여 다양한 형태로 변신..

이중에서 Implements of Interface는 세번째 Polymorphism개념에 해당하는 것이다
사람의 얼굴의 원판은 같은데 다양하게 변한다고 생각하시면 좋겠다
즉 버튼도 OnClick 메소드가 필요한 것이고
이미지버튼도 OnClick 메소드가 필요 한 것이고..
체크박스도 OnClick 메소드가 필요할 것이다..
이렇게 이곳 저곳에서 모두 필요한 것을 일일이 개체의 크래스모듈마다
갖고 있는 다는 것은 비경제의 원단이고, 중복을 무지하게 싫어하는
컴퓨터 프로그래밍에서 어떤 조치를 하지 않을수 없는 것이다
그러니 유사한 개체들이 공통으로 사용하는 것들을 모아서 하나의 추상적개체를
만들어 놓고 사용하려고 노력하는 것이고 그것이 Polymorphism인것이다
이 개념은 VB.Net코너에서 이야기할 크래스와 똑같은 이야기니 관심을 갖는 것이
좋을 것이다

아래와 같이 두개의 버튼을 만들어 넣었다
xml문을 그대로 복사하여 붙여 넣으시면 된다

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/activity_main" > <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginLeft="99dp" android:layout_marginTop="141dp" android:text="Button" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/button1" android:layout_centerVertical="true" android:text="Button" /> </RelativeLayout>

이제 버튼에 지능을 심어주는 과정에서..
앞페이지에서 했던 것을 쉽게 이해하게 다시 간단하게 요약하도록 하고
이벤트프로시져를 만드는 방법을 두가지로 다시 해보도록 한다
앞페이지에서 한 방법대로 그대로 하면 아래와 같다

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        Button btnOne = (Button) findViewById(R.id.button1);
        btnOne.setOnClickListener(new View.OnClickListener() {
			
			public void onClick(View v) {
				// 이곳에 작업할 내용을 작성하고
				
			}
		});
        
        Button btnTwo = (Button) findViewById(R.id.button2);
        btnTwo.setOnClickListener(new View.OnClickListener() {
			
			public void onClick(View v) {
				// 이곳에 작업할 내용을 작성하고
				
			}
		});
    }

    
    
}

위에서 두개의 버튼을 각각 프로시져와 연결이 되어 있다
하나의 프로시져로 두개의 버튼이던 열개의 버튼이던 처리하게 할 수 없나???
그래야 효율적이지..그래서 아래와 같이 차근,차근 쫓아서 해보시기 바란다



아래와 같은 크래스모듈의 Activity 와 { 사이에

public class MainActivity extends Activity{

public class MainActivity extends Activity implements View. {

implements View. 라고 쩜을 치면 목록상자가 나타난다..
수많은 인터페이스중에서 시행하고 싶은 (Implement하고 싶은)것을 선택하라는 것이다
목록에서 보듯이 수많이 제공되는 Interface중에서..
View개체는 앞에서 언급했지만 모든 콘트롤개체의 상위개체이고
모든 콘트롤 개체는 View개체의 성질머리를 상속받는다
그중에서 OnClickListener 라는 것을 사용하겠다고 선택후 엔터키를 탁쳐주면 된다
그러면 아래의 그림과 같이 크래스명밑에 물결무늬 밑줄이 얹찮게 나타난다



이런 물결밑줄은 항상에러이거나 경고이거나, 조언을 하는 대화상자가 마우스를
갖대 대면 나타난다..
이것도 마우스를 갖다대면 add unimplemented method 라는 것이 처음에 나타난다
이것은 OnClickListener라는 것을 사용하겠다고 해놓고 코드상에는 아직 사용하지
않고 있다는 경고표시인 것이다
이 add unimplemented method( 아직 실행안된 메소드 추가하세요!!)를 크릭해주면

public class MainActivity extends Activity implements View.OnClickListener {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);    
    }

	public void onClick(View v) {
		// TODO Auto-generated method stub
		
		
	}

}

위의 빨강색으로 메소드가 하나 만들어졌다
Click이벤트가 발생하는 모든 콘트롤은 이것을 사용할수 있는 것이다
버튼이 한개이던 백개이던 상관없이 이 메소드를 사용하면 된다
그런데 각 콘트롤이 이것을 사용하겠다는 선언은 해주어야 한다
그래야 해당 콘트롤에 Click이벤트가 발생하면 이 메소드를 찾아 들어가는 것이다
이 메소드는 자신을 사용하겠다고 들어 오는 놈만 처리해주면 된다
아래와 같이 코딩 해보자

public class MainActivity extends Activity implements View.OnClickListener {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);   
        
        findViewById(R.id.button1).setOnClickListener(this);
        findViewById(R.id.button2).setOnClickListener(this);
		
    }

	public void onClick(View v) {
		// TODO Auto-generated method stub
		
		switch(v.getId()){
		case R.id.button1:
			findViewById(R.id.activity_main).setBackgroundColor(Color.RED);
			break;
		case R.id.button2:
			findViewById(R.id.activity_main).setBackgroundColor(Color.BLUE);
			break;
		}
		
	}

}

VB에서는 Select ~ Case문은 Java에서는 Switch 문으로 표현한다
그런데 주의할 점은
VB에서는 Case가 하나 실행되면 더 이상 실행되지 않고 Select문을 나가지만
Java에서는 멍청이 같이 ..
Case를 실행하고 또 다음 Case를 실행한다..별도의 조치가 없는 한
맨 마지막 Case문을 실행하고 마는 셈이다..
똑똑한 놈이 가끔 바보짓을 하는 것중에 이런 것이 있는 셈이다..
물론 이렇게 실행하여야 하는 경우도 있을 수도 있을 것이다
첫번 Case에서는 어떤 일을 해주고, 다음 Case에서는 추가적으로 또 다른 일을
해주고..등등 추가적인 어떤 작업을 실행시킬수도 있을 것이니까..
절대 바보짓은 아닌 것이다..그러나 위의 경우에서는 바보다..
아무튼 그런 기능때문에 Java에서는 항상 Break; 문을 넣어주어야 한다
이 Case 문이 끝났으니까...더 이상 Switch문 내에 있을 필요 없다는 명령이다

Switch문에서 조건을 따지는 변수는 v.getID() 에서 얻어지는 값이다
여기에서 매개변수로 전달 받은 v는 버튼 개체(View v 라고 한것은 버튼은 View개체에
속하는 개체..콘트롤에 해당하는 것은 모두 View라는 개체에서 관리한다고 했다
그래서 View v는 콘트롤 개체를 매개변수로 전달 받는 다는 것이고
이것은 이벤트를 발생시킨 콘트롤(View)가 되는 셈이다
v.getID()는 해당 개체의 ID값을 알아 내는 것이고 ..그럼 어떤 개체인지
Case문에서 비교하면서 해당 개체에 대한 작업을 하게 되는 것!!

그리고 처음 이벤트를 사용하겠다고 호출한 메소드

findViewById(R.id.button2).setOnClickListener(this);

에서 전달 하는 매개변수 this가 곧 onClick(View v)메소드의 View v에
해당 하는 것..this 는 VBA에서 워크시트모듈에서 Me라고 하였던 단축적표현과
같은 것이다
그러니 아래의 경우의 this는
findViewById(R.id.button2).setOnClickListener(this);
R.id.button2라는 ID를 갖고 있는 개체자체를 매개변수로 전달하는 것이다

좀 헷갈리겠지만 조금 참고 익숙해지면 별것 아님을 알게 될 것이다
이렇게 개체를 첫째버튼을 크릭하였을때는
화면 바탕색을 빨강색으로 해주고

findViewById(R.id.activity_main).setBackgroundColor(Color.RED);

여기에서 R.id.activity_main은 화면을 구성하는 xml화일에서

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:id="@+id/main_activity" > ... ... ... </LinerLayout>

android:id="@+id/main_activity"
라고 한 바탕을 구성하는 LinearLayout개체의 ID값인 것..즉 바탕을 구성하는
LinerLayout개체를 얻어낸 것이다

얻어낸 개체의 setBackGroundColor 메소드를 호출하여 색상값(상수목록에서 선택)
을 주면 되는 것이다

VBA에서와 똑 같다..프로그래밍개념은 똑 같다
개체를 찾아야 하고, 개체가 갖고 있는 메소드를 호출하면 되는 것이다
VBA에서 라면
Object.Background.Color="Red"
와 같은 형식으로 속성값을 줄텐데..
Java는
Object.setBackgroundColor("Red")와 같이 메소드를 사용한다

자꾸 사용하다보면 익숙해지면서..VBA와 비교해 보는 재미가 쏠쏠 할 것이다

그래서 위와 같이 간단하 버튼 두개 달고..
크릭하면 하나는 바탕색이 빨강색, 다른 하나는 파랑색이 되는
간단한 작업을 해 보았다
다음 페이지에서는 xml화일 없이 크래스모듈에서 독립적으로
코딩을 통하여 LinerLayout개체도 생성하고, Button도 생성하면서
작업을 해 보자
엑셀 UserForm에서 Userform없이 코딩으로 런타임에 생성하는 것이나
마찬가지개념의 작업을 해보자