Skip to content

Commit 989709a

Browse files
author
Philip Milne
committed
Simple MVC based binding mechanism for android controls.
Change-Id: I80fe18e0e15f8a840d558de9863650505bd5fb00
1 parent 749e452 commit 989709a

File tree

7 files changed

+365
-7
lines changed

7 files changed

+365
-7
lines changed

api/current.txt

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22826,6 +22826,17 @@ package android.util {
2282622826
method public void set(T, V);
2282722827
}
2282822828

22829+
public class PropertyValueModel extends android.util.ValueModel {
22830+
method public T get();
22831+
method public H getHost();
22832+
method public android.util.Property<H, T> getProperty();
22833+
method public java.lang.Class<T> getType();
22834+
method public static android.util.PropertyValueModel<H, T> of(H, android.util.Property<H, T>);
22835+
method public static android.util.PropertyValueModel<H, T> of(H, java.lang.Class<T>, java.lang.String);
22836+
method public static android.util.PropertyValueModel of(java.lang.Object, java.lang.String);
22837+
method public void set(T);
22838+
}
22839+
2282922840
public class SparseArray implements java.lang.Cloneable {
2283022841
ctor public SparseArray();
2283122842
ctor public SparseArray(int);
@@ -22974,6 +22985,14 @@ package android.util {
2297422985
field public int type;
2297522986
}
2297622987

22988+
public abstract class ValueModel {
22989+
ctor protected ValueModel();
22990+
method public abstract T get();
22991+
method public abstract java.lang.Class<T> getType();
22992+
method public abstract void set(T);
22993+
field public static final android.util.ValueModel EMPTY;
22994+
}
22995+
2297722996
public class Xml {
2297822997
method public static android.util.AttributeSet asAttributeSet(org.xmlpull.v1.XmlPullParser);
2297922998
method public static android.util.Xml.Encoding findEncodingByName(java.lang.String) throws java.io.UnsupportedEncodingException;
@@ -27393,10 +27412,12 @@ package android.widget {
2739327412
method public abstract void onSelectedDayChange(android.widget.CalendarView, int, int, int);
2739427413
}
2739527414

27396-
public class CheckBox extends android.widget.CompoundButton {
27415+
public class CheckBox extends android.widget.CompoundButton implements android.widget.ValueEditor {
2739727416
ctor public CheckBox(android.content.Context);
2739827417
ctor public CheckBox(android.content.Context, android.util.AttributeSet);
2739927418
ctor public CheckBox(android.content.Context, android.util.AttributeSet, int);
27419+
method public android.util.ValueModel<java.lang.Boolean> getValueModel();
27420+
method public void setValueModel(android.util.ValueModel<java.lang.Boolean>);
2740027421
}
2740127422

2740227423
public abstract interface Checkable {
@@ -27569,14 +27590,16 @@ package android.widget {
2756927590
method public void setSize(int, int);
2757027591
}
2757127592

27572-
public class EditText extends android.widget.TextView {
27593+
public class EditText extends android.widget.TextView implements android.widget.ValueEditor {
2757327594
ctor public EditText(android.content.Context);
2757427595
ctor public EditText(android.content.Context, android.util.AttributeSet);
2757527596
ctor public EditText(android.content.Context, android.util.AttributeSet, int);
2757627597
method public void extendSelection(int);
27598+
method public android.util.ValueModel<java.lang.CharSequence> getValueModel();
2757727599
method public void selectAll();
2757827600
method public void setSelection(int, int);
2757927601
method public void setSelection(int);
27602+
method public void setValueModel(android.util.ValueModel<java.lang.CharSequence>);
2758027603
}
2758127604

2758227605
public abstract interface ExpandableListAdapter {
@@ -28593,11 +28616,13 @@ package android.widget {
2859328616
method public abstract java.lang.Object[] getSections();
2859428617
}
2859528618

28596-
public class SeekBar extends android.widget.AbsSeekBar {
28619+
public class SeekBar extends android.widget.AbsSeekBar implements android.widget.ValueEditor {
2859728620
ctor public SeekBar(android.content.Context);
2859828621
ctor public SeekBar(android.content.Context, android.util.AttributeSet);
2859928622
ctor public SeekBar(android.content.Context, android.util.AttributeSet, int);
28623+
method public android.util.ValueModel<java.lang.Integer> getValueModel();
2860028624
method public void setOnSeekBarChangeListener(android.widget.SeekBar.OnSeekBarChangeListener);
28625+
method public void setValueModel(android.util.ValueModel<java.lang.Integer>);
2860128626
}
2860228627

2860328628
public static abstract interface SeekBar.OnSeekBarChangeListener {
@@ -29169,6 +29194,11 @@ package android.widget {
2916929194
method public android.widget.TextView getText2();
2917029195
}
2917129196

29197+
public abstract interface ValueEditor {
29198+
method public abstract android.util.ValueModel<T> getValueModel();
29199+
method public abstract void setValueModel(android.util.ValueModel<T>);
29200+
}
29201+
2917229202
public class VideoView extends android.view.SurfaceView implements android.widget.MediaController.MediaPlayerControl {
2917329203
ctor public VideoView(android.content.Context);
2917429204
ctor public VideoView(android.content.Context, android.util.AttributeSet);
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/*
2+
* Copyright (C) 2012 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+
17+
package android.util;
18+
19+
/**
20+
* A value model for a {@link Property property} of a host object. This class can be used for
21+
* both reflective and non-reflective property implementations.
22+
*
23+
* @param <H> the host type, where the host is the object that holds this property
24+
* @param <T> the value type
25+
*
26+
* @see Property
27+
* @see ValueModel
28+
*/
29+
public class PropertyValueModel<H, T> extends ValueModel<T> {
30+
private final H mHost;
31+
private final Property<H, T> mProperty;
32+
33+
private PropertyValueModel(H host, Property<H, T> property) {
34+
mProperty = property;
35+
mHost = host;
36+
}
37+
38+
/**
39+
* Returns the host.
40+
*
41+
* @return the host
42+
*/
43+
public H getHost() {
44+
return mHost;
45+
}
46+
47+
/**
48+
* Returns the property.
49+
*
50+
* @return the property
51+
*/
52+
public Property<H, T> getProperty() {
53+
return mProperty;
54+
}
55+
56+
@Override
57+
public Class<T> getType() {
58+
return mProperty.getType();
59+
}
60+
61+
@Override
62+
public T get() {
63+
return mProperty.get(mHost);
64+
}
65+
66+
@Override
67+
public void set(T value) {
68+
mProperty.set(mHost, value);
69+
}
70+
71+
/**
72+
* Return an appropriate PropertyValueModel for this host and property.
73+
*
74+
* @param host the host
75+
* @param property the property
76+
* @return the value model
77+
*/
78+
public static <H, T> PropertyValueModel<H, T> of(H host, Property<H, T> property) {
79+
return new PropertyValueModel<H, T>(host, property);
80+
}
81+
82+
/**
83+
* Return a PropertyValueModel for this {@code host} and a
84+
* reflective property, constructed from this {@code propertyType} and {@code propertyName}.
85+
*
86+
* @param host
87+
* @param propertyType the property type
88+
* @param propertyName the property name
89+
* @return a value model with this host and a reflective property with this type and name
90+
*
91+
* @see Property#of
92+
*/
93+
public static <H, T> PropertyValueModel<H, T> of(H host, Class<T> propertyType,
94+
String propertyName) {
95+
return of(host, Property.of((Class<H>) host.getClass(), propertyType, propertyName));
96+
}
97+
98+
private static Class getNullaryMethodReturnType(Class c, String name) {
99+
try {
100+
return c.getMethod(name).getReturnType();
101+
} catch (NoSuchMethodException e) {
102+
return null;
103+
}
104+
}
105+
106+
private static Class getFieldType(Class c, String name) {
107+
try {
108+
return c.getField(name).getType();
109+
} catch (NoSuchFieldException e) {
110+
return null;
111+
}
112+
}
113+
114+
private static String capitalize(String name) {
115+
if (name.isEmpty()) {
116+
return name;
117+
}
118+
return Character.toUpperCase(name.charAt(0)) + name.substring(1);
119+
}
120+
121+
/**
122+
* Return a PropertyValueModel for this {@code host} and and {@code propertyName}.
123+
*
124+
* @param host the host
125+
* @param propertyName the property name
126+
* @return a value model with this host and a reflective property with this name
127+
*/
128+
public static PropertyValueModel of(Object host, String propertyName) {
129+
Class clazz = host.getClass();
130+
String suffix = capitalize(propertyName);
131+
Class propertyType = getNullaryMethodReturnType(clazz, "get" + suffix);
132+
if (propertyType == null) {
133+
propertyType = getNullaryMethodReturnType(clazz, "is" + suffix);
134+
}
135+
if (propertyType == null) {
136+
propertyType = getFieldType(clazz, propertyName);
137+
}
138+
if (propertyType == null) {
139+
throw new NoSuchPropertyException(propertyName);
140+
}
141+
return of(host, propertyType, propertyName);
142+
}
143+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Copyright (C) 2012 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+
17+
package android.util;
18+
19+
/**
20+
* A ValueModel is an abstraction for a 'slot' or place in memory in which a value
21+
* may be stored and retrieved. A common implementation of ValueModel is a regular property of
22+
* an object, whose value may be retrieved by calling the appropriate <em>getter</em>
23+
* method and set by calling the corresponding <em>setter</em> method.
24+
*
25+
* @param <T> the value type
26+
*
27+
* @see PropertyValueModel
28+
*/
29+
public abstract class ValueModel<T> {
30+
/**
31+
* The empty model should be used in place of {@code null} to indicate that a
32+
* model has not been set. The empty model has no value and does nothing when it is set.
33+
*/
34+
public static final ValueModel EMPTY = new ValueModel() {
35+
@Override
36+
public Class getType() {
37+
return Object.class;
38+
}
39+
40+
@Override
41+
public Object get() {
42+
return null;
43+
}
44+
45+
@Override
46+
public void set(Object value) {
47+
48+
}
49+
};
50+
51+
protected ValueModel() {
52+
}
53+
54+
/**
55+
* Returns the type of this property.
56+
*
57+
* @return the property type
58+
*/
59+
public abstract Class<T> getType();
60+
61+
/**
62+
* Returns the value of this property.
63+
*
64+
* @return the property value
65+
*/
66+
public abstract T get();
67+
68+
/**
69+
* Sets the value of this property.
70+
*
71+
* @param value the new value for this property
72+
*/
73+
public abstract void set(T value);
74+
}

core/java/android/widget/CheckBox.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import android.util.AttributeSet;
2121
import android.view.accessibility.AccessibilityEvent;
2222
import android.view.accessibility.AccessibilityNodeInfo;
23+
import android.util.ValueModel;
2324

2425

2526
/**
@@ -55,7 +56,9 @@
5556
* {@link android.R.styleable#View View Attributes}
5657
* </p>
5758
*/
58-
public class CheckBox extends CompoundButton {
59+
public class CheckBox extends CompoundButton implements ValueEditor<Boolean> {
60+
private ValueModel<Boolean> mValueModel = ValueModel.EMPTY;
61+
5962
public CheckBox(Context context) {
6063
this(context, null);
6164
}
@@ -79,4 +82,22 @@ public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
7982
super.onInitializeAccessibilityNodeInfo(info);
8083
info.setClassName(CheckBox.class.getName());
8184
}
85+
86+
@Override
87+
public ValueModel<Boolean> getValueModel() {
88+
return mValueModel;
89+
}
90+
91+
@Override
92+
public void setValueModel(ValueModel<Boolean> valueModel) {
93+
mValueModel = valueModel;
94+
setChecked(mValueModel.get());
95+
}
96+
97+
@Override
98+
public boolean performClick() {
99+
boolean handled = super.performClick();
100+
mValueModel.set(isChecked());
101+
return handled;
102+
}
82103
}

0 commit comments

Comments
 (0)