Fragment_Delegate.java revision 19a021038f2f4683dddef651543d7298f5bd7218
1/*
2 * Copyright (C) 2010 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
17package android.app;
18
19import com.android.ide.common.rendering.api.IProjectCallback;
20
21import android.content.Context;
22import android.os.Bundle;
23
24/**
25 * Delegate used to provide new implementation of a select few methods of {@link Fragment}
26 *
27 * Through the layoutlib_create tool, the original  methods of Fragment have been replaced
28 * by calls to methods of the same name in this delegate class.
29 *
30 * The methods being re-implemented are the ones responsible for instantiating Fragment objects.
31 * Because the classes of these objects are found in the project, these methods need access to
32 * {@link IProjectCallback} object. They are however static methods, so the callback is set
33 * before the inflation through {@link #setProjectCallback(IProjectCallback)}.
34 */
35public class Fragment_Delegate {
36
37    private static IProjectCallback sProjectCallback;
38
39    /**
40     * Sets the current {@link IProjectCallback} to be used to instantiate classes coming
41     * from the project being rendered.
42     */
43    public static void setProjectCallback(IProjectCallback projectCallback) {
44        sProjectCallback = projectCallback;
45    }
46
47    /**
48     * Like {@link #instantiate(Context, String, Bundle)} but with a null
49     * argument Bundle.
50     */
51    /*package*/ static Fragment instantiate(Context context, String fname) {
52        return instantiate(context, fname, null);
53    }
54
55    /**
56     * Create a new instance of a Fragment with the given class name.  This is
57     * the same as calling its empty constructor.
58     *
59     * @param context The calling context being used to instantiate the fragment.
60     * This is currently just used to get its ClassLoader.
61     * @param fname The class name of the fragment to instantiate.
62     * @param args Bundle of arguments to supply to the fragment, which it
63     * can retrieve with {@link #getArguments()}.  May be null.
64     * @return Returns a new fragment instance.
65     * @throws InstantiationException If there is a failure in instantiating
66     * the given fragment class.  This is a runtime exception; it is not
67     * normally expected to happen.
68     */
69    /*package*/ static Fragment instantiate(Context context, String fname, Bundle args) {
70        try {
71            if (sProjectCallback != null) {
72                Fragment f = (Fragment) sProjectCallback.loadView(fname,
73                        new Class[0], new Object[0]);
74
75                if (args != null) {
76                    args.setClassLoader(f.getClass().getClassLoader());
77                    f.mArguments = args;
78                }
79                return f;
80            }
81
82            return null;
83        } catch (ClassNotFoundException e) {
84            throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
85                    + ": make sure class name exists, is public, and has an"
86                    + " empty constructor that is public", e);
87        } catch (java.lang.InstantiationException e) {
88            throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
89                    + ": make sure class name exists, is public, and has an"
90                    + " empty constructor that is public", e);
91        } catch (IllegalAccessException e) {
92            throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
93                    + ": make sure class name exists, is public, and has an"
94                    + " empty constructor that is public", e);
95        } catch (Exception e) {
96            throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
97                    + ": make sure class name exists, is public, and has an"
98                    + " empty constructor that is public", e);
99        }
100    }
101}
102