활성 프레임 간 뷰 모델 공유

8231 단어 AndroidViewModel

입문


안녕하세요.안드로이드의 View Model, 편리하죠.
활동이 재생성될 때의 데이터 복구를 간소화할 수 있지만 다음과 같은 일을 하고 싶습니다.

하고 싶은 일


다양한 범위의 활동이나 활동, 프레임 간에 ViewModel 공유

그림에서 보듯이 First Activity와 Second Activity에서 같은 View Model을 공유할 수 있다면 좋겠다.
구체적으로 말하면 사진의 뷰어에서 다음과 같이 Grid의 디스플레이와 목록의 디스플레이 기능을 전환할 수 있다.

이 두 화면 모두 같은 이미지 목록을 가지고 있고 사진의 정보도 같기 때문에 같은 View Model을 공유하고 싶습니다.

뷰 모델 공유 정보


프레임 간에 뷰 모델을 공유할 수 있습니다.
https://developer.android.com/topic/libraries/architecture/viewmodel?hl=JA#sharing
Activity는 공유되므로 역할 영역은 공통입니다.(말이 있는지 모르겠다)
이번에는 Fragment와 Activity 사이에서 소통하고 싶어서 이 방법으로는 잘 안 돼요.

ViewModelStoreOwner


따라서 View Model Store Owner가 등장할 차례입니다.
ViewModelStoreOwner ViewModel을 저장하는 ViewModelStore의 역할 영역을 정의할 수 있습니다.
ViewModelStoreOwner는 추상적인 방법 하나만 있는 인터페이스입니다.
public interface ViewModelStoreOwner {
    /**
     * Returns owned {@link ViewModelStore}
     *
     * @return a {@code ViewModelStore}
     */
    @NonNull
    ViewModelStore getViewModelStore();
}
프로세스로서 ViewModel을 공유하고 싶은 Activity에 ViewModel Store Owner를 설치하고 공동의 ViewModel Store를 사용하면 좋겠다고 생각합니다.
우선, 같은 View Model Store를 얻기 위해, 우리는 View Model Store Owner에 기본적으로 실현된 인터페이스를 추가할 준비를 했습니다.
interface PhotoViewModelStoreOwner : ViewModelStoreOwner {
     override fun getViewModelStore(): ViewModelStore = // SingletonなViewModelStoreをDIなどで挿入
}
이를 ViewModel을 공유하려는 Activity, Fragment로 구현합니다.
class PhotoGridFragment : Fragment(), SnapPhotoViewModelStoreOwner {
     private val viewModel: PhotoViewModel by lazy {
        PhotoViewModel.get(id, photoTag, this)
     }
     override fun getViewModelStore(): ViewModelStore {
        return super<PhotoViewModelStoreOwner>.getViewModelStore()
     }
}
class PhotoListActivity : AppCompatActivity(), SnapPhotoViewModelStoreOwner {
     private val viewModel: PhotoViewModel by lazy {
        PhotoViewModel.get(id, photoTag, this)
     }
     override fun getViewModelStore(): ViewModelStore {
        return super<PhotoViewModelStoreOwner>.getViewModelStore()
     }
}

그리고 View Model 방면에서 공장 방법을 준비했다.
companion object {
        fun get(
            id: Int,
            photoTag: String?,
            viewModelStoreOwner: SnapPhotoViewModelStoreOwner
        ): PhotoViewModel = ViewModelProvider(viewModelStoreOwner, PhotoViewModelFactory(id, photoTag))
                .get(photoTag ?: "all", PhotoViewModel::class.java)
}
이제 뷰 모델을 공유할 수 있습니다.
또한clear가 정확하지 않으면ViewModelStore에 ViewModel이 저장되므로 역할역이 긴 Activity or Fragment의 on Destry clear를 사용하면 된다.
override fun onDestroy() {
        viewModelStore.clear()
        super.onDestroy()
}

경품


ActivityScope의ViewModel에서는 서로 다른 범위의 사람들이 공유할 수 없지만 ApplicationScope는 Activity가 폐기된 후에도 생존할 수 있기 때문에 공유할 수 있다.
방법은 ViewModelStoreOwner 구현을 애플리케이션으로 전환하는 것입니다.
class MyApplication : Application, ViewModelStoreOwner {
    private val viewModelStore : ViewModelStore = ViewModelStore()
    override fun getViewModelStore(): ViewModelStore = viewModelStore
}

그러나 이런 방법이라면clear를 할 수 없고ViewModel은 Activity가 사라진 후에도 영원히 보존되기 때문에 좋은 방법은 아니다.

좋은 웹페이지 즐겨찾기