Fragment간 데이터 주고받기 (ViewModel 사용)
안드로이드 앱을 만들다 보면 Fragment를 이용하여 앱 구성을 하게 되고 이때 구성된 Fragment간에 데이터를 주고받을 일이 거의 필수적으로 생기게 됩니다.
여기서는 Fragment간 데이터를 주고 받는 방법에 대해서 공식 문서를 참고하여 간략히 정리하고자 합니다.
Fragment간 데이터를 주고 받으려고 할때 주의점은 Fragment간에 직접적으로 데이터를 주고받으면 안되고 Shared ViewModel을 이용하거나 Fragment와 연결된 Activity를 통해서 데이터를 주고 받아야됩니다.
주로 interface를 활용하여 Fragment간 데이터를 Activity를 통해서 주고 받는 방법을 많이 사용했었는데, 여기서는 ViewModel을 이용하여 Fragment간 데이터를 주고 받는 예제를 살펴보도록 하겠습니다.
[참고] 안드로이드 공식문서 - ViewModel Overview
혹시 안드로이드 공식문서 참고하실분은 하기 링크 문서에서 Share data between fragments 부분을 보시면 됩니다.
https://developer.android.com/topic/libraries/architecture/viewmodel#java
예제) ChattingFragment의 채팅창 데이터를 MonitoringFragment로 실시간 전달하기 (ViewModel 사용)
예제는 ChattingFragment의 채팅창 입력내용이 MonitoringFragment에 전달되어 Monitoring Fragment 채팅창에 실시간 반영되도록 하는 간단한 예제입니다.
※ Fragment간 데이터 입력 및 전송 요약
1) ViewModel 클래스 정의
2) ChattingFragment의 sharedViewModel.setLiveData( ... ); 에서 전달 데이터 입력
3) MonitoringFragment의 sharedViewModel.getLiveData().observe( ... ); 에서 데이터 수신
요약 내용을 보시고 아래 예제를 천천히 살펴보면 어렵지 않게 이해하실 수 있습니다.
1. build.gradle에 dependencies 추가
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
2. ViewModel 클래스
- SharedViewModel.java
public class SharedViewModel extends ViewModel {
private final MutableLiveData<String> liveData = new MutableLiveData<>();
public LiveData<String> getLiveData() {
return liveData;
}
public void setLiveData(String str) {
liveData.setValue(str);
}
}
3. ChattingFragment
- ChattingFragment.java
public class ChattingFragment extends Fragment {
private SharedViewModel sharedViewModel;
private EditText chattingEditText;
private Button sendButton;
private TextView chattingTextView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_chatting, container, false);
chattingEditText = rootView.findViewById(R.id.chatting_editText);
sendButton = rootView.findViewById(R.id.send_button);
chattingTextView = rootView.findViewById(R.id.chatting_textView);
sendButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String preMessage = chattingTextView.getText().toString();
chattingTextView.setText(chattingEditText.getText().toString() + "\n" + preMessage);
sharedViewModel.setLiveData(chattingEditText.getText().toString() + "\n" + preMessage);
chattingEditText.setText("");
}
});
return rootView;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
sharedViewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
}
}
- fragment_chatting.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"
tools:context=".ChattingFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/chatting_editText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<Button
android:id="@+id/send_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="전송"/>
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/chatting_textView"
android:textSize="24dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</ScrollView>
</LinearLayout>
4. MonitoringFragment
- MonitoringFragment.java
public class MonitoringFragment extends Fragment {
private SharedViewModel sharedViewModel;
private TextView monitoringTextView;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_monitoring, container, false);
monitoringTextView = (TextView) rootView.findViewById(R.id.monitoring_textView);
return rootView;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
sharedViewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
sharedViewModel.getLiveData().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(String s) {
monitoringTextView.setText(s);
}
});
}
}
- fragment_monitoring.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"
tools:context=".ChattingFragment">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="#FFFFFF"
android:background="#000000"
android:text="Monitoring Fragment"
android:textSize="24dp" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/monitoring_textView"
android:textColor="@color/colorAccent"
android:textSize="24dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</ScrollView>
</LinearLayout>
5. MainActivity
- MainActivity.java
public class MainActivity extends AppCompatActivity {
private ChattingFragment chattingFragment;
private MonitoringFragment monitoringFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
chattingFragment = (ChattingFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_chatting);
monitoringFragment = (MonitoringFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_monitoring);
}
}
- 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"
tools:context=".MainActivity">
<fragment
android:id="@+id/fragment_chatting"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:name="com.kadosholy.fragment_communication_viewmodel.ChattingFragment"
tools:layout="@layout/fragment_chatting" />
<fragment
android:id="@+id/fragment_monitoring"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:name="com.kadosholy.fragment_communication_viewmodel.MonitoringFragment"
tools:layout="@layout/fragment_monitoring" />
</LinearLayout>
[참고] Fragment간 데이터 주고받기 (interface 사용)
https://kadosholy.tistory.com/26
'IT 개발 > Android' 카테고리의 다른 글
[안드로이드] Fragment간 데이터 주고받기 (Interface 사용) (0) | 2020.06.17 |
---|---|
[안드로이드] Volley 사용법 - 로또 번호 가져오기 (1) | 2020.05.31 |
[안드로이드] 데이터 저장하기 - SQLite Database사용법 (0) | 2020.05.19 |
[안드로이드] TabLayout과 ViewPager (Material Design) (1) | 2020.04.19 |
[안드로이드] 안드로이드 스튜디오 설치 및 시작하기 (0) | 2020.04.06 |