diff options
author | Tor Norbye <tnorbye@google.com> | 2011-05-18 12:14:43 -0700 |
---|---|---|
committer | Android Code Review <code-review@android.com> | 2011-05-18 12:14:43 -0700 |
commit | bf6b323f21012b8eb5e8d2e9ba424f71791db045 (patch) | |
tree | 9b18c5f6e3c73a024b874d5c90ed01a87b1d61d3 /eclipse | |
parent | f257edb5a919e1449fa6c65a0841793315c45927 (diff) | |
parent | cd05e93b1194c89fe9eca1ee4b999d2991334f4b (diff) | |
download | sdk-bf6b323f21012b8eb5e8d2e9ba424f71791db045.zip sdk-bf6b323f21012b8eb5e8d2e9ba424f71791db045.tar.gz sdk-bf6b323f21012b8eb5e8d2e9ba424f71791db045.tar.bz2 |
Merge "Basic fragment support" into tools-adt_r11
Diffstat (limited to 'eclipse')
12 files changed, 325 insertions, 18 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/icons/fragment.png b/eclipse/plugins/com.android.ide.eclipse.adt/icons/fragment.png Binary files differnew file mode 100644 index 0000000..35b62b6 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/icons/fragment.png diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/api/IClientRulesEngine.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/api/IClientRulesEngine.java index 6aa4776..e31323b 100755 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/api/IClientRulesEngine.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/api/IClientRulesEngine.java @@ -147,6 +147,14 @@ public interface IClientRulesEngine { String displayIncludeSourceInput(); /** + * Displays an input dialog tailored for inputing the source of a {@code <fragment>} + * layout tag. + * + * @return the fully qualified class name of the fragment activity + */ + String displayFragmentSourceInput(); + + /** * Select the given nodes * * @param nodes the nodes to be selected, never null diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/FragmentRule.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/FragmentRule.java new file mode 100644 index 0000000..3e10efd --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/FragmentRule.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php + * + * 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 com.android.ide.common.layout; + +import static com.android.ide.common.layout.LayoutConstants.ANDROID_URI; +import static com.android.ide.common.layout.LayoutConstants.ATTR_NAME; + +import com.android.ide.common.api.INode; +import com.android.ide.common.api.IViewRule; +import com.android.ide.common.api.InsertType; + +/** + * An {@link IViewRule} for the special XML {@code <fragment>} tag. + */ +public class FragmentRule extends BaseViewRule { + @Override + public void onCreate(INode node, INode parent, InsertType insertType) { + // When dropping a fragment tag, ask the user which layout to include. + if (insertType == InsertType.CREATE) { // NOT InsertType.CREATE_PREVIEW + String fqcn = mRulesEngine.displayFragmentSourceInput(); + if (fqcn != null) { + node.editXml("Add Fragment", + new PropertySettingNodeHandler(ANDROID_URI, ATTR_NAME, + fqcn.length() > 0 ? fqcn : null)); + } else { + // Remove the view; the insertion was canceled + parent.removeChild(node); + } + } + } +} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/LayoutConstants.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/LayoutConstants.java index 319a2b4d..825c84e 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/LayoutConstants.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/LayoutConstants.java @@ -32,12 +32,10 @@ public class LayoutConstants { /** The element name in a <code><view class="..."></code> element. */ public static final String VIEW = "view"; //$NON-NLS-1$ - /** The element name in a <code><fragment android:name="..."></code> element. */ - public static final String FRAGMENT = "fragment"; //$NON-NLS-1$ - /** The attribute name in a {@code <view class="...">} element. */ public static final String ATTR_CLASS = "class"; //$NON-NLS-1$ public static final String ATTR_ON_CLICK = "onClick"; //$NON-NLS-1$ + public static final String ATTR_TAG = "tag"; //$NON-NLS-1$ // Some common layout element names public static final String RELATIVE_LAYOUT = "RelativeLayout"; //$NON-NLS-1$ diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/ProjectCallback.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/ProjectCallback.java index 7383659..064094e 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/ProjectCallback.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/ProjectCallback.java @@ -20,6 +20,7 @@ import static com.android.ide.common.layout.LayoutConstants.ANDROID_PKG_PREFIX; import static com.android.ide.common.layout.LayoutConstants.CALENDAR_VIEW; import static com.android.ide.common.layout.LayoutConstants.EXPANDABLE_LIST_VIEW; import static com.android.ide.common.layout.LayoutConstants.LIST_VIEW; +import static com.android.ide.eclipse.adt.internal.editors.layout.descriptors.LayoutDescriptors.VIEW_FRAGMENT; import com.android.ide.common.rendering.LayoutLibrary; import com.android.ide.common.rendering.api.AdapterBinding; @@ -45,6 +46,7 @@ import com.android.util.Pair; import org.eclipse.core.resources.IProject; import java.lang.reflect.Constructor; +import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Set; @@ -141,7 +143,9 @@ public final class ProjectCallback extends LegacyCallback { } catch (Exception e) { // Add the missing class to the list so that the renderer can print them later. // no need to log this. - mMissingClasses.add(className); + if (!className.equals(VIEW_FRAGMENT)) { + mMissingClasses.add(className); + } } try { @@ -175,6 +179,27 @@ public final class ProjectCallback extends LegacyCallback { Method m = view.getClass().getMethod("setText", new Class<?>[] { CharSequence.class }); m.invoke(view, getShortClassName(className)); + + // Call MockView.setGravity(Gravity.CENTER) to get the text centered in + // MockViews. + // TODO: Do this in layoutlib's MockView class instead. + try { + // Look up android.view.Gravity#CENTER - or can we just hard-code + // the value (17) here? + Class<?> gravity = + Class.forName("android.view.Gravity", //$NON-NLS-1$ + true, view.getClass().getClassLoader()); + Field centerField = gravity.getField("CENTER"); //$NON-NLS-1$ + int center = centerField.getInt(null); + m = view.getClass().getMethod("setGravity", + new Class<?>[] { Integer.TYPE }); + // Center + //int center = (0x0001 << 4) | (0x0001 << 0); + m.invoke(view, Integer.valueOf(center)); + } catch (Exception e) { + // Not important to center views + } + return view; } catch (Exception e) { // We failed to create and return a mock view. diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/LayoutDescriptors.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/LayoutDescriptors.java index 172802e..f7019a5 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/LayoutDescriptors.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/LayoutDescriptors.java @@ -16,8 +16,14 @@ package com.android.ide.eclipse.adt.internal.editors.layout.descriptors; +import static com.android.ide.common.layout.LayoutConstants.ANDROID_URI; +import static com.android.ide.common.layout.LayoutConstants.ATTR_CLASS; +import static com.android.ide.common.layout.LayoutConstants.ATTR_NAME; +import static com.android.ide.common.layout.LayoutConstants.ATTR_TAG; + import com.android.ide.common.api.IAttributeInfo.Format; import com.android.ide.common.resources.platform.AttributeInfo; +import com.android.ide.common.resources.platform.DeclareStyleableInfo; import com.android.ide.common.resources.platform.ViewClassInfo; import com.android.ide.common.resources.platform.ViewClassInfo.LayoutParamsInfo; import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor; @@ -26,6 +32,8 @@ import com.android.ide.eclipse.adt.internal.editors.descriptors.DocumentDescript import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor; import com.android.ide.eclipse.adt.internal.editors.descriptors.IDescriptorProvider; import com.android.ide.eclipse.adt.internal.editors.descriptors.SeparatorAttributeDescriptor; +import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.ClassAttributeDescriptor; +import com.android.sdklib.IAndroidTarget; import com.android.sdklib.SdkConstants; import java.util.ArrayList; @@ -56,6 +64,13 @@ public final class LayoutDescriptors implements IDescriptorProvider { public static final String VIEW_MERGE = "merge"; //$NON-NLS-1$ /** + * The XML name of the special {@code <fragment>} layout tag. + * A synthetic element with that name is created as part of the view descriptors list + * returned by {@link #getViewDescriptors()}. + */ + public static final String VIEW_FRAGMENT = "fragment"; //$NON-NLS-1$ + + /** * The XML name of the special {@code <view>} layout tag. This is used to add generic * views with a class attribute to specify the view. * <p> @@ -144,8 +159,11 @@ public final class LayoutDescriptors implements IDescriptorProvider { * * @param views The list of views in the framework. * @param layouts The list of layouts in the framework. + * @param styleMap A map from style names to style information provided by the SDK + * @param target The android target being initialized */ - public synchronized void updateDescriptors(ViewClassInfo[] views, ViewClassInfo[] layouts) { + public synchronized void updateDescriptors(ViewClassInfo[] views, ViewClassInfo[] layouts, + Map<String, DeclareStyleableInfo> styleMap, IAndroidTarget target) { // This map links every ViewClassInfo to the ElementDescriptor we created. // It is filled by convertView() and used later to fix the super-class hierarchy. @@ -172,6 +190,15 @@ public final class LayoutDescriptors implements IDescriptorProvider { } } + // Find View and inherit all its layout attributes + AttributeDescriptor[] viewLayoutAttribs = findViewLayoutAttributes( + SdkConstants.CLASS_FRAMELAYOUT, newLayouts); + + if (target.getVersion().getApiLevel() >= 4) { + ViewElementDescriptor fragmentTag = createFragment(viewLayoutAttribs, styleMap); + newViews.add(fragmentTag); + } + List<ElementDescriptor> newDescriptors = new ArrayList<ElementDescriptor>(); newDescriptors.addAll(newLayouts); newDescriptors.addAll(newViews); @@ -185,7 +212,7 @@ public final class LayoutDescriptors implements IDescriptorProvider { // The <merge> tag can only be a root tag, so it is added at the end. // It gets everything else as children but it is not made a child itself. - ViewElementDescriptor mergeTag = createMerge(newLayouts); + ViewElementDescriptor mergeTag = createMerge(viewLayoutAttribs); mergeTag.setChildren(newDescriptors); // mergeTag makes a copy of the list newDescriptors.add(mergeTag); newLayouts.add(mergeTag); @@ -352,16 +379,11 @@ public final class LayoutDescriptors implements IDescriptorProvider { /** * Creates and returns a new {@code <merge>} descriptor. - * @param knownLayouts A list of all known layout view descriptors, used to find the - * FrameLayout descriptor and extract its layout attributes. + * @param viewLayoutAttribs The layout attributes to use for the new descriptor */ - private ViewElementDescriptor createMerge(List<ViewElementDescriptor> knownLayouts) { + private ViewElementDescriptor createMerge(AttributeDescriptor[] viewLayoutAttribs) { String xml_name = VIEW_MERGE; - // Find View and inherit all its layout attributes - AttributeDescriptor[] viewLayoutAttribs = findViewLayoutAttributes( - SdkConstants.CLASS_FRAMELAYOUT, knownLayouts); - // Create the include descriptor ViewElementDescriptor desc = new ViewElementDescriptor(xml_name, // xml_name xml_name, // ui_name @@ -377,6 +399,82 @@ public final class LayoutDescriptors implements IDescriptorProvider { } /** + * Creates and returns a new {@code <fragment>} descriptor. + * @param viewLayoutAttribs The layout attributes to use for the new descriptor + * @param styleMap The style map provided by the SDK + */ + private ViewElementDescriptor createFragment(AttributeDescriptor[] viewLayoutAttribs, + Map<String, DeclareStyleableInfo> styleMap) { + String xml_name = VIEW_FRAGMENT; + final ViewElementDescriptor descriptor; + + // First try to create the descriptor from metadata in attrs.xml: + DeclareStyleableInfo style = styleMap.get("Fragment"); //$NON-NLS-1$ + String fragmentTooltip = + "A Fragment is a piece of an application's user interface or behavior that " + + "can be placed in an Activity"; + String sdkUrl = "http://developer.android.com/guide/topics/fundamentals/fragments.html"; + ClassAttributeDescriptor classAttribute = new ClassAttributeDescriptor( + // Should accept both CLASS_V4_FRAGMENT and CLASS_FRAGMENT + null /*superClassName*/, + ATTR_CLASS, ATTR_CLASS, null /* namespace */, + "Supply the name of the fragment class to instantiate", + new AttributeInfo(ATTR_CLASS, new Format[] { Format.STRING}), + true /*mandatory*/); + + if (style != null) { + descriptor = new ViewElementDescriptor( + VIEW_FRAGMENT, VIEW_FRAGMENT, VIEW_FRAGMENT, + fragmentTooltip, // tooltip + sdkUrl, //, + null /* attributes */, + viewLayoutAttribs, // layout attributes + null /*childrenElements*/, + false /*mandatory*/); + ArrayList<AttributeDescriptor> descs = new ArrayList<AttributeDescriptor>(); + // The class attribute is not included in the attrs.xml + descs.add(classAttribute); + DescriptorsUtils.appendAttributes(descs, + null, // elementName + SdkConstants.NS_RESOURCES, + style.getAttributes(), + null, // requiredAttributes + null); // overrides + //descriptor.setTooltip(style.getJavaDoc()); + descriptor.setAttributes(descs.toArray(new AttributeDescriptor[descs.size()])); + } else { + // The above will only work on API 11 and up. However, fragments are *also* available + // on older platforms, via the fragment support library, so add in a manual + // entry if necessary. + descriptor = new ViewElementDescriptor(xml_name, // xml_name + xml_name, // ui_name + xml_name, // "class name"; the GLE only treats this as an element tag + fragmentTooltip, + sdkUrl, + new AttributeDescriptor[] { + new ClassAttributeDescriptor( + null /*superClassName*/, + ATTR_NAME, ATTR_NAME, ANDROID_URI, + "Supply the name of the fragment class to instantiate", + new AttributeInfo(ATTR_NAME, new Format[] { Format.STRING}), + true /*mandatory*/), + classAttribute, + new ClassAttributeDescriptor( + null /*superClassName*/, + ATTR_TAG, ATTR_TAG, ANDROID_URI, + "Supply a tag for the top-level view containing a String", + new AttributeInfo(ATTR_TAG, new Format[] { Format.STRING}), + true /*mandatory*/), + }, // attributes + viewLayoutAttribs, // layout attributes + null, // children + false /* mandatory */); + } + + return descriptor; + } + + /** * Finds the descriptor and retrieves all its layout attributes. */ private AttributeDescriptor[] findViewLayoutAttributes( diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/RulesEngine.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/RulesEngine.java index 6838432..2d0dc66 100755 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/RulesEngine.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/RulesEngine.java @@ -18,6 +18,8 @@ package com.android.ide.eclipse.adt.internal.editors.layout.gre; import static com.android.ide.common.layout.LayoutConstants.ANDROID_WIDGET_PREFIX; import static com.android.ide.eclipse.adt.internal.editors.layout.descriptors.LayoutDescriptors.VIEW_MERGE; +import static com.android.sdklib.SdkConstants.CLASS_FRAGMENT; +import static com.android.sdklib.SdkConstants.CLASS_V4_FRAGMENT; import com.android.ide.common.api.DropFeedback; import com.android.ide.common.api.IClientRulesEngine; @@ -41,6 +43,7 @@ import com.android.ide.eclipse.adt.internal.editors.layout.gle2.LayoutCanvas; import com.android.ide.eclipse.adt.internal.editors.layout.gle2.SelectionManager; import com.android.ide.eclipse.adt.internal.editors.layout.gle2.SimpleElement; import com.android.ide.eclipse.adt.internal.editors.layout.uimodel.UiViewElementNode; +import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper; import com.android.ide.eclipse.adt.internal.resources.CyclicDependencyValidator; import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager; import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData; @@ -54,12 +57,32 @@ import com.android.sdklib.IAndroidTarget; import com.android.sdklib.internal.project.ProjectProperties; import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Status; +import org.eclipse.jdt.core.Flags; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.ITypeHierarchy; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.search.IJavaSearchScope; +import org.eclipse.jdt.core.search.SearchEngine; +import org.eclipse.jdt.ui.IJavaElementSearchConstants; +import org.eclipse.jdt.ui.JavaUI; +import org.eclipse.jdt.ui.dialogs.ITypeInfoFilterExtension; +import org.eclipse.jdt.ui.dialogs.ITypeInfoRequestor; +import org.eclipse.jdt.ui.dialogs.TypeSelectionExtension; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.IInputValidator; import org.eclipse.jface.dialogs.InputDialog; import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.window.Window; +import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.dialogs.SelectionDialog; import java.io.File; import java.net.MalformedURLException; @@ -764,7 +787,6 @@ public class RulesEngine { * with a few methods they can use to use functionality from this {@link RulesEngine}. */ private class ClientRulesEngineImpl implements IClientRulesEngine { - private final String mFqcn; public ClientRulesEngineImpl(String fqcn) { @@ -960,5 +982,104 @@ public class RulesEngine { } }); } + + public String displayFragmentSourceInput() { + try { + // Compute a search scope: We need to merge all the subclasses + // android.app.Fragment and android.support.v4.app.Fragment + IJavaSearchScope scope = SearchEngine.createWorkspaceScope(); + IJavaProject javaProject = BaseProjectHelper.getJavaProject(mProject); + if (javaProject != null) { + IType oldFragmentType = javaProject.findType(CLASS_V4_FRAGMENT); + + // First check to make sure fragments are available, and if not, + // warn the user. + IAndroidTarget target = Sdk.getCurrent().getTarget(mProject); + if (target.getVersion().getApiLevel() < 11 && oldFragmentType == null) { + // Compatibility library must be present + Status status = new Status(IStatus.WARNING, AdtPlugin.PLUGIN_ID, 0, + "Fragments require API level 11 or higher, or a compatibility " + + "library for older versions.\n\n" + + "Please install the \"Android Compatibility Package\" from " + + "the SDK manager and add its .jar file " + + "(extras/android/compatibility/v4/android-support-v4.jar) " + + "to the project's " + + " Java Build Path.", null); + ErrorDialog.openError(Display.getCurrent().getActiveShell(), + "Fragment Warning", null, status); + + // TODO: Offer to automatically perform configuration for the user; + // either upgrade project to require API 11, or first install the + // compatibility library via the SDK manager and then adding + // ${SDK_HOME}/extras/android/compatibility/v4/android-support-v4.jar + // to the project jar dependencies. + return null; + } + + // Look up sub-types of each (new fragment class and compatibility fragment + // class, if any) and merge the two arrays - then create a scope from these + // elements. + IType[] fragmentTypes = new IType[0]; + IType[] oldFragmentTypes = new IType[0]; + if (oldFragmentType != null) { + ITypeHierarchy hierarchy = + oldFragmentType.newTypeHierarchy(new NullProgressMonitor()); + oldFragmentTypes = hierarchy.getAllSubtypes(oldFragmentType); + } + IType fragmentType = javaProject.findType(CLASS_FRAGMENT); + if (fragmentType != null) { + ITypeHierarchy hierarchy = + fragmentType.newTypeHierarchy(new NullProgressMonitor()); + fragmentTypes = hierarchy.getAllSubtypes(fragmentType); + } + IType[] subTypes = new IType[fragmentTypes.length + oldFragmentTypes.length]; + System.arraycopy(fragmentTypes, 0, subTypes, 0, fragmentTypes.length); + System.arraycopy(oldFragmentTypes, 0, subTypes, fragmentTypes.length, + oldFragmentTypes.length); + scope = SearchEngine.createJavaSearchScope(subTypes, IJavaSearchScope.SOURCES); + } + + Shell parent = AdtPlugin.getDisplay().getActiveShell(); + SelectionDialog dialog = JavaUI.createTypeDialog( + parent, + new ProgressMonitorDialog(parent), + scope, + IJavaElementSearchConstants.CONSIDER_CLASSES, false, + // Use ? as a default filter to fill dialog with matches + "?", //$NON-NLS-1$ + new TypeSelectionExtension() { + @Override + public ITypeInfoFilterExtension getFilterExtension() { + return new ITypeInfoFilterExtension() { + public boolean select(ITypeInfoRequestor typeInfoRequestor) { + int modifiers = typeInfoRequestor.getModifiers(); + if (!Flags.isPublic(modifiers) + || Flags.isInterface(modifiers) + || Flags.isEnum(modifiers)) { + return false; + } + return true; + } + }; + } + }); + + dialog.setTitle("Choose Fragment Class"); + dialog.setMessage("Select a Fragment class (? = any character, * = any string):"); + if (dialog.open() == IDialogConstants.CANCEL_ID) { + return null; + } + + Object[] types = dialog.getResult(); + if (types != null && types.length > 0) { + return ((IType) types[0]).getFullyQualifiedName(); + } + } catch (JavaModelException e) { + AdtPlugin.log(e, null); + } catch (CoreException e) { + AdtPlugin.log(e, null); + } + return null; + } } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/extra-view-metadata.xml b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/extra-view-metadata.xml index 0870f69..7f11574 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/extra-view-metadata.xml +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/extra-view-metadata.xml @@ -168,6 +168,11 @@ name="Include Other Layout" render="skip" /> <view + class="fragment" + name="Fragment" + fill="opposite" + render="skip" /> + <view class="android.widget.TableLayout" fill="opposite" render="skip" /> diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiElementNode.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiElementNode.java index e2b6ccf..47f22a1 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiElementNode.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiElementNode.java @@ -247,6 +247,8 @@ public class UiElementNode implements IPropertySource { attr = _Element_getAttributeNS(elem, SdkConstants.NS_RESOURCES, AndroidManifestDescriptors.ANDROID_LABEL_ATTR); + } else if (mXmlNode.getNodeName().equals(LayoutDescriptors.VIEW_FRAGMENT)) { + attr = attr.substring(attr.lastIndexOf('.') + 1); } if (attr == null || attr.length() == 0) { attr = _Element_getAttributeNS(elem, diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/Hyperlinks.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/Hyperlinks.java index c30b78a..069d475 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/Hyperlinks.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/Hyperlinks.java @@ -20,7 +20,6 @@ import static com.android.ide.common.layout.LayoutConstants.ANDROID_URI; import static com.android.ide.common.layout.LayoutConstants.ATTR_CLASS; import static com.android.ide.common.layout.LayoutConstants.ATTR_NAME; import static com.android.ide.common.layout.LayoutConstants.ATTR_ON_CLICK; -import static com.android.ide.common.layout.LayoutConstants.FRAGMENT; import static com.android.ide.common.layout.LayoutConstants.NEW_ID_PREFIX; import static com.android.ide.common.layout.LayoutConstants.VIEW; import static com.android.ide.common.resources.ResourceResolver.PREFIX_ANDROID_RESOURCE_REF; @@ -29,6 +28,7 @@ import static com.android.ide.eclipse.adt.AdtConstants.ANDROID_PKG; import static com.android.ide.eclipse.adt.AdtConstants.EXT_XML; import static com.android.ide.eclipse.adt.AdtConstants.FN_RESOURCE_BASE; import static com.android.ide.eclipse.adt.AdtConstants.FN_RESOURCE_CLASS; +import static com.android.ide.eclipse.adt.internal.editors.layout.descriptors.LayoutDescriptors.VIEW_FRAGMENT; import static com.android.ide.eclipse.adt.internal.editors.resources.descriptors.ResourcesDescriptors.NAME_ATTR; import static com.android.ide.eclipse.adt.internal.editors.resources.descriptors.ResourcesDescriptors.ROOT_ELEMENT; import static com.android.ide.eclipse.adt.internal.editors.resources.descriptors.ResourcesDescriptors.STYLE_ELEMENT; @@ -340,8 +340,8 @@ public class Hyperlinks { } String tag = context.getElement().getTagName(); String attributeName = attribute.getLocalName(); - return ATTR_CLASS.equals(attributeName) && (VIEW.equals(tag) || FRAGMENT.equals(tag)) - || ATTR_NAME.equals(attributeName) && FRAGMENT.equals(tag); + return ATTR_CLASS.equals(attributeName) && (VIEW.equals(tag) || VIEW_FRAGMENT.equals(tag)) + || ATTR_NAME.equals(attributeName) && VIEW_FRAGMENT.equals(tag); } /** Returns true if this represents an onClick attribute specifying a method handler */ diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/AndroidTargetParser.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/AndroidTargetParser.java index 19b2e3d..1bdfd4e 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/AndroidTargetParser.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/AndroidTargetParser.java @@ -199,7 +199,8 @@ public final class AndroidTargetParser { } LayoutDescriptors layoutDescriptors = new LayoutDescriptors(); - layoutDescriptors.updateDescriptors(layoutViewsInfo, layoutGroupsInfo); + layoutDescriptors.updateDescriptors(layoutViewsInfo, layoutGroupsInfo, + attrsXmlParser.getDeclareStyleableList(), mAndroidTarget); progress.worked(1); if (progress.isCanceled()) { diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/LayoutTestBase.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/LayoutTestBase.java index 18d985e..a3d0f1b 100644 --- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/LayoutTestBase.java +++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/LayoutTestBase.java @@ -253,6 +253,11 @@ public class LayoutTestBase extends TestCase { public void select(Collection<INode> nodes) { fail("Not supported in tests yet"); } + + public String displayFragmentSourceInput() { + fail("Not supported in tests yet"); + return null; + } } public void testDummy() { |