package com.example.sample; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v7.app.ActionBarActivity; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /* * 초기 액티비티가 화면에 보여질때 setContentView 메서드를 통해 화면에 View 를 붙여준다. * res/layout/activity_main.xml 을 액티비티의 레이아웃으로 설정한다. * 하지만 activity_main.xml 안에서는 FrameLayout 하나만 선언 되어 있는데, 이는 해당 레이아웃에 * 프레그먼트를 사용하기 위해 미리 선언 되어 있다. */ setContentView(R.layout.activity_main); /* * savedInstanceState 란 무엇인가 ? * * savedInstanceState 객체는 onSaveInstanceState 메서드에서 저장한 Bundle 객체에 대한 정보를 가지고 있음 * onSaveInstanceState 메서드를 구현하기 위해선 Override 해야 한다. * onSaveInstanceState 메서드가 호출되는 시점은 메모리 부족/강제종료 및 스크린 Orientation 이 변경될때 호출된다. */ if (savedInstanceState == null) { //초기 프로젝트 실행후 액티비티의 상태 저장값은 NULL //ID 이름이 container(Frame Layout)인 레이아웃 안에 프래그먼트를 붙이기 위해 아래 코드 사용 getSupportFragmentManager().beginTransaction() .add(R.id.container, new PlaceholderFragment()).commit(); } } //액션바에 옵션메뉴를 달기 위해선 onCreateOptionsMenu 를 구현해야 한다. @Override public boolean onCreateOptionsMenu(Menu menu) { /* * res/menu/menu.xml 에 메뉴를 구성할수 있다. * 이곳에선 구성된 메뉴를 생성한다. * 초기 프로젝트 생성시 Settings 이라는 기본 메뉴가 들어가 있다. */ getMenuInflater().inflate(R.menu.main, menu); return true; } //옵션메뉴 클릭시 onOptionsItemSelected 메서드가 호출되며, 해당 메서드에서 작동하는 코드를 구현한다. @Override public boolean onOptionsItemSelected(MenuItem item) { //각 옵션메뉴 버튼마다 고유의 ID 를 가지고 있으므로, ID 를 통해 어떤 메뉴를 클릭하였는지 구분한다. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } //PlaceholderFragment 클래스를 정적 내부 클래스(Static Nested Class) 로 선언하여, 외부에서도 접근할수 있도록 선언한다. public static class PlaceholderFragment extends Fragment { //생성자 public PlaceholderFragment() { } //프레그먼트가 화면에 보여질 View 를 구성한다. @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { /* * LayoutInflater 를 사용하여 해당 프레그먼트의 레이아웃을 설정하고 xml 을 View 객체로 생성한다. * 실질적으로 컴파일 될때 보여질 화면은 fragment_main 에서 담당한다. */ View rootView = inflater.inflate(R.layout.fragment_main, container, false); /* * fragment_main.xml 에 선언되어 있는 TextView (Hello World) 를 코드상에서 객체로 사용하기 위해서는 해당 주소를 찾아 TextView 로 캐스팅 해야 한다. * 일반적으로 액티비티 안에서 View 에 대한 ID 값을 참조하기 위해서 findViewById 를 사용하였지만, * Fragment는 객체로 생성한 View 를 통해 View(컴포넌트)의 ID 값을 찾아야 한다. (아래 코드 참조) */ TextView textView = (TextView)rootView.findViewById(R.id.textView); //rootView 객체에서 findViewById 메서드 사용하여 View의 ID 를 통해 TextView 로 캐스팅 한다. textView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(getActivity(), "Hello World 클릭!", Toast.LENGTH_SHORT).show(); } }); return rootView; } } }
※ 프레그먼트(PlaceholderFragment Class)를 왜 정적 내부 클래스 (Static Nested Class) 로 선언 하였는가?
자바 기초가 탄탄하신분들은 이미 눈치 채셨을겁니다.
(이너클래스, 익명 이너클래스, 내부 클래스, 로컬 클래스 에 대해 잘 모른다면 자바 기본 서적을 참고하세요)
다른 클래스에서 특정 외부 클래스(Outer Class) 안에 있는 내부 클래스(Inner Class) 를 접근하기 위해서는,
반드시 Outer Class 를 통해서 (객체 생성) Inner Class 에 접근이 가능합니다.
하지만 정적 이너 클래스의 경우 Outer Class의 객체 생성 없이도 객체 생성이 가능합니다.
즉, PlaceholderFragment Class 를 만약 이너 클래스로 선언 하였다면,
(ex. public class PlaceholderFragment)
다른 클래스 에선 해당 클래스로 접근할수 있는 방법은 아래와 같습니다.
package com.example.sample; public class A { public void Test() { //Outer Class 를 먼저 생성후 Inner Class 를 생성할수 있다. //즉 MainActivity 안에 PlaceholderFragment 클래스가 존재하기 때문에 아래 작업을 해야한다. MainActivity outer = new MainActivity(); MainActivity.PlaceholderFragment inner = outer.new PlaceholderFragment(); } }
(MainActivity 안에서는 PlaceholderFragment a = new PlaceholderFragment(); 와 같이 선언 가능)
반대로 PlaceholderFragment Class 를 만약 정적 이너 클래스로 선언 하였다면,
(ex. public static class PlaceholderFragment)
다른 클래스 에선 해당 클래스로 접근할수 있는 방법은 아래와 같습니다.
package com.example.sample; public class A { public void Test() { //정적 이너 클래스 인경우 아래 한줄로 객체 생성이 가능하다. //즉 MainActivity 안에 PlaceholderFragment 정적 이너 클래스가 존재하기 때문에 아래 작업을 해야한다. MainActivity.PlaceholderFragment fragment = new MainActivity.PlaceholderFragment(); } }
'프로그래밍 > Android' 카테고리의 다른 글
Apache HttpClient 라이브러리를 통한 HTTP 통신 JSON 파싱 (1/3) (3) | 2014.04.16 |
---|---|
Android ADT 22.6.0 이상 이전의 BlankActivity 환경 만들기 (4) | 2014.03.30 |
Android ADT 22.6.0 이후의 변화 (2) | 2014.03.29 |