1 /*
2  * Copyright 2019 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("ViewTreeLifecycleOwner")
17 
18 package androidx.lifecycle
19 
20 import android.view.View
21 import androidx.core.viewtree.getParentOrViewTreeDisjointParent
22 import androidx.lifecycle.runtime.R
23 
24 /**
25  * Set the [LifecycleOwner] responsible for managing the given [View]. Calls to [get] from this view
26  * or descendants will return `lifecycleOwner`.
27  *
28  * This should only be called by constructs such as activities or fragments that manage a view tree
29  * and reflect their own lifecycle through a [LifecycleOwner]. Callers should only set a
30  * [LifecycleOwner] that will be *stable.* The associated lifecycle should report that it is
31  * destroyed if the view tree is removed and is not guaranteed to later become reattached to a
32  * window.
33  *
34  * @param lifecycleOwner LifecycleOwner representing the manager of the given view
35  */
36 @JvmName("set")
setViewTreeLifecycleOwnernull37 public fun View.setViewTreeLifecycleOwner(lifecycleOwner: LifecycleOwner?) {
38     setTag(R.id.view_tree_lifecycle_owner, lifecycleOwner)
39 }
40 
41 /**
42  * Retrieve the [LifecycleOwner] responsible for managing the given [View]. This may be used to
43  * scope work or heavyweight resources associated with the view that may span cycles of the view
44  * becoming detached and reattached from a window.
45  *
46  * @return The [LifecycleOwner] responsible for managing this view and/or some subset of its
47  *   ancestors
48  */
49 @JvmName("get")
findViewTreeLifecycleOwnernull50 public fun View.findViewTreeLifecycleOwner(): LifecycleOwner? {
51     var currentView: View? = this
52     while (currentView != null) {
53         val lifecycleOwner = currentView.getTag(R.id.view_tree_lifecycle_owner) as? LifecycleOwner
54         if (lifecycleOwner != null) {
55             return lifecycleOwner
56         }
57         currentView = currentView.getParentOrViewTreeDisjointParent() as? View
58     }
59     return null
60 }
61