티스토리 뷰
2. 프래그먼트를 이해하자
액티비티는 한 화면당 1개씩 있는 형태였지만 프래그먼트는 액티비티 1개당 여러 개
존재할 수 있습니다. 그러므로 액티비티 1개로 구현했던 것을 기능 단위로 프래그먼트로 나누어 구현할 수 있습니다.
덧붙여, 프래그먼트는 안드로이드의 프레임워크에서 구현된 것과 지원 라이브러리에서 구현된 것으로 2가지가 있습니다.
안드로이드 2.3 이상을 지원하는 경우 지원 라이브러리를 이용할 수밖에 없지만 안드로이드 4.1 이상을 지원하는 경우라도 지원 라이브러리를 이용하는 편이 좋습니다.
그럼 이번에는 단순한 프래그먼트를 가진 앱을 만들어 보겠습니다.
누르면 클릭 이벤트를 액티비티에 통보하고 액티비티에서 Toast를 표시하는 앱입니다.
여기서는 프래그먼트를 다음 3단계로 생각하면 될것 같습니다.
1. 프래그먼트 클래스를 만든다
2. 프래그먼트 뷰 구축에 이용할 레이아웃 XML을 만든다
3. 액티비티로부터 작성한 프래그먼트를 이용한다
1. 프래그먼트 클래스를 만든다
프래그먼트를 만드는 데는 2가지 규칙이 있습니다
첫번째는 프래그먼트 클래스를 상속하는 것이고, 두번째는 인수가 없는 기본 생성자
를 준비하는 것입니다.
MainActivity (전체)
public class MainActivity extends AppCompatActivity implements OnFragmentInteraction {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public void nFragmentInteraction() {
Toast.makeText(this, "버튼을 눌렀습니다.", Toast.LENGTH_SHORT).show();
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<fragment
app:layout_constraintRight_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:name="com.example.geunho.myapplication.MyFragment"
android:id="@+id/my_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.constraint.ConstraintLayout>
(id와 name 속성을 잊지 말자 ~~)
MyFragment.java (전체)
public class MyFragment extends Fragment {
private OnFragmentInteraction mListener;
public MyFragment() {}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteraction) {
mListener = (OnFragmentInteraction) context;
} else {
new RuntimeException(context.toString() + " OnFragmentInteraction 인터페이스를 구현 해주세요");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_my, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.findViewById(R.id.btn_1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mListener.nFragmentInteraction();
}
});
}
}
2. 프래그먼트 뷰 구축에 이용할 레이아웃 XML을 만든다 (전체)
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
tools:context=".MyFragment">
<Button
android:layout_gravity="center_horizontal|center_vertical"
android:text="PUSH !"
android:id="@+id/btn_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</FrameLayout>
여기서 간단히 설명하자면
MyFragment를 이용하기 위해 레이아웃 XML을 전개하고 뷰를 생성합니다.
프래그먼트에서는 뷰를 생성하는 시점이 정해져 있어 onCreateView() 에서 생성
하고 뷰가 만들어지면 onViewCreated()가 콜백됩니다.
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_my, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.findViewById(R.id.btn_1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mListener.nFragmentInteraction();
}
});
}
onClick() 안에 mListener.onFragmentInteraction() 이 갑자기 등장 했는데 이것은 버튼
을 눌렀을 때의 처리를 액티비티에서 처리 하기 위해서 콜백 메소드를 만들었습니다
public interface OnFragmentInteraction {
void nFragmentInteraction();
}
액티비티에서 구현한 리스너와 프래그먼트의 연결은 액티비티와 프래그먼트가 연결될 때 onAttach()에서 합니다 또한 연결을 끊기 전에 onDetach()에서 리스너에 대한 참조를 해제 합니다.
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteraction) {
mListener = (OnFragmentInteraction) context;
} else {
new RuntimeException(context.toString() + " OnFragmentInteraction 인터페이스를 구현 해주세요");
}
}
리스너가 구현되지 않았으면 RuntimeException을 던처 처리를 계속할 수 없게 했습니다.
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
연결을 끊기 전에 onDetach()에서 리스너에 대한 참조를 해제 합니다.
** 액티비티나 프래그먼트에 수명주기는 꼭 알고 활용하도록 합니다. **
여기에서 액티비티에 있는 onSaveInstanceState()는 프래그먼트에도 있습니다.
이 메서드는 프래그먼트가 폐기되기 전에 호출되므로 필요한 정보는 이때 저장할
수 있습니다 액티비티와 달리 onRestoreInstanceState() 는 프래그먼트에 존재하지
않지만 onCreate() ~ onActivityCreated()의 수명주기의 메서드의 인수에 Bundle이
포함돼 있어 액티비티와 똑같이 복귀하도록 구현할 ㅅ 있습니다.
'android' 카테고리의 다른 글
6. BroadcastReceiver로 브로드캐스트 이벤트를 수신하자 (0) | 2018.05.20 |
---|---|
5. UI를 갖지 않는 프래그먼트를 이용하자 (0) | 2018.05.20 |
4.중첩 프래그먼트를 이용하자 (0) | 2018.05.09 |
3. 프래그먼트를 동적으로 추가 및 삭제하기 (0) | 2018.05.03 |
1. 커스텀 뷰 만들기 (0) | 2018.05.02 |