본문 바로가기
Programming/Android

[Android-java] 여러 Fragment에 한 ViewModel 공유하기

by IN.0 2023. 3. 13.
728x90
반응형

구글링을 열심히 하다가, 코틀린 코드는 많은데 자바 버전이 별로 없어서 남겨본다.


아래와 같이 뷰모델을 정의한다.

// SharedViewModel.java

public class SharedViewModel extends ViewModel {
    private MutableLiveData<String> data = new MutableLiveData<>();

    public void setData(String input) {
        data.setValue(input);
    }

    public LiveData<String> getData() {
        return data;
    }
}

 

위에서 정의한 ViewModel을 여러 Fragment에서 사용하도록 하자.

먼저, Fragment A에서 ViewModel을 생성하고 데이터를 설정하는 방법은 다음과 같다.

// FragmentA.java

public class FragmentA extends Fragment {
    private SharedViewModel sharedViewModel;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        sharedViewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);

        // 데이터 설정
        sharedViewModel.setData("Hello from Fragment A");

        // ...
    }

    // ...
}

다음으로, Fragment B에서 ViewModel을 공유하여 데이터를 가져오는 방법은 아래와 같다.

// FragmentB.java

public class FragmentB extends Fragment {
    private SharedViewModel sharedViewModel;
    private TextView textView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_b, container, false);

        // ViewModel 공유
        sharedViewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);

        textView = view.findViewById(R.id.textView);

        // 데이터 감시
        sharedViewModel.getData().observe(getViewLifecycleOwner(), new Observer<String>() {
            @Override
            public void onChanged(String s) {
                textView.setText(s);
            }
        });

        // ...
    }

    // ...
}

 

이렇게 되면 Fragment A에서 설정한 데이터가 Fragment B에서 표시된다.

이 방법은 Activity의 ViewModelStore를 사용하여 ViewModel을 공유한다.

ViewModelStore는 액티비티 생명주기에 따라 관리되며, 액티비티가 파괴될 때 ViewModel도 함께 파괴된다.

따라서 Fragment A와 Fragment B가 같은 액티비티에 속하고 있다면 ViewModel을 공유할 수 있다.

 


만약 ViewModel에 Factory를 사용할 경우 아래 내용을 추가로 참조하자.

 

ViewModel에 아래 코드를 추가해 준다.

// SharedViewModel.java에 아래 코드 추가

public class SharedViewModelFactory implements ViewModelProvider.Factory {

    private String inputData;

    public SharedViewModelFactory(String inputData) {
        this.inputData = inputData;
    }

    @NonNull
    @Override
    public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
        if (modelClass.isAssignableFrom(SharedViewModel.class)) {
            return (T) new SharedViewModel(inputData);
        }
        throw new IllegalArgumentException("Unknown ViewModel class");
    }
}

SharedViewModelFactory 클래스는 생성자를 통해 입력 데이터를 전달받고,

create() 메소드를 통해 ViewModel 객체를 만든다.

그리고, FragmentA에서 SharedViewModel 객체를 생성할 때 Factory를 사용하여 만든다.

// FragmentA.java를 아래와 같이 수정

public class FragmentA extends Fragment {
    private SharedViewModel sharedViewModel;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        String inputData = "Hello from Fragment A";
        SharedViewModelFactory factory = new SharedViewModelFactory(inputData);
        sharedViewModel = new ViewModelProvider(requireActivity(), factory).get(SharedViewModel.class);

        // ...

        return view;
    }

    // ...
}

FragmentB에서는 기존과 동일하게 ViewModel을 공유할 수도, 위와 같이 Factory를 통해 공유할 수도 있다.

 

728x90
반응형

댓글