본 게시글은
'Do It! 안드로이드 프로그래밍 개정7판' / '단계별로 배우는 안드로이드 프로그래밍'
두 권의 교재를 통해 학습한 내용을 스스로 정리하는 목적으로 작성한 게시글 입니다.
*프래그먼트 내용은 '단계별로 배우는 안드로이드 프로그래밍'에는 없는 내용입니다.
Fragment, 우리말로 '파편' 이라는 뜻이다.
안드로이드에서 프래그먼트는 '부분화면'을 만드는데 사용된다.
또 각각의 프래그먼트는 액티비티처럼 독립적이어서 따로 관리할 수 있다.
프래그먼트는 반드시 액티비티 '위에' 존재해야한다.
액티비티로 만든 화면을 '프래그먼트'라는 부분 단위로 쪼개 관리하는 것이기 때문이다.
프래그먼트가 동작하는 시점은 메모리에 생성된 시점이 아닌, 액티비티 위에 존재하게된 시점이다.
프래그먼트는 '프래그먼트매니저'에 의해 관리된다.
액티비티는 시스템이 관리하기 때문에, 액티비티의 제어는 시스템이 이해할 수 있는 언어로 해야한다.
시스템이 이해할 수 있는 언어로 된 것이 바로 인텐트이다.
그러나 프래그먼트는 시스템이 관리하지 않아 인텐트를 사용할 수 없으므로,
프래그먼트간 데이터 전달은 '메소드 호출 방식'을 이용한다.
프래그먼트는 액티비티를 본 떠 만들었다.
따라서 프래그먼트도 하나의 xml 레이아웃과 java 소스코드의 쌍으로 이루어진다.
xml 레이아웃 파일 작성
|
프래그먼트 java 소스에서 해당 레이아웃을 inflate
|
이렇게 만들어진 fragment를 액티비티에 추가
xml 레이아웃을 만들어서 액티비티의 부분화면에 직접 infate 시켰던 과정과 비슷하다.
인플레이션 과정은 프래그먼트의 순환주기 중 onCreateView() 콜백 메소드에서 일어난다.
이 메소드에서 infate 메소드를 호출하여 인플레이션을 진행하고,
인플레이션이 진행된 후에는 프래그먼트를 하나의 뷰처럼 쓸 수 있다.
Do It 안드로이드 프로그래밍 '도전09' 실습을 통해 직접 프래그먼트를 작성해보겠다.
우선 프래그먼트 레이아웃을 만들어준다.
왜인지 hint 속성을 기입해도 EditText 미리보기에 글자가 안나온다..
실행했을 때도 안나온다면 그때 다시 문제를 찾아봐야할 것 같다.
다음으로 프래그먼트의 자바소스코드를 새로 만들어 작성해준다.
package com.example.proj9;
import android.app.DatePickerDialog;
import android.os.Build;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.fragment.app.Fragment;
public class FragmentJava extends Fragment {
EditText editTextName, editTextOld;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_layout_, container, false);
editTextName = rootView.findViewById(R.id.editTextName);
editTextOld = rootView.findViewById(R.id.editTextOld);
Button buttonBirth = rootView.findViewById(R.id.buttonBirth);
Button buttonSave = rootView.findViewById(R.id.buttonSave);
buttonSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getContext(), "name : " + editTextName.getText().toString() +
"\nOld : " + editTextOld.getText().toString() +
"\nDate : " + buttonBirth.getText().toString(), Toast.LENGTH_SHORT).show();
}
});
DatePickerDialog.OnDateSetListener dateSetListener = new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
buttonBirth.setText(year + "년 " + (month+1) + "월 " + dayOfMonth + "일");
}
};
buttonBirth.setOnClickListener(new View.OnClickListener() {
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void onClick(View v) {
DatePickerDialog datePickerDialog = new DatePickerDialog(getContext(), dateSetListener, 2021, 0, 3);
datePickerDialog.show();
}
});
return rootView;
}
}
개인적으로 이 책을 초보자에게 권유하고 싶지 않은 이유 중 하나가
학습하지 않은 내용을 구현하도록 과제를 준다는 점이다.
본 책에서는 날짜를 설정하기 위해 DatePickerDialog 클래스를 활용하도록 힌트를 제공하는데,
이 클래스를 어떻게 활용해야하는지는 본 내용까지 일절 설명이 없었다.
결국 구글링으로 해결하였는데, 초보자들이 구글링으로 해결한다면 이미 초보자가 아닐 가능성이 높지 않을까
어쩌면 구글링으로 문제를 해결하는 경험을 제공하고 싶었을지도 모른다ㅋㅋ
프래그먼트는 액티비티와 달리 setContentView 메서드가 없어서
소스코드와 xml 레이아웃을 연결하기 위해 인플레이션 과정을 거쳐야 한다.
프래그먼트의 콜백메소드 중 onCreateView 메소드의 인자중 inflater가 그 역할을 할 수 있게 해준다.
inflater.inflate( 연결할 레이아웃, 프래그먼트가 붙어있는 컨테이너, attachToRoot 여부) 와 같이 사용하는데,
https://medium.com/vingle-tech-blog/android-layoutinflater-b6e44c265408
기본적으로는 레이아웃인플레이터 객체이기 떄문에, 해당 블로그 글을 참고하여 이해하였다.
inflater 의 리턴타입은 View 이지만, ViewGroup도 View의 하위에 속하기 때문에, ViewGroup으로 형변환 할 수 있다.
프래그먼트는 다른 뷰를 담고 있으므로 뷰그룹으로 변환하였다고 이해하였다.
구체적으로 내가 이해한 방식은, 프래그먼트를 이용해 부분 화면 영역을 지정하고,
그 영역 안에 onCreateVIew 메소드를 통해 만들어진(return된) 뷰그룹을 집어 넣는다고 이해하였다.
이렇게 뷰 그룹이 만들어진 다음부터는, 해당 뷰 그룹안에 있는 뷰를 참조해서 사용할 수 있다.
그 후부터는 액티비티에서 하던대로 뷰의 속성값 읽어와서 토스트로 띄워주면 된다
DatePickerDialog 의 사용법은
https://lktprogrammer.tistory.com/158
해당 블로그의 글을 참고하여 이해하였다.
리스너를 설정해야 한다는 점, show() 메소드로 호출해야 띄워진다는 점이 특징이었다.
dateSetListener는 날짜를 선택하고 확인 버튼을 누를 때 발생하는 이벤트를 감지하는 리스너로 이해했다.
해당 리스너의 onDateSet 메소드의 인자로 전달되는 날짜가 선택된 날짜 정보이다.
DatePickerDialog 객체는 (Context객체, 리스너, 초기 날짜 값)을 생성자의 인자로 넘겨주어 만들 수 있었다.
(아직도 context 객체의 필요성은 와닿지가 않는다. 지금은 이 객체가 띄워질 액티비티 정도로 이해하고 있는데,
그냥 생성만 하면 알아서 그 액티비티 위로 띄워질텐데 왜 필요한지 의문점이 남아있다.)
마지막으로 이렇게 만들어진 프래그먼트를 메인 액티비티에 연결해주면 끝이다.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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
android:id="@+id/fragment"
android:name="com.example.proj9.FragmentJava"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
메인 액티비티의 xml 레이아웃 파일 소스이다.
실행결과는 다음과 같다.
원하는 대로 실행이 잘 되는 것을 확인 하였다.
다음에는 액션바에 대해서 정리할 예정이다
'Android > Java' 카테고리의 다른 글
[안드로이드] getWidth() 와 getMeasuredWidth() (0) | 2021.03.20 |
---|---|
[안드로이드] Constraint Layout 동적 생성 후 동적으로 뷰 추가하기 (0) | 2021.03.20 |
[안드로이드] 인텐트 활용 : 데이터 교환(2) (0) | 2021.01.02 |
[안드로이드] 인텐트 활용 : 데이터 교환(1) (0) | 2021.01.01 |
[안드로이드] 인텐트의 개념 (0) | 2021.01.01 |