액티비티 또는 프래그먼트 사이에서 객체를 전달하는 예제를 만들어보겠습니다.
이전 글에서 코드를 조금 수정해서 작업을 진행하겠습니다. (이전 글이 궁금하신분들은 파란색 글씨 클릭)
레이아웃부터 조금 수정해보겠습니다.
1.activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<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"
android:gravity="center"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:textColor="@android:color/black"
android:gravity="center"
android:text="이름"
android:textSize="30sp"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent"/>
<EditText
android:id="@+id/name_et"
android:inputType="text"
android:imeOptions="actionNext"
android:maxLines="1"
android:gravity="center"
android:textColor="@android:color/black"
android:textSize="30sp"
android:layout_weight="8"
android:layout_width="0dp"
android:layout_height="match_parent"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp">
<TextView
android:textColor="@android:color/black"
android:gravity="center"
android:text="나이"
android:textSize="30sp"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent"/>
<EditText
android:id="@+id/age_et"
android:inputType="number"
android:imeOptions="actionDone"
android:maxLines="1"
android:gravity="center"
android:textColor="@android:color/black"
android:textSize="30sp"
android:layout_weight="8"
android:layout_width="0dp"
android:layout_height="match_parent"/>
</LinearLayout>
<Button
android:background="#0517EB"
android:imeOptions="actionDone"
android:id="@+id/add_bt"
android:textColor="@android:color/white"
android:textSize="30sp"
android:text="추가"
android:layout_marginBottom="20dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:background="#8005EB"
android:imeOptions="actionDone"
android:id="@+id/send_bt"
android:textColor="@android:color/white"
android:textSize="30sp"
android:text="전송"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
참고 사항
EditText에서 android:imeOptions = "ActionNext" 를 추가하면 다음 EditText로 넘어갈 수 있습니다.
2. activity_request.xml (이전 글을 보셨다면 해당 레이아웃은 동일합니다.)
<?xml version="1.0" encoding="utf-8"?>
<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:id="@+id/request_layout"
tools:context=".RequestActivity"
android:orientation="horizontal">
</LinearLayout>
3.fragment1.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
전달 받은 리스트를 띄워주기 위해서 리스트뷰를 추가했습니다.
4. Person.java
import android.os.Parcel;
import android.os.Parcelable;
public class Person implements Parcelable {
String name;
int age;
public Person() {
}
//객체를 받아올때 호출
protected Person(Parcel in) {
name = in.readString();
age = in.readInt();
}
public static final Creator<Person> CREATOR = new Creator<Person>() {
@Override
public Person createFromParcel(Parcel in) {
return new Person(in);
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
@Override
public int describeContents() {
return 0;
}
//객체를 전달할때 호출
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(age);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
원하는 객체에 Parcelable을 implements 해주시고 alt + enter만 누르시면 함수와 생성자가 생기게 됩니다.
객체를 받아올때, 전달할때 호출되는 함수에서 보시면
Parcel.read...()
Parcel.write...()
함수가 보이실텐데 밑에 사진에 보시면 지원되는 형태가 많습니다.
원하시는 함수를 사용해주시면 될 것 같습니다.
혹시라도 ArrayList<Person>처럼 본인이 직접 만든 객체를 담은 리스트를 전달해야 하는 경우도 있기 때문에 Company라는 객체를 추가하여 예제를 만들어보겠습니다.
5. Company.java
import android.os.Parcel;
import android.os.Parcelable;
import java.util.ArrayList;
public class Company implements Parcelable {
ArrayList<Person> persons;
public Company(){ }
protected Company(Parcel in) {
persons = new ArrayList<>();
in.readTypedList(persons,Person.CREATOR);
}
public static final Creator<Company> CREATOR = new Creator<Company>() {
@Override
public Company createFromParcel(Parcel in) {
return new Company(in);
}
@Override
public Company[] newArray(int size) {
return new Company[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeTypedList(persons);
}
public ArrayList<Person> getPersons() {
return persons;
}
public void setPersons(ArrayList<Person> persons) {
this.persons = persons;
}
}
protected Company(Parcel in) {
persons = new ArrayList<>();
in.readTypedList(persons,Person.CREATOR);
}
객체를 담은 ArrayList를 전달할때 코드를 해당 부분처럼 해줘야 오류가 나지 않습니다.
6. MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.AppCompatEditText;
import android.content.Intent;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
EditText name_et, age_et;
Button add_bt, send_bt;
ArrayList<Person> persons;
Company company;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
persons = new ArrayList<>();
name_et = findViewById(R.id.name_et);
age_et = findViewById(R.id.age_et);
add_bt = findViewById(R.id.add_bt);
add_bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//EditText의 텍스트 가져오기
String name = name_et.getText().toString();
int age = Integer.parseInt(age_et.getText().toString());
//Person객체 생성
Person person = new Person();
person.setName(name);
person.setAge(age);
//ArrayList에 추가
persons.add(person);
//EditText 초기화
name_et.setText("");
age_et.setText("");
Toast.makeText(MainActivity.this, "데이터 추가", Toast.LENGTH_SHORT).show();
}
});
send_bt = findViewById(R.id.send_bt);
send_bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
company = new Company();
company.setPersons(persons);
//RequestActivity로 전달할 인텐트 생성
Intent intent = new Intent(MainActivity.this, RequestActivity.class);
//ArrayList 인텐트에 저장
intent.putExtra("company",company);
//RequestActivity 시작
startActivity(intent);
}
});
}
}
7. RequestActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import java.util.ArrayList;
public class RequestActivity extends AppCompatActivity {
Fragment1 fragment1;
Company company;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_request);
//MainActivity의 인텐트를 받아서 ArrayList 저장
Intent intent = getIntent();
company = intent.getParcelableExtra("company");
//fragment 생성
fragment1 = new Fragment1();
//requestActivity에 fragment1을 띄워줌
getSupportFragmentManager().beginTransaction().replace(R.id.request_layout,fragment1).commit();
//번들객체 생성, ArrayList 전달
Bundle bundle = new Bundle();
bundle.putParcelable("company",company);
//fragment1로 번들 전달
fragment1.setArguments(bundle);
}
}
8. Fragment1.java
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import java.util.ArrayList;
public class Fragment1 extends Fragment {
ViewGroup viewGroup;
ListView lv;
Company company;
ArrayList<String> str_persons;
ArrayAdapter<String> adapter;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
viewGroup = (ViewGroup) inflater.inflate(R.layout.fragment1,container,false);
lv = viewGroup.findViewById(R.id.lv);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//ListView 아이템 클릭시 토스트 메세지 띄우기
Toast.makeText(getContext(),str_persons.get(position),Toast.LENGTH_SHORT);
}
});
//RequestActivity에서 전달한 번들 저장
Bundle bundle = getArguments();
company = bundle.getParcelable("company");
//ListView에 띄우기 위해서 ArrayList<String> 생성
str_persons = new ArrayList<>();
for(Person person:company.getPersons()){
String str_person = "이름 " + person.getName() + "\n나이 " + person.getAge();
str_persons.add(str_person);
}
//ListView의 Adapter생성, 세팅
adapter = new ArrayAdapter(getContext(),android.R.layout.simple_list_item_1,str_persons);
lv.setAdapter(adapter);
return viewGroup;
}
}
실행해보시면 입력 값이 리스트에 띄워지는것을 확인하실 수 있습니다.
그냥 기본적인 예제이기 때문에 정답이라고 할 수 없습니다.
필요하신대로 코드를 수정하여 사용하시기 바랍니다.
Parcelable의 더 자세한 내용은 링크를 참고해주세요