19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.view;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
197b9c912f536925ac6ec43935d6e97506851b33d6Tor Norbyeimport android.annotation.IdRes;
207b9c912f536925ac6ec43935d6e97506851b33d6Tor Norbyeimport android.annotation.LayoutRes;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Canvas;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet;
25b27b7a152437d6ebb4f2a2700858b69634c00acdJeff Sharkeyimport android.widget.RemoteViews.RemoteView;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.R;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29b6af533114cfa5a4547990e79e96bd0402c47e72Mihai Predaimport java.lang.ref.WeakReference;
30b6af533114cfa5a4547990e79e96bd0402c47e72Mihai Preda
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A ViewStub is an invisible, zero-sized View that can be used to lazily inflate
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * layout resources at runtime.
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * When a ViewStub is made visible, or when {@link #inflate()}  is invoked, the layout resource
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is inflated. The ViewStub then replaces itself in its parent with the inflated View or Views.
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Therefore, the ViewStub exists in the view hierarchy until {@link #setVisibility(int)} or
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #inflate()} is invoked.
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The inflated View is added to the ViewStub's parent with the ViewStub's layout
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * parameters. Similarly, you can define/override the inflate View's id by using the
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ViewStub's inflatedId property. For instance:
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre>
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     &lt;ViewStub android:id="@+id/stub"
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *               android:inflatedId="@+id/subTree"
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *               android:layout="@layout/mySubTree"
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *               android:layout_width="120dip"
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *               android:layout_height="40dip" /&gt;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </pre>
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The ViewStub thus defined can be found using the id "stub." After inflation of
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the layout resource "mySubTree," the ViewStub is removed from its parent. The
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * View created by inflating the layout resource "mySubTree" can be found using the
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * id "subTree," specified by the inflatedId property. The inflated View is finally
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * assigned a width of 120dip and a height of 40dip.
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The preferred way to perform the inflation of the layout resource is the following:
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre>
6151efddbd3bb304de2dd47fa8cd1114ac555958bbAlan Viverette *     ViewStub stub = findViewById(R.id.stub);
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     View inflated = stub.inflate();
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </pre>
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * When {@link #inflate()} is invoked, the ViewStub is replaced by the inflated View
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and the inflated View is returned. This lets applications get a reference to the
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * inflated View without executing an extra findViewById().
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#ViewStub_inflatedId
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#ViewStub_layout
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
72b27b7a152437d6ebb4f2a2700858b69634c00acdJeff Sharkey@RemoteView
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic final class ViewStub extends View {
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mInflatedId;
7539a72dd207eb009d3bf84bb10b7c72fb7a6853c1Alan Viverette    private int mLayoutResource;
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
77b6af533114cfa5a4547990e79e96bd0402c47e72Mihai Preda    private WeakReference<View> mInflatedViewRef;
78b6af533114cfa5a4547990e79e96bd0402c47e72Mihai Preda
79b27b7a152437d6ebb4f2a2700858b69634c00acdJeff Sharkey    private LayoutInflater mInflater;
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private OnInflateListener mInflateListener;
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ViewStub(Context context) {
8339a72dd207eb009d3bf84bb10b7c72fb7a6853c1Alan Viverette        this(context, 0);
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Creates a new ViewStub with the specified layout resource.
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context The application's environment.
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param layoutResource The reference to a layout resource that will be inflated.
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
927b9c912f536925ac6ec43935d6e97506851b33d6Tor Norbye    public ViewStub(Context context, @LayoutRes int layoutResource) {
9339a72dd207eb009d3bf84bb10b7c72fb7a6853c1Alan Viverette        this(context, null);
9439a72dd207eb009d3bf84bb10b7c72fb7a6853c1Alan Viverette
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLayoutResource = layoutResource;
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ViewStub(Context context, AttributeSet attrs) {
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(context, attrs, 0);
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
102617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    public ViewStub(Context context, AttributeSet attrs, int defStyleAttr) {
103617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette        this(context, attrs, defStyleAttr, 0);
104617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    }
105617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette
106617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    public ViewStub(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
10739a72dd207eb009d3bf84bb10b7c72fb7a6853c1Alan Viverette        super(context);
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10939a72dd207eb009d3bf84bb10b7c72fb7a6853c1Alan Viverette        final TypedArray a = context.obtainStyledAttributes(attrs,
11039a72dd207eb009d3bf84bb10b7c72fb7a6853c1Alan Viverette                R.styleable.ViewStub, defStyleAttr, defStyleRes);
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInflatedId = a.getResourceId(R.styleable.ViewStub_inflatedId, NO_ID);
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLayoutResource = a.getResourceId(R.styleable.ViewStub_layout, 0);
11339a72dd207eb009d3bf84bb10b7c72fb7a6853c1Alan Viverette        mID = a.getResourceId(R.styleable.ViewStub_id, NO_ID);
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        a.recycle();
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setVisibility(GONE);
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setWillNotDraw(true);
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the id taken by the inflated view. If the inflated id is
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link View#NO_ID}, the inflated view keeps its original id.
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return A positive integer used to identify the inflated view or
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         {@link #NO_ID} if the inflated view should keep its id.
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setInflatedId(int)
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @attr ref android.R.styleable#ViewStub_inflatedId
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1307b9c912f536925ac6ec43935d6e97506851b33d6Tor Norbye    @IdRes
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getInflatedId() {
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mInflatedId;
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Defines the id taken by the inflated view. If the inflated id is
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link View#NO_ID}, the inflated view keeps its original id.
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param inflatedId A positive integer used to identify the inflated view or
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                   {@link #NO_ID} if the inflated view should keep its id.
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getInflatedId()
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @attr ref android.R.styleable#ViewStub_inflatedId
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1457b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal    @android.view.RemotableViewMethod(asyncImpl = "setInflatedIdAsync")
1467b9c912f536925ac6ec43935d6e97506851b33d6Tor Norbye    public void setInflatedId(@IdRes int inflatedId) {
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInflatedId = inflatedId;
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1507b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal    /** @hide **/
1517b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal    public Runnable setInflatedIdAsync(@IdRes int inflatedId) {
1527b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal        mInflatedId = inflatedId;
1537b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal        return null;
1547b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal    }
1557b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the layout resource that will be used by {@link #setVisibility(int)} or
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #inflate()} to replace this StubbedView
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in its parent by another view.
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The layout resource identifier used to inflate the new View.
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setLayoutResource(int)
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setVisibility(int)
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #inflate()
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @attr ref android.R.styleable#ViewStub_layout
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1687b9c912f536925ac6ec43935d6e97506851b33d6Tor Norbye    @LayoutRes
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getLayoutResource() {
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mLayoutResource;
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Specifies the layout resource to inflate when this StubbedView becomes visible or invisible
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or when {@link #inflate()} is invoked. The View created by inflating the layout resource is
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * used to replace this StubbedView in its parent.
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param layoutResource A valid layout resource identifier (different from 0.)
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getLayoutResource()
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setVisibility(int)
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #inflate()
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @attr ref android.R.styleable#ViewStub_layout
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1857b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal    @android.view.RemotableViewMethod(asyncImpl = "setLayoutResourceAsync")
1867b9c912f536925ac6ec43935d6e97506851b33d6Tor Norbye    public void setLayoutResource(@LayoutRes int layoutResource) {
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLayoutResource = layoutResource;
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1907b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal    /** @hide **/
1917b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal    public Runnable setLayoutResourceAsync(@LayoutRes int layoutResource) {
1927b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal        mLayoutResource = layoutResource;
1937b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal        return null;
1947b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal    }
1957b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal
196b27b7a152437d6ebb4f2a2700858b69634c00acdJeff Sharkey    /**
197b27b7a152437d6ebb4f2a2700858b69634c00acdJeff Sharkey     * Set {@link LayoutInflater} to use in {@link #inflate()}, or {@code null}
198b27b7a152437d6ebb4f2a2700858b69634c00acdJeff Sharkey     * to use the default.
199b27b7a152437d6ebb4f2a2700858b69634c00acdJeff Sharkey     */
200b27b7a152437d6ebb4f2a2700858b69634c00acdJeff Sharkey    public void setLayoutInflater(LayoutInflater inflater) {
201b27b7a152437d6ebb4f2a2700858b69634c00acdJeff Sharkey        mInflater = inflater;
202b27b7a152437d6ebb4f2a2700858b69634c00acdJeff Sharkey    }
203b27b7a152437d6ebb4f2a2700858b69634c00acdJeff Sharkey
204b27b7a152437d6ebb4f2a2700858b69634c00acdJeff Sharkey    /**
205b27b7a152437d6ebb4f2a2700858b69634c00acdJeff Sharkey     * Get current {@link LayoutInflater} used in {@link #inflate()}.
206b27b7a152437d6ebb4f2a2700858b69634c00acdJeff Sharkey     */
207b27b7a152437d6ebb4f2a2700858b69634c00acdJeff Sharkey    public LayoutInflater getLayoutInflater() {
208b27b7a152437d6ebb4f2a2700858b69634c00acdJeff Sharkey        return mInflater;
209b27b7a152437d6ebb4f2a2700858b69634c00acdJeff Sharkey    }
210b27b7a152437d6ebb4f2a2700858b69634c00acdJeff Sharkey
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setMeasuredDimension(0, 0);
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void draw(Canvas canvas) {
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void dispatchDraw(Canvas canvas) {
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * When visibility is set to {@link #VISIBLE} or {@link #INVISIBLE},
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #inflate()} is invoked and this StubbedView is replaced in its parent
227f54df840fb31772bfabb5d4ac604897da19cf619Tim Hutt     * by the inflated layout resource. After that calls to this function are passed
228f54df840fb31772bfabb5d4ac604897da19cf619Tim Hutt     * through to the inflated view.
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param visibility One of {@link #VISIBLE}, {@link #INVISIBLE}, or {@link #GONE}.
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #inflate()
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2357b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal    @android.view.RemotableViewMethod(asyncImpl = "setVisibilityAsync")
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setVisibility(int visibility) {
237b6af533114cfa5a4547990e79e96bd0402c47e72Mihai Preda        if (mInflatedViewRef != null) {
238b6af533114cfa5a4547990e79e96bd0402c47e72Mihai Preda            View view = mInflatedViewRef.get();
239b6af533114cfa5a4547990e79e96bd0402c47e72Mihai Preda            if (view != null) {
240b6af533114cfa5a4547990e79e96bd0402c47e72Mihai Preda                view.setVisibility(visibility);
241b6af533114cfa5a4547990e79e96bd0402c47e72Mihai Preda            } else {
242b6af533114cfa5a4547990e79e96bd0402c47e72Mihai Preda                throw new IllegalStateException("setVisibility called on un-referenced view");
243b6af533114cfa5a4547990e79e96bd0402c47e72Mihai Preda            }
24458acbafcf2263232c4805cf7a39196acf03763d9Adam Powell        } else {
245b6af533114cfa5a4547990e79e96bd0402c47e72Mihai Preda            super.setVisibility(visibility);
24658acbafcf2263232c4805cf7a39196acf03763d9Adam Powell            if (visibility == VISIBLE || visibility == INVISIBLE) {
24758acbafcf2263232c4805cf7a39196acf03763d9Adam Powell                inflate();
24858acbafcf2263232c4805cf7a39196acf03763d9Adam Powell            }
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2527b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal    /** @hide **/
2537b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal    public Runnable setVisibilityAsync(int visibility) {
2547b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal        if (visibility == VISIBLE || visibility == INVISIBLE) {
2557b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal            ViewGroup parent = (ViewGroup) getParent();
2567b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal            return new ViewReplaceRunnable(inflateViewNoAdd(parent));
2577b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal        } else {
2587b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal            return null;
2597b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal        }
2607b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal    }
2617b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal
2627b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal    private View inflateViewNoAdd(ViewGroup parent) {
2637b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal        final LayoutInflater factory;
2647b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal        if (mInflater != null) {
2657b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal            factory = mInflater;
2667b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal        } else {
2677b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal            factory = LayoutInflater.from(mContext);
2687b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal        }
2697b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal        final View view = factory.inflate(mLayoutResource, parent, false);
2707b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal
2717b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal        if (mInflatedId != NO_ID) {
2727b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal            view.setId(mInflatedId);
2737b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal        }
2747b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal        return view;
2757b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal    }
2767b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal
2777b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal    private void replaceSelfWithView(View view, ViewGroup parent) {
2787b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal        final int index = parent.indexOfChild(this);
2797b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal        parent.removeViewInLayout(this);
2807b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal
2817b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal        final ViewGroup.LayoutParams layoutParams = getLayoutParams();
2827b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal        if (layoutParams != null) {
2837b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal            parent.addView(view, index, layoutParams);
2847b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal        } else {
2857b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal            parent.addView(view, index);
2867b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal        }
2877b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal    }
2887b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Inflates the layout resource identified by {@link #getLayoutResource()}
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and replaces this StubbedView in its parent by the inflated layout resource.
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The inflated layout resource.
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View inflate() {
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ViewParent viewParent = getParent();
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (viewParent != null && viewParent instanceof ViewGroup) {
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mLayoutResource != 0) {
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final ViewGroup parent = (ViewGroup) viewParent;
3027b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal                final View view = inflateViewNoAdd(parent);
3037b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal                replaceSelfWithView(view, parent);
304b6af533114cfa5a4547990e79e96bd0402c47e72Mihai Preda
3057b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal                mInflatedViewRef = new WeakReference<>(view);
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mInflateListener != null) {
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mInflateListener.onInflate(this, view);
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return view;
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new IllegalArgumentException("ViewStub must have a valid layoutResource");
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalStateException("ViewStub must have a non-null ViewGroup viewParent");
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Specifies the inflate listener to be notified after this ViewStub successfully
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * inflated its layout resource.
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param inflateListener The OnInflateListener to notify of successful inflation.
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see android.view.ViewStub.OnInflateListener
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setOnInflateListener(OnInflateListener inflateListener) {
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInflateListener = inflateListener;
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Listener used to receive a notification after a ViewStub has successfully
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * inflated its layout resource.
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see android.view.ViewStub#setOnInflateListener(android.view.ViewStub.OnInflateListener)
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static interface OnInflateListener {
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Invoked after a ViewStub successfully inflated its layout resource.
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * This method is invoked after the inflated view was added to the
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * hierarchy but before the layout pass.
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param stub The ViewStub that initiated the inflation.
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param inflated The inflated View.
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        void onInflate(ViewStub stub, View inflated);
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3487b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal
3497b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal    /** @hide **/
3507b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal    public class ViewReplaceRunnable implements Runnable {
3517b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal        public final View view;
3527b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal
3537b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal        ViewReplaceRunnable(View view) {
3547b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal            this.view = view;
3557b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal        }
3567b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal
3577b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal        @Override
3587b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal        public void run() {
3597b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal            replaceSelfWithView(view, (ViewGroup) getParent());
3607b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal        }
3617b0e2c7659c5abd9e452cc71a6dbe0fee1d8b12fSunny Goyal    }
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
363