1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 @file:JvmName("ViewTreeViewModelStoreOwner")
17 
18 package androidx.lifecycle
19 
20 import android.view.View
21 import androidx.core.viewtree.getParentOrViewTreeDisjointParent
22 import androidx.lifecycle.viewmodel.R
23 
24 /**
25  * Set the [ViewModelStoreOwner] associated with the given [View]. Calls to [get] from this view or
26  * descendants will return `viewModelStoreOwner`.
27  *
28  * This should only be called by constructs such as activities or fragments that manage a view tree
29  * and retain state through a [ViewModelStoreOwner]. Callers should only set a [ViewModelStoreOwner]
30  * that will be *stable.* The associated [ViewModelStore] should be cleared if the view tree is
31  * removed and is not guaranteed to later become reattached to a window.
32  *
33  * @param viewModelStoreOwner ViewModelStoreOwner associated with the given view
34  */
35 @JvmName("set")
setViewTreeViewModelStoreOwnernull36 public fun View.setViewTreeViewModelStoreOwner(viewModelStoreOwner: ViewModelStoreOwner?) {
37     setTag(R.id.view_tree_view_model_store_owner, viewModelStoreOwner)
38 }
39 
40 /**
41  * Retrieve the [ViewModelStoreOwner] associated with the given [View]. This may be used to retain
42  * state associated with this view across configuration changes.
43  *
44  * @return The [ViewModelStoreOwner] associated with this view and/or some subset of its ancestors
45  */
46 @JvmName("get")
findViewTreeViewModelStoreOwnernull47 public fun View.findViewTreeViewModelStoreOwner(): ViewModelStoreOwner? {
48     var currentView: View? = this
49     while (currentView != null) {
50         val storeOwner =
51             currentView.getTag(R.id.view_tree_view_model_store_owner) as? ViewModelStoreOwner
52         if (storeOwner != null) {
53             return storeOwner
54         }
55         currentView = currentView.getParentOrViewTreeDisjointParent() as? View
56     }
57     return null
58 }
59