/* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.app; import com.android.ide.common.rendering.api.IProjectCallback; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; import android.content.Context; import android.os.Bundle; /** * Delegate used to provide new implementation of a select few methods of {@link Fragment} * * Through the layoutlib_create tool, the original methods of Fragment have been replaced * by calls to methods of the same name in this delegate class. * * The methods being re-implemented are the ones responsible for instantiating Fragment objects. * Because the classes of these objects are found in the project, these methods need access to * {@link IProjectCallback} object. They are however static methods, so the callback is set * before the inflation through {@link #setProjectCallback(IProjectCallback)}. */ public class Fragment_Delegate { private static IProjectCallback sProjectCallback; /** * Sets the current {@link IProjectCallback} to be used to instantiate classes coming * from the project being rendered. */ public static void setProjectCallback(IProjectCallback projectCallback) { sProjectCallback = projectCallback; } /** * Like {@link #instantiate(Context, String, Bundle)} but with a null * argument Bundle. */ @LayoutlibDelegate /*package*/ static Fragment instantiate(Context context, String fname) { return instantiate(context, fname, null); } /** * Create a new instance of a Fragment with the given class name. This is * the same as calling its empty constructor. * * @param context The calling context being used to instantiate the fragment. * This is currently just used to get its ClassLoader. * @param fname The class name of the fragment to instantiate. * @param args Bundle of arguments to supply to the fragment, which it * can retrieve with {@link #getArguments()}. May be null. * @return Returns a new fragment instance. * @throws InstantiationException If there is a failure in instantiating * the given fragment class. This is a runtime exception; it is not * normally expected to happen. */ @LayoutlibDelegate /*package*/ static Fragment instantiate(Context context, String fname, Bundle args) { try { if (sProjectCallback != null) { Fragment f = (Fragment) sProjectCallback.loadView(fname, new Class[0], new Object[0]); if (args != null) { args.setClassLoader(f.getClass().getClassLoader()); f.mArguments = args; } return f; } return null; } catch (ClassNotFoundException e) { throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname + ": make sure class name exists, is public, and has an" + " empty constructor that is public", e); } catch (java.lang.InstantiationException e) { throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname + ": make sure class name exists, is public, and has an" + " empty constructor that is public", e); } catch (IllegalAccessException e) { throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname + ": make sure class name exists, is public, and has an" + " empty constructor that is public", e); } catch (Exception e) { throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname + ": make sure class name exists, is public, and has an" + " empty constructor that is public", e); } } }