PROGRAMMING WORKSHOP

Android|
RelativeLayout | ListView | SrcollView | TextView

안드로이드 프로젝트를 시작하면서 처음 Activity를 삽입하면
크래스 모듈과 하나의 레이아웃 xml화일이 쌍으로 만들어진다
그리고 추가적으로 Activity를 삽입하면 꼭 Layout용 xml화일이 같이
만들어진다..
여기에서 중요한 메인은 크래스모듈이고
인터페이스를 구성하는 Layout xml화일은 부속품이라고 보시는 것이 좋다



엑셀의 워크시트도 워크시트 한장을 삽입하면 꼭 해당 크래스의 모듈이
붙어 있는 것을 알수 있다
그러나 엑셀에서는 워크시트가 주인이고 크래스모듈은 워크시트의 자동화를
도와주는 역할로 보시면 될 것이다
그러나 안드로이드 쟈바에서는 크래스가 주인이다..
어떤 시트를 선택하여 사용하던, 스스로 시작적인터페이스를 만들어서
사용하던 크래스모둘..즉 Activity개체가 주인인 것이다

안드로이드앱을 처음 만들때 항상 기본적으로 블랙박스역할을 하는 것이
하나 더 있다
이것이 없으면 App이 돌아가지 않는다



이것은 나중에 수시로 편집하게 될 부분이다
화일의 이름은 AndroidManifest.xml
하나의 App은 여러개의 Activity(창)로 구성되고
어느것을 시작될때 기본창으로 할 것인지
앱의 버전은 안드로이드 어떤 버전으로 사용할 것인지
인터넷을 통하여 써버에서 정보를 갖여 올 것인지
스크린을 옆으로 자빠지게 할 것인지, 그냥 세로로 세워서
보게 할 것인지, 자동으로 뒤집어지게 할 것인지...등등..
(물론 Acitivy단위의 일은 Activity크래스에서 프로그래밍적으로 처리도 되지만)
전화기에 화일을 만들 것인지..허용하는 코드를 이곳에 넣어야 하고
전체 Acitivity들을 중앙통제하는 것

이것은 안드로이드에만 있는 것이 아니고
엑셀도 통합문서단위에서 처리하는 것이 있고
Application단위에서 처리하는 일이 있는 것이 아닌가?
모든 프로그래밍이 마찬가지이다
그런데 엑셀은 Application레벨의 일은 지가 알아서 하게 놓아두면
되고, 특별히 무언가 하고 싶은면 Application레벨에서의 일을
프로그래밍적으로 처리하면 되는 것

아래와 같이 해 보면서 위의 내용이 뭔 소린지 알아보도록 하자
목록상자는 어떤 프로그램이나 갖고 있는 콘트롤이다
Android에서는 ListView콘트롤(View)라고 한다
그런데 Activity 화일(하나의 화면화일) 자체가 ListView로 만들수 있고..
대개가 그렇게 사용한다

물론 ListView콘트롤(View)를 다른 콘트롤과 같이 하나의
화면(Activity)에 삽입하여 사용하기도 하고

아래의 그림과 같이 배열을 목록상자의 정보로 전달하여
화면에 나타나고 스크롤이 되게 해본다
이때 목록상자는 콘트롤이 아니고 Activity화면 자체가 목록역활을 한다



새로운 프로젝트를 하나 만들면 Activity 화일과 Layout 화일이 쌍으로
만들어지고..
Activity 크래스화일을 열면 아래와 같다

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sub);
    }
	
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_sub, menu);
        return true;
    }

    
}

Activity개체를 상속받아서 MainActivity 개체(화면)를 만든다는
크래스 인것이다
이 Activity개체를 ListActivity라고 고친다
이 말은 화면을 ListActivity라는 개체를 상속받아서 MainActivity를
만들겠다는 이야기다
그래서 ListActivity라고 수정하니까..아래의 그림과 같이 여기저기 에러표시가 나타난다



이것은 Activity개체를 상속받아 사용하겠다는 Activity가
ListActivity개체를 사용하겠다고 하니까..ListActivity는 참조가 되어있지
않다는 ListActivity밑에 마우스를 갖여다 대면 안내문이 나타난다
안내한대로 ListActivity를 Import(참조)시키겠다고 크릭하면
선언부의 Imports에 ListActivity개체가 등록된다
그리고 에러표시도 사라진다

이제 화면구성자체가 목록상자로 바뀌게 된 셈이다
이것은 처음 만들때 쌍으로 만들어졌던 Layout 화일은 필요없게 된다
layout폴더에 있는 Layout화일을 삭제해버려도 된다
더 이상 필요없는 것이다
그냥 크래스화일일 알아서 만들겠다는 것이 된 것이고
이것은 Layout은 부속화일이고 크래스화일이 개체를 만드는 메인이라는 것을 알수 있는 것이다
처음에 헷갈린다..어느 것이 메인이고 어느것이 부속화일인지..

그리고
Layout 화일을 어떤 것을 쓰겠다는
SetContentView(Layout이름)의 명령도 필요없게 된다
하지만 목록을 아직 채우지 않았다

목록을 채우는 것을 xml화일로 목록을 만들어서 처리하기도 하겠지만
번거롭다..
그냥 배열을 만들어서 목록개체와 연결해버리면 간단할 것이다
VBA에서 목록상자에 값을 넣는 것도 배열을 넣는 것이라는 것을
아시는 분은 아실 것이다
그런데 모바일에서 중요한 것은 속도감이다
목록이 수천개가 되는 것을 콘트롤에 연결해 버린다면..
컨트롤이 얼마나 무거워지겠는가????
그래서 Adapter라고 하는 개념이 나온다
중간에서 배열정보와 콘트롤간의 교량역할을 해주는 것이다
전기컨센트에 아답타를 끼우면 중간 조율이 되는 것과 같은 의미의
Adapter인 것이다

그러니 배열을 직방으로 콘트롤과 연결하는 것이 아니고
Adapter개체에 배열을 물리고 Adapter개체를 목록상자에 물려 주는 것!!
중간에 하나 더 걸친다는 것!!을 아시고
그러면 화면에 나타나는 부문만큼의 정보만 Adapter가 열나게
목록상자에 보내주는 것이라고 보시면 될 것이다
그래서 스마트폰의 목록은 손으로 툭치면 물흐르듯이
주루룩 돌아가는 것이다
참고로 VB.Net에서도 데이타관련 Adpater역할이 커진다
아래와 같이 몇줄 코딩하면 된다

public class MainActivity extends ListActivity {
	
	// 전역변수 배열 선언
	
	
	String list[]={"A","B","C","D","E","F","G","H",
			"I","J","K","L","M","N","O","P","R",
			"S","T","U","V","W","X","Y","Z"};
	
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
		
		// 배열을 ArrayAdapter로 만들어서 이것을 setListAdapter 명령으로 목록상자
		// 즉 여기에서는 Activity 개체 자체가 목록개체..
		// this 는 엑셀 VBA에서 Me에 해당하는 것..자신의 개체를 의미한다
		
		
        this.setListAdapter(new ArrayAdapter(this,android.R.layout.simple_list_item_1, list));
		
		
		// 아래의 Layout화일을 연결하는 명령은 필요 없어지는 것이다
        // setContentView(R.layout.activity_main);
		
    }

아래의 구문이 좀 복잡해 보이니까...

this.setListAdapter(new ArrayAdapter(this,android.R.layout.simple_list_item_1, list));

조금 풀어서 만들면

ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1, list);
this.setListAdapter(adapter)

와 같이 두줄로 표현하면 조금 이해하기 쉬울 것이다
ArrayAdapter adapter를 VBA적으로 표현한다면
Dim adapter As ArrayAdapter 와 같다
그런데 이라는 것은 String 값으로 구성된 집합체라는 의미다
아무튼 변수선언과 동시에 값을 만들어 넣으니까..좀 복잡해 보인다

ArrayAdapter(this,android.R.layout.simple_list_item_1, list);

위의 빨강색 부분을 좀더 구체적으로 보면 아래와 같다



이제 ListView의 아이템을 선택하면 어떤 작업을 할 것인지를
코딩해주어야 겠다
우선 ListView의 아이템을 선택하였을때 화면이 바뀌게 해주어야 할 것이고
그렇다면 화면(Activity)개체를 하나 만들어야 할 것이다



그리고 이름을 ResponseActivity.java라고 지어 주었다
이렇게 java확장자의 크래스는 컴파일되면 class라는 확장자로 바뀌어
Bin폴더에 저장된다
여러분의 컴퓨터속에 class라는 확장자의 화일이 있다면
이것은 java크래스화일로 아시면 된다

아무튼 아래의 그림과 같이 ListView Activity의 목록의 아이템을 선택하면
다른 하나의 Activity(화면,ResponseActivity.java)이 만들어지고 이 Activity에 정보를 전달하여
내용을 전달된 정보에 따라서 다른 문자를 표현해주도록 해본다



다른 Activity만들기..
다른 Activity에 정보 전달하기..(아주 중요한 문제일 것이다)
목록을 선택할때마다 수많은 Activity를 만드는 것은 바보짓이 것이다
하나를 만들어서 모든 목록의 선택에 반응하는 일꾼이 되게 한다

그리고 ResponseActivity.java에서 사용할 화면(XML layout)을 하나 만들고
res/layout/폴더를 선택한후 New/Others../Android XML File 에서 선택하여
설치한후 이름을 response.xml 화일로 지어주었다

하나만 더 수고를 해주자
위에서 설명한 App의 블랙박스..AndroidManifest.xml 화일을 열고
ResponseActivity.java 를 등록하여야 하는 일..

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android1_10" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/title_activity_main" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".ResponseActivity" android:label="@string/title_activity_main" > <intent-filter> <action android:name="android.intent.action.RESPONSE" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> </application> </manifest>

두번째 Activity 태그를 MainActivity 태그를 복사하여
붙여 넣고..
android.intent.category.LAUNCHER 을
android.intent.category.DEFAULT로 바꿔준다
하나의 App에는 초기화화면은 하나만 있어야 하고
LAUNCHER라는 의미는 초기화화면으로 사용하겠다는 선언인 셈이다
그러니 다른 Activity가 부르면 일을 하는 ResponseActivity는
LAUNCHER가 되면 안되고, DEFAULT로 바꿔준다
그리고 action.RESPONSE라고 적절히 부르기 좋은 이름으로 바꿔주고
Activity의 이름(Name)은 쩜하나 찍고...Acitivy 크래스명과 같이 해준다

다른 Activity에서 다른 이름의 Activity를 호출할때 이 AndroidManifest.xml화일을
통하여 호출하는 것이니 필수적으로 잘 작성하여 놓아야 할 것이다

만약 Activity 크래스를 만들때 Class가 아닌 Android Activity로 만들때는
크래스모듈과 더불어 Layout.xml 화일이 같이 쌍으로 만들어지게 된다
이때는 AndroidManifest.xml화일에 자동으로 등록이 되기도 하지만..
따로, 따로 만들고, 직접등록하고 하는 방법이 에러가 덜 나고
콘트롤하기 좋다

실행을 하다가 에러가 나면 AndroidManifest.xml내용에 Activity정보가
정상적으로 잘 정리가 되었는지 살피는 것이 먼저 할 일이다

이제 목록상자를 선택하면(Activity개체자체가 목록상자라는 점 기억하시고) 어떤 일을 할지 메소드(VBA에서는 이벤트프로시져라고 하지만 Java에서는 그냥 몰아서 모두 메소드라고 한다)를 작성하여야 하는데..이것은 몇번 이전에 해보았지만 분명히 다 까먹어서
기억이 안날 것이니..다시 열심히 그림그려놓고 보자



모듈시트를 오른쪽마우스로 크릭하여 Source/Override|Implements Method..를 크릭하면
대화상자가 나타나고, Activity, ListActivity등 개체명이 나타난다
현재의 Activity는 ListActivity를 상속받아서 화면 전체를
ListView로 사용하는 것이니..ListAcitvity개체에서 선택하여야 할 것이다
이곳에서 OnListItemClick을 선택하고 OK 하면 아래와 같이 메소드의 틀이 자동삽입된다

@Override protected void onListItemClick(ListView l, View v, int position, long id) { // TODO Auto-generated method stub super.onListItemClick(l, v, position, id); }

위의 내용에 작업할 내용을 작성하면 된다..아래와 같이..

	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		// TODO Auto-generated method stub
		super.onListItemClick(l, v, position, id);
		
	Intent intent = new Intent(MainActivity.this, ResponseActivity.class);  
        Bundle b = new Bundle(); 
        b.putString("name",list[position]);
        intent.putExtras(b);
        startActivity(intent);  
		
     }

Intent라는 개체가 화면자체의 개체..
이것을 new Intent(현재크래스= Activity.this, 호출할 크래스=ResponseActivity.class)
호출할 크래스는 class라는 확장자가 붙었다
java라는 확장자가 컴파일되면서 class확장자로 변하여 Bin디렉토리에 저장이 되고
이것을 호출하게 되는 것이다
그리고 정보를 다른 Activity에 전달하기 위한 개체가 Bundle이라는 개체이다
Bundle ..말 그대로 꾸러미를 쌓아서 전달한다는 의미인것이다
Bundle b = new Bundle()
와 같이 꾸러미 개체를 생성한 것이다
생성했으니 이곳에 짐을 실어야지!!!
짐은 곧 정보..Bundle개체의 putString 이라는 메소드가 있다
putBoolean이라고 하면 Boolen정보를
putDouble이라고 하면 Double 정보를 이렇게 각각의 정보의 타입마다
메소드이름이 있다는 점...
여기에서는 목록에서 선택된 알파벳문자를 전달하려고 하는 것이니까..
b.putString() 인 것이다
정보를 전달할때는 정보의 이름과 그리고 값을 전달한다
그래서
b.putString("name",list[position]) 이라고 한 것은
"name"이라는 정보의 이름으로 값을 list[position] 즉 list라는 배열에서
onListItemClick메소드의 매개변수 position은 몇번째 목록을 선택하였다는 정보를
얻을수 있다
그러니 이것을 그대로 전역변수로 만들어 놓았던 list배열에서 찾으면 된다
그래서 name이라는 이름으로 어떤 알파벳값을 전달하려고 하는 것이다
이렇게 만든 bundle개체를 intent개체에 담는다
Intent개체에 담는 것은
intent.putExtars(b) 라는 putExtras메소드를 사용한다
이제 꾸러미 싸서 intent개체에 실었으니..
startActivity(intent)로 다른 Activity를 실행시키면 된다

그럼 호출당하는 Activity에서 전달 받은 Bundles..꾸러미 개체를 까서
대응을 하여야 할 것이다
아래와 같이 ResponseActivity.java를 작성한다

public class ResponseActivity extends Activity {
    //두개의 배열을 만든다..하나는 화면의 바탕색, 다른 하나는 문자의 색상
	int bc[]={Color.BLACK,Color.BLUE,Color.GREEN,Color.GRAY,Color.RED,Color.YELLOW};
	int fc[]={Color.YELLOW,Color.WHITE,Color.BLACK,Color.WHITE,Color.WHITE,Color.BLACK};
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		
		Bundle extras = getIntent().getExtras();
		String data=extras.getString("name");
		this.setContentView(R.layout.response);
		  LinearLayout ll = (LinearLayout)findViewById(R.id.ll1);             
		  TextView tv = new TextView(this);         
		  tv.setText(data);   
		  
		 
		  Random rd= new Random();
		  int i= rd.nextInt(6);
		   ll.setBackgroundColor(bc[i]);
		  tv.setTextSize(TypedValue.COMPLEX_UNIT_DIP,500);
		  tv.setTextColor(fc[i]);
		  ll.addView(tv); 
	}

}

본래 Activity의 onCrate메소드에서 아래와 같이 Bundle개체를 매개변수로 받고 있다

protected void onCreate(Bundle savedInstanceState) {
...
...
}

이것이 호출하는 쪽에서 전달하는 Bundle이 되는 셈이다
바탕색과 문자색을
int bc[]={Color.BLACK,Color.BLUE,Color.GREEN,Color.GRAY,Color.RED,Color.YELLOW};
int fc[]={Color.YELLOW,Color.WHITE,Color.BLACK,Color.WHITE,Color.WHITE,Color.BLACK};
와 같이 배열에 담았다, 이렇게 한 것은 바탕색에 맞는 문자색상을
배열에 맞게 담아 놓은 것
예를 들어서 빨강색 바탕에 빨강색문자같은 경우가 되면 안되니까..
목록상자를 선택할때마다 ResponseActivity.java의 onCreate메소드가 실행되면서
Random 개체로 랜덤숫자를 i 값에 받아서
Bundle개체를 통하여 전달받은 문자를 화면에 써주고
TextView의 setText
바탕색을 LinearLayout의 setBackgroundColor(bc[i]) 로 랜덤값 i로 바탕색주고
문자색은 TextView의 setTextColor(fc[i]) 로 준다..
문자의 크기를 TextView.setTextSize()를 정해주고

이렇게하여 두개의 Activity사이를 정보를 전달하고 실행하는 과정을 간단하게 해 보았다
뭔가 복잡해 보이겠지만..실은 몇가지 원칙을 알면
카메레온같이 변화무쌍한 엑셀에 비하여 무척 간단한 편이다
다음 페이지에서는 급하게 Android를 하느라고 Android 인터페이스를
이것 저것 하면서 보여드렸지만
Android는 Java를 기반으로 하는 것이니..
Java언어를 기본적으로 살펴보는 것이 좋을 것같으니..
Java언어의 기본을 차근차근 살펴보고..그런 후 Android를 다시 하도록 하자

***[LOG-IN]***