diff options
author | Tor Norbye <tnorbye@google.com> | 2012-11-30 12:26:31 -0800 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2012-11-30 12:26:31 -0800 |
commit | 6c7924f6fea737bf5c87c1a6b845d690b8c46099 (patch) | |
tree | e384df11488d2015fbc35703f0b683638a957d5d /lint | |
parent | ec25355d4688c6f93d38f4fa4f20d945af239b9e (diff) | |
parent | 4c2c7f656cc57c1f12d0efa1a753ab372b6b69de (diff) | |
download | sdk-6c7924f6fea737bf5c87c1a6b845d690b8c46099.zip sdk-6c7924f6fea737bf5c87c1a6b845d690b8c46099.tar.gz sdk-6c7924f6fea737bf5c87c1a6b845d690b8c46099.tar.bz2 |
Merge "Make inefficient weight detector identify more candidates"
Diffstat (limited to 'lint')
5 files changed, 110 insertions, 5 deletions
diff --git a/lint/libs/lint_api/src/com/android/tools/lint/client/api/DefaultSdkInfo.java b/lint/libs/lint_api/src/com/android/tools/lint/client/api/DefaultSdkInfo.java index b5a1628..2f54659 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/client/api/DefaultSdkInfo.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/client/api/DefaultSdkInfo.java @@ -65,9 +65,12 @@ import static com.android.SdkConstants.WIDGET_PKG_PREFIX; import com.android.annotations.NonNull; import com.android.annotations.Nullable; import com.google.common.annotations.Beta; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; import java.util.HashMap; import java.util.Map; +import java.util.Set; /** * Default simple implementation of an {@link SdkInfo} @@ -155,10 +158,23 @@ class DefaultSdkInfo extends SdkInfo { return type; } + @Override + public boolean isLayout(@NonNull String tag) { + // TODO: Read in widgets.txt from the platform install area to look up this information + // dynamically instead! + + if (super.isLayout(tag)) { + return true; + } + + return LAYOUTS.contains(tag); + } + private static final int CLASS_COUNT = 59; + private static final int LAYOUT_COUNT = 20; - @NonNull - private static final Map<String, String> PARENTS = new HashMap<String, String>(CLASS_COUNT); + private static final Map<String,String> PARENTS = Maps.newHashMapWithExpectedSize(CLASS_COUNT); + private static final Set<String> LAYOUTS = Sets.newHashSetWithExpectedSize(CLASS_COUNT); static { PARENTS.put(COMPOUND_BUTTON, BUTTON); @@ -203,8 +219,8 @@ class DefaultSdkInfo extends SdkInfo { PARENTS.put(WEB_VIEW, ABSOLUTE_LAYOUT); PARENTS.put(AUTO_COMPLETE_TEXT_VIEW, EDIT_TEXT); PARENTS.put(MULTI_AUTO_COMPLETE_TEXT_VIEW, AUTO_COMPLETE_TEXT_VIEW); + PARENTS.put(CHECKED_TEXT_VIEW, TEXT_VIEW); - PARENTS.put("CheckedTextView", TEXT_VIEW); //$NON-NLS-1$ PARENTS.put("MediaController", FRAME_LAYOUT); //$NON-NLS-1$ PARENTS.put("SlidingDrawer", VIEW_GROUP); //$NON-NLS-1$ PARENTS.put("DialerFilter", RELATIVE_LAYOUT); //$NON-NLS-1$ @@ -237,6 +253,28 @@ class DefaultSdkInfo extends SdkInfo { } } */ + + LAYOUTS.add(TAB_HOST); + LAYOUTS.add(HORIZONTAL_SCROLL_VIEW); + LAYOUTS.add(VIEW_SWITCHER); + LAYOUTS.add(TAB_WIDGET); + LAYOUTS.add(VIEW_ANIMATOR); + LAYOUTS.add(SCROLL_VIEW); + LAYOUTS.add(GRID_VIEW); + LAYOUTS.add(TABLE_ROW); + LAYOUTS.add(RADIO_GROUP); + LAYOUTS.add(LIST_VIEW); + LAYOUTS.add(EXPANDABLE_LIST_VIEW); + LAYOUTS.add("MediaController"); //$NON-NLS-1$ + LAYOUTS.add("DialerFilter"); //$NON-NLS-1$ + LAYOUTS.add("ViewFlipper"); //$NON-NLS-1$ + LAYOUTS.add("SlidingDrawer"); //$NON-NLS-1$ + LAYOUTS.add("StackView"); //$NON-NLS-1$ + LAYOUTS.add("SearchView"); //$NON-NLS-1$ + LAYOUTS.add("TextSwitcher"); //$NON-NLS-1$ + LAYOUTS.add("AdapterViewFlipper"); //$NON-NLS-1$ + LAYOUTS.add("ImageSwitcher"); //$NON-NLS-1$ + assert LAYOUTS.size() <= LAYOUT_COUNT : LAYOUTS.size(); } // Currently using a map; this should really be a list, but using a map until we actually diff --git a/lint/libs/lint_api/src/com/android/tools/lint/client/api/SdkInfo.java b/lint/libs/lint_api/src/com/android/tools/lint/client/api/SdkInfo.java index 5ff7f90..8b3d1e9 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/client/api/SdkInfo.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/client/api/SdkInfo.java @@ -76,5 +76,15 @@ public abstract class SdkInfo { @Nullable public abstract String getParentViewName(@NonNull String name); + /** + * Returns true if the given widget name is a layout + * + * @param tag the XML tag for the view + * @return true if the given tag corresponds to a layout + */ + public boolean isLayout(@NonNull String tag) { + return tag.endsWith("Layout"); //$NON-NLS-1$ + } + // TODO: Add access to resource resolution here. } diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/InefficientWeightDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/InefficientWeightDetector.java index 9c92c4b..39009c6 100644 --- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/InefficientWeightDetector.java +++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/InefficientWeightDetector.java @@ -23,11 +23,15 @@ import static com.android.SdkConstants.ATTR_LAYOUT_WEIGHT; import static com.android.SdkConstants.ATTR_LAYOUT_WIDTH; import static com.android.SdkConstants.ATTR_ORIENTATION; import static com.android.SdkConstants.LINEAR_LAYOUT; +import static com.android.SdkConstants.RADIO_GROUP; import static com.android.SdkConstants.VALUE_VERTICAL; import static com.android.SdkConstants.VIEW; +import static com.android.SdkConstants.VIEW_FRAGMENT; +import static com.android.SdkConstants.VIEW_INCLUDE; import static com.android.SdkConstants.VIEW_TAG; import com.android.annotations.NonNull; +import com.android.tools.lint.client.api.SdkInfo; import com.android.tools.lint.detector.api.Category; import com.android.tools.lint.detector.api.Issue; import com.android.tools.lint.detector.api.LayoutDetector; @@ -170,9 +174,16 @@ public class InefficientWeightDetector extends LayoutDetector { && !element.hasAttributeNS(ANDROID_URI, ATTR_BASELINE_ALIGNED)) { // See if all the children are layouts boolean allChildrenAreLayouts = children.size() > 0; + SdkInfo sdkInfo = context.getClient().getSdkInfo(context.getProject()); for (Element child : children) { - // TODO: Make better check - if (!child.getTagName().endsWith("Layout")) { //$NON-NLS-1$ + String tagName = child.getTagName(); + if (!(sdkInfo.isLayout(tagName) + // RadioGroup is a layout, but one which possibly should be base aligned + && !tagName.equals(RADIO_GROUP) + // Consider <fragment> tags as layouts for the purposes of this check + || VIEW_FRAGMENT.equals(tagName) + // Ditto for <include> tags + || VIEW_INCLUDE.equals(tagName))) { allChildrenAreLayouts = false; } } diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/InefficientWeightDetectorTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/InefficientWeightDetectorTest.java index ad0da87..644bb10 100644 --- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/InefficientWeightDetectorTest.java +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/InefficientWeightDetectorTest.java @@ -58,6 +58,15 @@ public class InefficientWeightDetectorTest extends AbstractCheckTest { lintFiles("res/layout/baseline_weights.xml")); } + public void testWeights4() throws Exception { + assertEquals( + "res/layout/activity_item_two_pane.xml:1: Warning: Set android:baselineAligned=\"false\" on this element for better performance [DisableBaselineAlignment]\n" + + "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" + + "^\n" + + "0 errors, 1 warnings\n", + lintFiles("res/layout/activity_item_two_pane.xml")); + } + public void testNoVerticalWeights3() throws Exception { // Orientation=vertical assertEquals( diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/activity_item_two_pane.xml b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/activity_item_two_pane.xml new file mode 100644 index 0000000..b19047a --- /dev/null +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/activity_item_two_pane.xml @@ -0,0 +1,37 @@ +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_marginLeft="16dp" + android:layout_marginRight="16dp" + android:divider="?android:attr/dividerHorizontal" + android:orientation="horizontal" + android:showDividers="middle" + tools:context=".ItemListActivity" > + + <!-- + This layout is a two-pane layout for the Items + master/detail flow. See res/values-large/refs.xml and + res/values-sw600dp/refs.xml for an example of layout aliases + that replace the single-pane version of the layout with + this two-pane version. + + For more on layout aliases, see: + http://developer.android.com/training/multiscreen/screensizes.html#TaskUseAliasFilters + --> + + <fragment + android:id="@+id/item_list" + android:name="com.example.master.ItemListFragment" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" + tools:layout="@android:layout/list_content" /> + + <FrameLayout + android:id="@+id/item_detail_container" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="3" /> + +</LinearLayout> |