Add new setTag(int, Object) API to allow applications to specify several tags.
This commit is contained in:
@@ -135944,6 +135944,19 @@
|
|||||||
visibility="public"
|
visibility="public"
|
||||||
>
|
>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="getTag"
|
||||||
|
return="java.lang.Object"
|
||||||
|
abstract="false"
|
||||||
|
native="false"
|
||||||
|
synchronized="false"
|
||||||
|
static="false"
|
||||||
|
final="false"
|
||||||
|
deprecated="not deprecated"
|
||||||
|
visibility="public"
|
||||||
|
>
|
||||||
|
<parameter name="key" type="int">
|
||||||
|
</parameter>
|
||||||
|
</method>
|
||||||
<method name="getTop"
|
<method name="getTop"
|
||||||
return="int"
|
return="int"
|
||||||
abstract="false"
|
abstract="false"
|
||||||
@@ -137843,6 +137856,21 @@
|
|||||||
<parameter name="tag" type="java.lang.Object">
|
<parameter name="tag" type="java.lang.Object">
|
||||||
</parameter>
|
</parameter>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="setTag"
|
||||||
|
return="void"
|
||||||
|
abstract="false"
|
||||||
|
native="false"
|
||||||
|
synchronized="false"
|
||||||
|
static="false"
|
||||||
|
final="false"
|
||||||
|
deprecated="not deprecated"
|
||||||
|
visibility="public"
|
||||||
|
>
|
||||||
|
<parameter name="key" type="int">
|
||||||
|
</parameter>
|
||||||
|
<parameter name="tag" type="java.lang.Object">
|
||||||
|
</parameter>
|
||||||
|
</method>
|
||||||
<method name="setTouchDelegate"
|
<method name="setTouchDelegate"
|
||||||
return="void"
|
return="void"
|
||||||
abstract="false"
|
abstract="false"
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ import com.android.internal.view.menu.MenuBuilder;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
import java.lang.ref.SoftReference;
|
import java.lang.ref.SoftReference;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
@@ -1288,6 +1289,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
|
|||||||
*/
|
*/
|
||||||
static final ThreadLocal<Rect> sThreadLocal = new ThreadLocal<Rect>();
|
static final ThreadLocal<Rect> sThreadLocal = new ThreadLocal<Rect>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map used to store views' tags.
|
||||||
|
*/
|
||||||
|
private static WeakHashMap<View, SparseArray<Object>> sTags;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lock used to access sTags.
|
||||||
|
*/
|
||||||
|
private static final Object sTagsLock = new Object();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The animation currently associated with this view.
|
* The animation currently associated with this view.
|
||||||
* @hide
|
* @hide
|
||||||
@@ -7000,6 +7011,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
|
|||||||
* Returns this view's tag.
|
* Returns this view's tag.
|
||||||
*
|
*
|
||||||
* @return the Object stored in this view as a tag
|
* @return the Object stored in this view as a tag
|
||||||
|
*
|
||||||
|
* @see #setTag(Object)
|
||||||
|
* @see #getTag(int)
|
||||||
*/
|
*/
|
||||||
@ViewDebug.ExportedProperty
|
@ViewDebug.ExportedProperty
|
||||||
public Object getTag() {
|
public Object getTag() {
|
||||||
@@ -7013,11 +7027,101 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
|
|||||||
* resorting to another data structure.
|
* resorting to another data structure.
|
||||||
*
|
*
|
||||||
* @param tag an Object to tag the view with
|
* @param tag an Object to tag the view with
|
||||||
|
*
|
||||||
|
* @see #getTag()
|
||||||
|
* @see #setTag(int, Object)
|
||||||
*/
|
*/
|
||||||
public void setTag(final Object tag) {
|
public void setTag(final Object tag) {
|
||||||
mTag = tag;
|
mTag = tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the tag associated with this view and the specified key.
|
||||||
|
*
|
||||||
|
* @param key The key identifying the tag
|
||||||
|
*
|
||||||
|
* @return the Object stored in this view as a tag
|
||||||
|
*
|
||||||
|
* @see #setTag(int, Object)
|
||||||
|
* @see #getTag()
|
||||||
|
*/
|
||||||
|
public Object getTag(int key) {
|
||||||
|
SparseArray<Object> tags = null;
|
||||||
|
synchronized (sTagsLock) {
|
||||||
|
if (sTags != null) {
|
||||||
|
tags = sTags.get(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tags != null) return tags.get(key);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a tag associated with this view and a key. A tag can be used
|
||||||
|
* to mark a view in its hierarchy and does not have to be unique within
|
||||||
|
* the hierarchy. Tags can also be used to store data within a view
|
||||||
|
* without resorting to another data structure.
|
||||||
|
*
|
||||||
|
* The specified key should be an id declared in the resources of the
|
||||||
|
* application to ensure it is unique. Keys identified as belonging to
|
||||||
|
* the Android framework or not associated with any package will cause
|
||||||
|
* an {@link IllegalArgumentException} to be thrown.
|
||||||
|
*
|
||||||
|
* @param key The key identifying the tag
|
||||||
|
* @param tag An Object to tag the view with
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException If they specified key is not valid
|
||||||
|
*
|
||||||
|
* @see #setTag(Object)
|
||||||
|
* @see #getTag(int)
|
||||||
|
*/
|
||||||
|
public void setTag(int key, final Object tag) {
|
||||||
|
// If the package id is 0x00 or 0x01, it's either an undefined package
|
||||||
|
// or a framework id
|
||||||
|
if ((key >>> 24) < 2) {
|
||||||
|
throw new IllegalArgumentException("The key must be an application-specific "
|
||||||
|
+ "resource id.");
|
||||||
|
}
|
||||||
|
|
||||||
|
setTagInternal(this, key, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variation of {@link #setTag(int, Object)} that enforces the key to be a
|
||||||
|
* framework id.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public void setTagInternal(int key, Object tag) {
|
||||||
|
if ((key >>> 24) != 0x1) {
|
||||||
|
throw new IllegalArgumentException("The key must be a framework-specific "
|
||||||
|
+ "resource id.");
|
||||||
|
}
|
||||||
|
|
||||||
|
setTagInternal(this, key, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setTagInternal(View view, int key, Object tag) {
|
||||||
|
SparseArray<Object> tags = null;
|
||||||
|
synchronized (sTagsLock) {
|
||||||
|
if (sTags == null) {
|
||||||
|
sTags = new WeakHashMap<View, SparseArray<Object>>();
|
||||||
|
} else {
|
||||||
|
tags = sTags.get(view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tags == null) {
|
||||||
|
tags = new SparseArray<Object>(2);
|
||||||
|
synchronized (sTagsLock) {
|
||||||
|
sTags.put(view, tags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tags.put(key, tag);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prints information about this view in the log output, with the tag
|
* Prints information about this view in the log output, with the tag
|
||||||
* {@link #VIEW_LOG_TAG}.
|
* {@link #VIEW_LOG_TAG}.
|
||||||
|
|||||||
@@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2007 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 com.android.frameworktest.view;
|
||||||
|
|
||||||
|
import com.android.frameworktest.R;
|
||||||
|
import android.test.suitebuilder.annotation.MediumTest;
|
||||||
|
|
||||||
|
import android.test.ActivityInstrumentationTestCase2;
|
||||||
|
import android.widget.Button;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exercises {@link android.view.View}'s tags property.
|
||||||
|
*/
|
||||||
|
public class SetTagsTest extends ActivityInstrumentationTestCase2<Disabled> {
|
||||||
|
private Button mView;
|
||||||
|
|
||||||
|
public SetTagsTest() {
|
||||||
|
super("com.android.frameworktest", Disabled.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
|
||||||
|
mView = (Button) getActivity().findViewById(R.id.disabledButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
@MediumTest
|
||||||
|
public void testSetUpConditions() throws Exception {
|
||||||
|
assertNotNull(mView);
|
||||||
|
}
|
||||||
|
|
||||||
|
@MediumTest
|
||||||
|
public void testSetTag() throws Exception {
|
||||||
|
mView.setTag("1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@MediumTest
|
||||||
|
public void testGetTag() throws Exception {
|
||||||
|
Object o = new Object();
|
||||||
|
mView.setTag(o);
|
||||||
|
|
||||||
|
final Object stored = mView.getTag();
|
||||||
|
assertNotNull(stored);
|
||||||
|
assertSame("The stored tag is inccorect", o, stored);
|
||||||
|
}
|
||||||
|
|
||||||
|
@MediumTest
|
||||||
|
public void testSetTagWithKey() throws Exception {
|
||||||
|
mView.setTag(R.id.a, "2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@MediumTest
|
||||||
|
public void testGetTagWithKey() throws Exception {
|
||||||
|
Object o = new Object();
|
||||||
|
mView.setTag(R.id.a, o);
|
||||||
|
|
||||||
|
final Object stored = mView.getTag(R.id.a);
|
||||||
|
assertNotNull(stored);
|
||||||
|
assertSame("The stored tag is inccorect", o, stored);
|
||||||
|
}
|
||||||
|
|
||||||
|
@MediumTest
|
||||||
|
public void testSetTagWithFrameworkId() throws Exception {
|
||||||
|
boolean result = false;
|
||||||
|
try {
|
||||||
|
mView.setTag(android.R.id.list, "2");
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
assertTrue("Setting a tag with a framework id did not throw an exception", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@MediumTest
|
||||||
|
public void testSetTagWithNoPackageId() throws Exception {
|
||||||
|
boolean result = false;
|
||||||
|
try {
|
||||||
|
mView.setTag(0x000000AA, "2");
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
assertTrue("Setting a tag with an id with no package did not throw an exception", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@MediumTest
|
||||||
|
public void testSetTagInternalWithFrameworkId() throws Exception {
|
||||||
|
mView.setTagInternal(android.R.id.list, "2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@MediumTest
|
||||||
|
public void testSetTagInternalWithApplicationId() throws Exception {
|
||||||
|
boolean result = false;
|
||||||
|
try {
|
||||||
|
mView.setTagInternal(R.id.a, "2");
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
assertTrue("Setting a tag with an id with app package did not throw an exception", result);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user