반응형

 

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

 

ViewModel 개요  |  Android 개발자  |  Android Developers

ViewModel을 사용하면 수명 주기를 인식하는 방식으로 UI 데이터를 관리할 수 있습니다.

developer.android.com

 

 

예제) 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

 

[안드로이드] Fragment간 데이터 주고받기 (Interface 사용)

Fragment간 데이터 주고받기 (Interface 사용) ViewModel을 이용하여 Fragment간 데이터를 주고받는 예제에 이어 이번에는 Interface를 이용하여 Fragment간 데이터를 주고 받는 방법에 대해서 알아보도록 하겠�

kadosholy.tistory.com

 

반응형

+ Recent posts