dngchn's [Android]2014. 11. 5. 11:30

하나의 솔루션만을 열어서 사용하던 Visual Studio에 익숙한 사용자라면,

나처럼 이클립스에 초보인 사용자라면, 처음에 분명 비슷한 고민이 생기리라.

아래와 같은 상황이라면 어떨까..


늘어가는 프로젝트, 바로 어제 작업했던 프로젝트 이름 고르기도 헷갈리고,

무엇보다, 처음 이클립스 띄우면 모든 프로젝트를 컴파일 하느라 버벅이는 듯 하다.

뭔가 폴더 구조를 만들어 묶어서 관리하고 싶은데.. . 라는 생각이 들었을때,

이를 위해 이클립스에서는 Working Set이라는 것을 제공한다.

말그대로 작업 묶음으로 이해하면 되겠다.


워킹셋을 이용하기 위해 Package Explorer에서 마우스 우클릭으로 New->Java Working Set을 아래와 같이 선택한다.


아래와 같이 뜨는 창에서 적당한 워킹셋의 이름을 주고, 해당 워킹셋에 포함시킬 프로젝트를 선택하고 Finish 버튼을 누르면 끝이다.


자, 이렇게 하고 Package Explorer를 보자. 엥? 뭐야.. 달라진게 없잖아... 라고 생각할 수도 있겠다.

아래와 같이 Package Explorer의 상단 메뉴 중 아래 화살표를 눌러 'Top Level Elements' -> 'Working Sets'으로 선택한다.

그러면 종전과는 다르게 Package Explorer가 워킹셋으로 묶여서 정리되어 표시된다.


한가지 더 팁이라면, 워킹셋을 대상으로 마우스 우클릭하여 'Close Project'메뉴를 선택하면, 말 그대로 사용하지 않는 프로젝트들을 이클립스 구동시마다 컴파일되지 않도록 제외시켜둘 수 있다(닫아둔다).

자.. 어떤가, 별것 아니지만, 점점 많아지는 프로젝트를 워킹셋을 잘 활용하면 효율적으로 관리할 수 있겠다.


Posted by dngchn
dngchn's [Android]2014. 11. 4. 22:47

지난 예제를 조금 확장해보자.

우선 새롭게 뜨는 뷰에 부모(?)뷰에서 데이터를 전달해보기로 한다.

이를 위해 필요한 것은 아래와 같다.

anotherIntent.putExtra("key", "value");

말 그대로 어떠한 값(value)을 하나의 키(key)로 넣어두는 것이다.

왜? 넣어두어야 새로운 뷰에서 꺼내어 참조할 수 있으니까.


그럼 어떻게 꺼낼까? 간단하다.

Intent myIntent = getIntent();
myIntent.getStringExtra("key");

알고있는 키를 통해 얻어내면 된다.


그럼 이와 같은 기본 개념을 갖고 예제를 통해 확인해보자.

우선 부모 뷰에서 EditText를 하나 두어, 사용자가 무언가 데이터를 입력하도록 하고,

이 데이터가 새로이 보여지는 뷰에 전달되도록(정확히는 새로운 뷰에서 꺼낼수 있도록) 하여,

뷰간의 데이터가 전달됨을 확인해보자.


우선 부모 뷰의 레이아웃(activity_main.xml)이다.

<LinearLayout 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:orientation="vertical" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />
    
    <EditText
        android:id="@+id/toSend"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        />
    
    <Button
        android:id="@+id/nextButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Next"
        /> 

</LinearLayout>

EditText를 배치하여 새로운 뷰로 전달할 메시지를 입력 받는다.


부모 뷰의 액티비티(MainActivity.java) 코드이다.

public class MainActivity extends ActionBarActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		Button btnNext = (Button) findViewById(R.id.nextButton);
		btnNext.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {				
				Intent anotherIntent = new Intent(getApplicationContext(), AnotherActivity.class);
				TextView toSend = (TextView) findViewById(R.id.toSend);				
				anotherIntent.putExtra("message", toSend.getText().toString());
				startActivity(anotherIntent);				
			}
		});
	}

startActivity를 호출하기 전에 'putExtra'를 통해 EditText에 입력된 텍스트를 'message'를 키로 삼아 넣어둔다.


새롭게 뜨는 뷰의 레이아웃(activity_another.xml)이다.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <TextView
        android:id="@+id/sentFrom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        />
    
    <Button
        android:id="@+id/closeButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Close"
        />   

</LinearLayout>

부모 뷰로부터 받은 메시지를 보여주기 위한 TextView를 위치 시킨다.


새롭게 뜨는 뷰의 액티비티(AnotherActivity.java) 코드이다.

public class AnotherActivity extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);	
		setContentView(R.layout.activity_another);
		
		TextView sendMessage = (TextView) findViewById(R.id.sentFrom);
		Intent myIntent = getIntent();		
		sendMessage.setText(myIntent.getStringExtra("message"));		
		
		Button btnClose = (Button) findViewById(R.id.closeButton);
		btnClose.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {				
				finish();				
			}
		});
	}
}

'getStringExtra'를 통해 부모 뷰로부터 전달된 데이터를 받아 표시한다.

데이터를 넘길 때 사용한 키('message')를 이용하여 얻어낸다.


이렇게 하여 실행해보면 아래와 같이 잘 동작됨을 확인할 수 있다.



만약 데이터의 흐름을 이번과 반대로 즉, 새로운 뷰에서 생성된 데이터가 부모 뷰로 가게 하려면 어떻게 해야 할까?

이는 다음 글에서 계속해서 알아보도록 하자.


Posted by dngchn
dngchn's [Android]2014. 11. 3. 13:54

안드로이드 앱 상에서 빈번히 발생하는 뷰의 전환 방법에 대해 이야기 해보자.

하나의 뷰는 Activity에 의해 관리된다. 뷰, 즉 사용자가 보는 화면이 전환된다는 의미는 Activity가 전환된다는 의미이다.

현재 보여지고 있는 뷰에서 다른 뷰로의 전환은, 전환하고자 하는 다른 뷰를 말 그대로 아래와 같이 시작시키면 된다.


StartActivity(anotherIntent);


위에서 인자인 anotherIntent는 Intent 타입 객체이다.

새롭게 화면상에 보이고자 하는 intent를 만들어 인자로 넘기는 구조이다.

이는 보통 아래와 같이 작성하여 준비한다.


Intent anotherIntent = new Intent(getApplicationContext(), AnotherActivity.class);


우선, 위와 같이 기본적인 개념만 잡고 직접 실습을 통해 시작해보자.

우선 재빨리 New->Android Application Project메뉴를 통해 ChangeViewTest 이름의 프로젝트를 생성하자.

기본 Hello world 프로젝트에 Activity(View)를 하나 추가하여 전환시켜보자.

일단 기본 뷰에 버튼을 하나 두고, 누르면 다른 뷰로 전환, 다른 뷰에서 버튼을 눌러 닫으면, 원래 뷰로 돌아오는 시나리오로 만들어 보자.

또 다른 뷰를 위해 레이아웃(activity_another.xml)과 액티비티(AnotherActivity.java) 추가한다.



우선, 기존 레이아웃과 액티비티 먼저 준비하자.

기존 레이아웃(activity_main.xml)에는 버튼 하나 추가 한다.

<LinearLayout 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:orientation="vertical" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />
    
    <Button
        android:id="@+id/nextButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Next"
        /> 

</LinearLayout>


기존 액티비티(MainActivity.java)에는 버튼에 대한 핸들러를 아래와 같이 추가한다.

기본 개념대로 Next 버튼을 클릭했을 때, 새롭게 띄워질 뷰에 대한 Intent를 준비하여 'startActivity'를 통해 새로운 액티비티를 시작해준다. 간단하다.

public class MainActivity extends ActionBarActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		Button btnNext = (Button) findViewById(R.id.nextButton);
		btnNext.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Intent anotherIntent = new Intent(getApplicationContext(), AnotherActivity.class);
				startActivity(anotherIntent);				
			}
		});
	}


이제 새로이 추가한 레이아웃과 액티비티를 다음과 같이 작성한다.

우선 레이아웃,

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <Button
        android:id="@+id/closeButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Close"
        />   

</LinearLayout>


그리고 액티비티,

public class AnotherActivity extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_another);
		
		Button btnClose = (Button) findViewById(R.id.closeButton);
		btnClose.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				finish();				
			}
		});
	}
}

위에서도 어려울 것 없다. 새롭게 보여지는 뷰는 달랑 버튼 하나를 갖고 있으며,

버튼이 클릭되면 자신을 죽인다(finish).


자, 위 기본 개념대로 새롭게 뷰를 전환할 준비가 다 되었다. 컴파일 하고 결과를 확인 해보자.

...

...

잘 되는지?

아마도 에러가 날 것이다. 이렇게 까지 먼저 해보도록 하는 이유는, 다음에서 필요한 과정을 깜빡 잊기 쉬워,

다시 한번 이렇게 강조 하고자 함이다.

우리는 앱에 새롭게 액티비티를 추가하였다. 이에 대한 사실을 명확히 알려야 한다. 다시 말해 우리의 앱을 실행 시킬 그 무언가의 주체에게 우리 앱은 이러저러한 액티비티가 있다고 알릴 필요가 있다. 어디에?

바로 AndroidManifest.xml에!


매니페스트 파일(AndroidManifest.xml)에 다음과 같이 액티비티를 추가하자.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.changeviewtest"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
        <!--새롭게 추가한 액티비티 정의 -->
        <activity android:name=".AnotherActivity"></activity>
    </application>

</manifest>


자, 이제 다시 실행해보자. 아래와 같이 화면이 뜨고, Next를 누르고, Close를 눌러보자.

성공이다! 우리가 새롭게 끼워 넣은 뷰가 보이고 닫히고, 단순하기 그지 없지만, 우리가 의도한 시나리오 대로 잘 동작 한다.





이것으로 아직 끝나지 않았다. 뭐 대충 화면 전환은 되지만, 실제 앱이 동작하는 시나리오를 생각 하자면,

원래 뷰와 새롭게 뜨고 죽는 뷰 사이에 무언가 데이터를 주고 받을 필요가 있을 것이다.

예를 들자면, 새롭게 뜨는 뷰를 통해 무언가 사용자에게 정보 입력을 받기위해서는 새로 뜬 뷰가 죽고 나서

사용자가 입력한 정보를 원래 뷰로 돌려줘야할 필요도 있을 것이고,

반대로 새로운 뷰가 뜰때 원래 뷰가 갖는 데이터를 보여줘야 할 필요도 있을 것이다.

이와 같은 시나리오에 대해서는 다음 글에서 한번 이번 예제를 확장시켜 알아보자.


Posted by dngchn