1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/*
2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Copyright (C) 2010 The Android Open Source Project
3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *
4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * you may not use this file except in compliance with the License.
6282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * You may obtain a copy of the License at
7282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *
8282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
9282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *
10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Unless required by applicable law or agreed to in writing, software
11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * See the License for the specific language governing permissions and
14282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * limitations under the License.
15282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */
16282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipackage android.app;
18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1937dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Guptaimport com.android.ide.common.rendering.api.LayoutlibCallback;
20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.tools.layoutlib.annotations.LayoutlibDelegate;
21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.content.Context;
23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.os.Bundle;
24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/**
26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Delegate used to provide new implementation of a select few methods of {@link Fragment}
27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *
28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Through the layoutlib_create tool, the original  methods of Fragment have been replaced
29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * by calls to methods of the same name in this delegate class.
30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *
31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * The methods being re-implemented are the ones responsible for instantiating Fragment objects.
32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Because the classes of these objects are found in the project, these methods need access to
3337dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta * {@link LayoutlibCallback} object. They are however static methods, so the callback is set
3437dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta * before the inflation through {@link #setLayoutlibCallback(LayoutlibCallback)}.
35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */
36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipublic class Fragment_Delegate {
37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
3837dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta    private static LayoutlibCallback sLayoutlibCallback;
39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /**
4137dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta     * Sets the current {@link LayoutlibCallback} to be used to instantiate classes coming
42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * from the project being rendered.
43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     */
4437dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta    public static void setLayoutlibCallback(LayoutlibCallback layoutlibCallback) {
4537dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta        sLayoutlibCallback = layoutlibCallback;
46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /**
49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * Like {@link #instantiate(Context, String, Bundle)} but with a null
50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * argument Bundle.
51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     */
52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @LayoutlibDelegate
53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /*package*/ static Fragment instantiate(Context context, String fname) {
54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return instantiate(context, fname, null);
55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /**
58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * Create a new instance of a Fragment with the given class name.  This is
59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * the same as calling its empty constructor.
60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     *
61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * @param context The calling context being used to instantiate the fragment.
62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * This is currently just used to get its ClassLoader.
63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * @param fname The class name of the fragment to instantiate.
64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * @param args Bundle of arguments to supply to the fragment, which it
6537dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta     * can retrieve with {@link Fragment#getArguments()}.  May be null.
66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * @return Returns a new fragment instance.
6737dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta     * @throws Fragment.InstantiationException If there is a failure in instantiating
68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * the given fragment class.  This is a runtime exception; it is not
69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * normally expected to happen.
70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     */
71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @LayoutlibDelegate
72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /*package*/ static Fragment instantiate(Context context, String fname, Bundle args) {
73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        try {
7437dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta            if (sLayoutlibCallback != null) {
7537dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta                Fragment f = (Fragment) sLayoutlibCallback.loadView(fname,
76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        new Class[0], new Object[0]);
77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (args != null) {
79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    args.setClassLoader(f.getClass().getClassLoader());
80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    f.mArguments = args;
81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                return f;
83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return null;
86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } catch (ClassNotFoundException e) {
87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    + ": make sure class name exists, is public, and has an"
89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    + " empty constructor that is public", e);
90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } catch (java.lang.InstantiationException e) {
91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    + ": make sure class name exists, is public, and has an"
93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    + " empty constructor that is public", e);
94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } catch (IllegalAccessException e) {
95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    + ": make sure class name exists, is public, and has an"
97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    + " empty constructor that is public", e);
98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } catch (Exception e) {
99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    + ": make sure class name exists, is public, and has an"
101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    + " empty constructor that is public", e);
102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
105