ShadowView.java revision d723e05df54299b88daa5b626c460d733d9bcf6d
133873d2b41a5cd2597b20a4e88eb8942944c0f23Tyler Schultzpackage com.xtremelabs.robolectric.shadows;
26eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz
36eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulzimport android.content.Context;
46eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulzimport android.content.res.Resources;
5ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williamsimport android.graphics.Bitmap;
6a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultzimport android.graphics.Point;
7a075f94a84c6dd3493700d0c752fc545642e44d5Mike Grafton & Tyler Schultzimport android.graphics.drawable.ColorDrawable;
8a075f94a84c6dd3493700d0c752fc545642e44d5Mike Grafton & Tyler Schultzimport android.graphics.drawable.Drawable;
9684ccc2fc5a1c79aa45af22b95c37f7c509a00c1Christian Williamsimport android.util.AttributeSet;
10924f851cb0ec279b6974744ce623f25bdc657551Ryan Richardimport android.view.MotionEvent;
116eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulzimport android.view.View;
12d4f5daf12f1d112cf06b8b8914437ed6c0b3a677Ryan Richard & Tyler Schultzimport android.view.ViewGroup;
135411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williamsimport android.view.ViewParent;
143f78da998ce73c1c7c25798a7e7e4f19287eff23Michael Portuesiimport android.view.animation.Animation;
15ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williamsimport com.xtremelabs.robolectric.Robolectric;
1622c22c9aa4ca68c2deac6164edc1d82bc9645310Christian Williams & Phil Goodwinimport com.xtremelabs.robolectric.internal.Implementation;
1722c22c9aa4ca68c2deac6164edc1d82bc9645310Christian Williams & Phil Goodwinimport com.xtremelabs.robolectric.internal.Implements;
1822c22c9aa4ca68c2deac6164edc1d82bc9645310Christian Williams & Phil Goodwinimport com.xtremelabs.robolectric.internal.RealObject;
196eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz
2086e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williamsimport java.io.PrintStream;
216c887826366610c9e44c21a9fec6020219226283Gautier Hayounimport java.lang.reflect.InvocationTargetException;
226c887826366610c9e44c21a9fec6020219226283Gautier Hayounimport java.lang.reflect.Method;
2351fe0b279e9f5568683d9ef67921f922a51c05d5Christian Williams & Tyler Schultzimport java.util.HashMap;
2451fe0b279e9f5568683d9ef67921f922a51c05d5Christian Williams & Tyler Schultzimport java.util.Map;
25c6f46aeb970c9111e2e79b806451f63b4853950bIan Fisher & Tyler Schultz
2686e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williamsimport static com.xtremelabs.robolectric.Robolectric.shadowOf;
2786e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams
28ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin/**
296c887826366610c9e44c21a9fec6020219226283Gautier Hayoun * Shadow implementation of {@code View} that simulates the behavior of this
306c887826366610c9e44c21a9fec6020219226283Gautier Hayoun * class.
31d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz * <p/>
326c887826366610c9e44c21a9fec6020219226283Gautier Hayoun * Supports listeners, focusability (but not focus order), resource loading,
336c887826366610c9e44c21a9fec6020219226283Gautier Hayoun * visibility, onclick, tags, and tracks the size and shape of the view.
34ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin */
35198b49fe81283e340891361045a8bdeb01f35e04Tyler Schultz@SuppressWarnings({"UnusedDeclaration"})
360b378afcde0200166e546c46a7642015accfce49Christian Williams & Ian Fisher@Implements(View.class)
37afe0a89d904a7fe2f5980b9deb26cc3240192459Christian Williamspublic class ShadowView {
38d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz    @RealObject
39d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz    protected View realView;
406eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz
416eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    private int id;
42afe0a89d904a7fe2f5980b9deb26cc3240192459Christian Williams    ShadowView parent;
4370e43520d16dba344ad0f2f96e5d9300880153ffPhil Goodwin & Tyler Schultz    protected Context context;
444d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    private boolean selected;
45810ca4e6f0dc6d69504b3e03ef61155f10083fbeChristian Williams & Joe Moore    private View.OnClickListener onClickListener;
46d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz    private View.OnLongClickListener onLongClickListener;
47c6f46aeb970c9111e2e79b806451f63b4853950bIan Fisher & Tyler Schultz    private Object tag;
48775ccf7ae53d9b4c77d3adf2514f26747cebd89cIan Fisher & Ryan Richard    private boolean enabled = true;
494d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    private int visibility = View.VISIBLE;
504d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    int left;
514d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    int top;
524d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    int right;
534d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    int bottom;
544d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    private int paddingLeft;
554d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    private int paddingTop;
564d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    private int paddingRight;
574d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    private int paddingBottom;
584d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    private ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(0, 0);
5944ade170c5bc611222ed25d5b1f8e7745104057dChristian Williams    private Map<Integer, Object> tags = new HashMap<Integer, Object>();
604d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    private boolean clickable;
61254044cea0df7e6aef3ce33c98a5003a6eba0512Christian Williams & Phil Goodwin    protected boolean focusable;
629729911f8638b6bb4d55b3d67e6d68a6b3f19dc7Phil Goodwin    boolean focusableInTouchMode;
634d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    private int backgroundResourceId = -1;
641f4067d01d9e2907f2d926b17d378cb40a379dcaRich Humphrey    private int backgroundColor;
655411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams    protected View.OnKeyListener onKeyListener;
664d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    private boolean isFocused;
675411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams    private View.OnFocusChangeListener onFocusChangeListener;
684d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    private boolean wasInvalidated;
69924f851cb0ec279b6974744ce623f25bdc657551Ryan Richard    private View.OnTouchListener onTouchListener;
70a2dd5bb88b4bfe0cbe77cfc3581ce42745509760Phil Goodwin & Tyler Schultz    protected AttributeSet attributeSet;
71ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williams    private boolean drawingCacheEnabled;
72a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz    public Point scrollToCoordinates;
734241c0d59435626c1858d15e5e3612674a666ec0Lowell Kirsh & Ryan Richard    private boolean didRequestLayout;
74a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz    private Drawable background;
753f78da998ce73c1c7c25798a7e7e4f19287eff23Michael Portuesi    private Animation animation;
766eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz
776eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    public void __constructor__(Context context) {
783c5249864cabd318d8b3f551f2f4ab7af7434f8bChristian Williams        __constructor__(context, null);
796eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    }
806eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz
815189dc7b67bf8426200b68a998442ba821a27222Phil Goodwin & Tyler Schultz    public void __constructor__(Context context, AttributeSet attributeSet) {
823c5249864cabd318d8b3f551f2f4ab7af7434f8bChristian Williams        __constructor__(context, attributeSet, 0);
833c5249864cabd318d8b3f551f2f4ab7af7434f8bChristian Williams    }
843c5249864cabd318d8b3f551f2f4ab7af7434f8bChristian Williams
853c5249864cabd318d8b3f551f2f4ab7af7434f8bChristian Williams    public void __constructor__(Context context, AttributeSet attributeSet, int defStyle) {
863c5249864cabd318d8b3f551f2f4ab7af7434f8bChristian Williams        this.context = context;
875189dc7b67bf8426200b68a998442ba821a27222Phil Goodwin & Tyler Schultz        this.attributeSet = attributeSet;
883c5249864cabd318d8b3f551f2f4ab7af7434f8bChristian Williams
893c5249864cabd318d8b3f551f2f4ab7af7434f8bChristian Williams        if (attributeSet != null) {
903c5249864cabd318d8b3f551f2f4ab7af7434f8bChristian Williams            applyAttributes();
913c5249864cabd318d8b3f551f2f4ab7af7434f8bChristian Williams        }
923c5249864cabd318d8b3f551f2f4ab7af7434f8bChristian Williams    }
933c5249864cabd318d8b3f551f2f4ab7af7434f8bChristian Williams
943c5249864cabd318d8b3f551f2f4ab7af7434f8bChristian Williams    public void applyAttributes() {
955189dc7b67bf8426200b68a998442ba821a27222Phil Goodwin & Tyler Schultz        applyIdAttribute();
966be1495845e002cf1888bf1fe6b2ef1f43a0198dPhil Goodwin & Tyler Schultz        applyVisibilityAttribute();
9749e04b12550327c269ed8b826c71b1affe503336Phil Goodwin & Tyler Schultz        applyEnabledAttribute();
984cee28dd02fadbaec9b236f04ff15057fd866077Phil Goodwin & Tyler Schultz        applyBackgroundAttribute();
99b53a662c0c9502e86039aa5d0c3fb7fb3f22e6bbChris Van Vranken        applyTagAttribute();
1006c887826366610c9e44c21a9fec6020219226283Gautier Hayoun        applyOnClickAttribute();
101684ccc2fc5a1c79aa45af22b95c37f7c509a00c1Christian Williams    }
102684ccc2fc5a1c79aa45af22b95c37f7c509a00c1Christian Williams
103de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
1046eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    public void setId(int id) {
1056eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz        this.id = id;
1066eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    }
1076eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz
108de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
109cc4bd26d94f6eba2a0dc3dae0065c8df2296a95eIan Fisher & Tyler Schultz    public void setClickable(boolean clickable) {
110cc4bd26d94f6eba2a0dc3dae0065c8df2296a95eIan Fisher & Tyler Schultz        this.clickable = clickable;
111cc4bd26d94f6eba2a0dc3dae0065c8df2296a95eIan Fisher & Tyler Schultz    }
112cc4bd26d94f6eba2a0dc3dae0065c8df2296a95eIan Fisher & Tyler Schultz
113ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
114ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * Also sets focusable in touch mode to false if {@code focusable} is false, which is the Android behavior.
115ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     *
116ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * @param focusable the new status of the {@code View}'s focusability
117ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
118de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
119cc4bd26d94f6eba2a0dc3dae0065c8df2296a95eIan Fisher & Tyler Schultz    public void setFocusable(boolean focusable) {
120cc4bd26d94f6eba2a0dc3dae0065c8df2296a95eIan Fisher & Tyler Schultz        this.focusable = focusable;
121adfaceabbda4c8c51f24a0def8926075bd7306adChristian Williams        if (!focusable) {
122415f3fdab8162ece7185268f71b577f7faa0ba38Phil Goodwin & Ryan Richard            setFocusableInTouchMode(false);
123415f3fdab8162ece7185268f71b577f7faa0ba38Phil Goodwin & Ryan Richard        }
124415f3fdab8162ece7185268f71b577f7faa0ba38Phil Goodwin & Ryan Richard    }
125415f3fdab8162ece7185268f71b577f7faa0ba38Phil Goodwin & Ryan Richard
126415f3fdab8162ece7185268f71b577f7faa0ba38Phil Goodwin & Ryan Richard    @Implementation
127415f3fdab8162ece7185268f71b577f7faa0ba38Phil Goodwin & Ryan Richard    public final boolean isFocusableInTouchMode() {
128415f3fdab8162ece7185268f71b577f7faa0ba38Phil Goodwin & Ryan Richard        return focusableInTouchMode;
129415f3fdab8162ece7185268f71b577f7faa0ba38Phil Goodwin & Ryan Richard    }
130415f3fdab8162ece7185268f71b577f7faa0ba38Phil Goodwin & Ryan Richard
131ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
132ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * Also sets focusable to true if {@code focusableInTouchMode} is true, which is the Android behavior.
133ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     *
134ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * @param focusableInTouchMode the new status of the {@code View}'s touch mode focusability
135ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
136415f3fdab8162ece7185268f71b577f7faa0ba38Phil Goodwin & Ryan Richard    @Implementation
137415f3fdab8162ece7185268f71b577f7faa0ba38Phil Goodwin & Ryan Richard    public void setFocusableInTouchMode(boolean focusableInTouchMode) {
138415f3fdab8162ece7185268f71b577f7faa0ba38Phil Goodwin & Ryan Richard        this.focusableInTouchMode = focusableInTouchMode;
139adfaceabbda4c8c51f24a0def8926075bd7306adChristian Williams        if (focusableInTouchMode) {
140415f3fdab8162ece7185268f71b577f7faa0ba38Phil Goodwin & Ryan Richard            setFocusable(true);
141415f3fdab8162ece7185268f71b577f7faa0ba38Phil Goodwin & Ryan Richard        }
142cc4bd26d94f6eba2a0dc3dae0065c8df2296a95eIan Fisher & Tyler Schultz    }
143cc4bd26d94f6eba2a0dc3dae0065c8df2296a95eIan Fisher & Tyler Schultz
144de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
145254044cea0df7e6aef3ce33c98a5003a6eba0512Christian Williams & Phil Goodwin    public boolean isFocusable() {
146254044cea0df7e6aef3ce33c98a5003a6eba0512Christian Williams & Phil Goodwin        return focusable;
147254044cea0df7e6aef3ce33c98a5003a6eba0512Christian Williams & Phil Goodwin    }
148254044cea0df7e6aef3ce33c98a5003a6eba0512Christian Williams & Phil Goodwin
149254044cea0df7e6aef3ce33c98a5003a6eba0512Christian Williams & Phil Goodwin    @Implementation
1506eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    public int getId() {
1516eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz        return id;
1526eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    }
1536eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz
154ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
155ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * Simulates the inflating of the requested resource.
156ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     *
1578de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz     * @param context  the context from which to obtain a layout inflater
158ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * @param resource the ID of the resource to inflate
1598de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz     * @param root     the {@code ViewGroup} to add the inflated {@code View} to
160ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * @return the inflated View
161ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
162de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
163a66c979cb64d406c1646a0909bd9a0b6b6ccd802Ian Fisher & Tyler Schultz    public static View inflate(Context context, int resource, ViewGroup root) {
16440c6251719cccc0a84ae99c976d2836b14374ce6Christian Williams        return ShadowLayoutInflater.from(context).inflate(resource, root);
165a66c979cb64d406c1646a0909bd9a0b6b6ccd802Ian Fisher & Tyler Schultz    }
166a66c979cb64d406c1646a0909bd9a0b6b6ccd802Ian Fisher & Tyler Schultz
167ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
168ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * Finds this {@code View} if it's ID is passed in, returns {@code null} otherwise
169ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     *
170ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * @param id the id of the {@code View} to find
171ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * @return the {@code View}, if found, {@code null} otherwise
172ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
173de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
1746eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    public View findViewById(int id) {
175e617325bfe357b73644421064cae37e0a033eed7Christian Williams & Tyler Schulz        if (id == this.id) {
176e617325bfe357b73644421064cae37e0a033eed7Christian Williams & Tyler Schulz            return realView;
177e617325bfe357b73644421064cae37e0a033eed7Christian Williams & Tyler Schulz        }
1786eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz
1796eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz        return null;
1806eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    }
1816eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz
182de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
1830c40acb66824054e469b3afbc3609ba39bbdac1cChristian Williams & Harry Ugol    public View getRootView() {
184afe0a89d904a7fe2f5980b9deb26cc3240192459Christian Williams        ShadowView root = this;
185adfaceabbda4c8c51f24a0def8926075bd7306adChristian Williams        while (root.parent != null) {
1860c40acb66824054e469b3afbc3609ba39bbdac1cChristian Williams & Harry Ugol            root = root.parent;
1870c40acb66824054e469b3afbc3609ba39bbdac1cChristian Williams & Harry Ugol        }
1880c40acb66824054e469b3afbc3609ba39bbdac1cChristian Williams & Harry Ugol        return root.realView;
1890c40acb66824054e469b3afbc3609ba39bbdac1cChristian Williams & Harry Ugol    }
1900c40acb66824054e469b3afbc3609ba39bbdac1cChristian Williams & Harry Ugol
191de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
192d4f5daf12f1d112cf06b8b8914437ed6c0b3a677Ryan Richard & Tyler Schultz    public ViewGroup.LayoutParams getLayoutParams() {
193d4f5daf12f1d112cf06b8b8914437ed6c0b3a677Ryan Richard & Tyler Schultz        return layoutParams;
194d4f5daf12f1d112cf06b8b8914437ed6c0b3a677Ryan Richard & Tyler Schultz    }
195d4f5daf12f1d112cf06b8b8914437ed6c0b3a677Ryan Richard & Tyler Schultz
196de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
197b0336c5991d124b6b157b9dc976ade56d00cba3eChristian Williams & Ryan Richard    public void setLayoutParams(ViewGroup.LayoutParams params) {
198b0336c5991d124b6b157b9dc976ade56d00cba3eChristian Williams & Ryan Richard        layoutParams = params;
199b0336c5991d124b6b157b9dc976ade56d00cba3eChristian Williams & Ryan Richard    }
200b0336c5991d124b6b157b9dc976ade56d00cba3eChristian Williams & Ryan Richard
201de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
2025411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams    public final ViewParent getParent() {
203a89236397e869467b3fc6f7208f551da61235795Christian Williams & Tyler Schultz        return parent == null ? null : (ViewParent) parent.realView;
2045411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams    }
2055411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams
206de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
2076eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    public final Context getContext() {
2086eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz        return context;
2096eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    }
2106eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz
211de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
2126eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    public Resources getResources() {
2136eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz        return context.getResources();
2146eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    }
2156eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz
216de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
2174d4b979c716f731be80852e7c04fdbe9862be3f0Ian Fisher & Phil Goodwin    public void setBackgroundResource(int backgroundResourceId) {
218a075f94a84c6dd3493700d0c752fc545642e44d5Mike Grafton & Tyler Schultz        this.background = this.getResources().getDrawable(backgroundResourceId);
2194d4b979c716f731be80852e7c04fdbe9862be3f0Ian Fisher & Phil Goodwin        this.backgroundResourceId = backgroundResourceId;
220a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz        setBackgroundDrawable(getResources().getDrawable(backgroundResourceId));
221a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz    }
222a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz
223a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz    /**
224a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz     * Non-Android accessor.
225a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz     *
226a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz     * @return the resource ID of this views background
227a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz     */
228a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz    public int getBackgroundResourceId() {
229a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz        return backgroundResourceId;
230a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz    }
231a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz
232a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz    @Implementation
233a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz    public void setBackgroundColor(int color) {
234a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz        backgroundColor = color;
235a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz        setBackgroundDrawable(new ColorDrawable(getResources().getColor(color)));
236a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz    }
237a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz
238a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz    /**
239a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz     * Non-Android accessor.
240a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz     *
241a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz     * @return the resource color ID of this views background
242a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz     */
243a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz    public int getBackgroundColor() {
244a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz        return backgroundColor;
245a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz    }
246a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz
247a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz    @Implementation
248a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz    public void setBackgroundDrawable(Drawable d) {
249a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz        this.background = d;
250a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz    }
251a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz
252a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz    @Implementation
253a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz    public Drawable getBackground() {
254a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz        return background;
2554d4b979c716f731be80852e7c04fdbe9862be3f0Ian Fisher & Phil Goodwin    }
2564d4b979c716f731be80852e7c04fdbe9862be3f0Ian Fisher & Phil Goodwin
257de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
2586eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    public int getVisibility() {
2596eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz        return visibility;
2606eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    }
2616eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz
262de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
2636eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    public void setVisibility(int visibility) {
2646eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz        this.visibility = visibility;
2656eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    }
266eaadc83b187e31670dec8837d0851c0646522987Joe Moore & Tyler Schultz
267de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
268eaadc83b187e31670dec8837d0851c0646522987Joe Moore & Tyler Schultz    public void setSelected(boolean selected) {
269eaadc83b187e31670dec8837d0851c0646522987Joe Moore & Tyler Schultz        this.selected = selected;
270eaadc83b187e31670dec8837d0851c0646522987Joe Moore & Tyler Schultz    }
271810ca4e6f0dc6d69504b3e03ef61155f10083fbeChristian Williams & Joe Moore
272de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
273acb084f15b3b6e2496136ee8449b5d64ccb54939Ryan Richard & Tyler Schultz    public boolean isSelected() {
274acb084f15b3b6e2496136ee8449b5d64ccb54939Ryan Richard & Tyler Schultz        return this.selected;
275acb084f15b3b6e2496136ee8449b5d64ccb54939Ryan Richard & Tyler Schultz    }
276acb084f15b3b6e2496136ee8449b5d64ccb54939Ryan Richard & Tyler Schultz
277de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
278775ccf7ae53d9b4c77d3adf2514f26747cebd89cIan Fisher & Ryan Richard    public boolean isEnabled() {
279775ccf7ae53d9b4c77d3adf2514f26747cebd89cIan Fisher & Ryan Richard        return this.enabled;
280775ccf7ae53d9b4c77d3adf2514f26747cebd89cIan Fisher & Ryan Richard    }
281adfaceabbda4c8c51f24a0def8926075bd7306adChristian Williams
282de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
283775ccf7ae53d9b4c77d3adf2514f26747cebd89cIan Fisher & Ryan Richard    public void setEnabled(boolean enabled) {
284775ccf7ae53d9b4c77d3adf2514f26747cebd89cIan Fisher & Ryan Richard        this.enabled = enabled;
285775ccf7ae53d9b4c77d3adf2514f26747cebd89cIan Fisher & Ryan Richard    }
286775ccf7ae53d9b4c77d3adf2514f26747cebd89cIan Fisher & Ryan Richard
287de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
288810ca4e6f0dc6d69504b3e03ef61155f10083fbeChristian Williams & Joe Moore    public void setOnClickListener(View.OnClickListener onClickListener) {
289810ca4e6f0dc6d69504b3e03ef61155f10083fbeChristian Williams & Joe Moore        this.onClickListener = onClickListener;
290810ca4e6f0dc6d69504b3e03ef61155f10083fbeChristian Williams & Joe Moore    }
291810ca4e6f0dc6d69504b3e03ef61155f10083fbeChristian Williams & Joe Moore
292de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
293810ca4e6f0dc6d69504b3e03ef61155f10083fbeChristian Williams & Joe Moore    public boolean performClick() {
294810ca4e6f0dc6d69504b3e03ef61155f10083fbeChristian Williams & Joe Moore        if (onClickListener != null) {
295810ca4e6f0dc6d69504b3e03ef61155f10083fbeChristian Williams & Joe Moore            onClickListener.onClick(realView);
296810ca4e6f0dc6d69504b3e03ef61155f10083fbeChristian Williams & Joe Moore            return true;
297810ca4e6f0dc6d69504b3e03ef61155f10083fbeChristian Williams & Joe Moore        } else {
298810ca4e6f0dc6d69504b3e03ef61155f10083fbeChristian Williams & Joe Moore            return false;
299810ca4e6f0dc6d69504b3e03ef61155f10083fbeChristian Williams & Joe Moore        }
300810ca4e6f0dc6d69504b3e03ef61155f10083fbeChristian Williams & Joe Moore    }
301c6f46aeb970c9111e2e79b806451f63b4853950bIan Fisher & Tyler Schultz
302de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
303d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz    public void setOnLongClickListener(View.OnLongClickListener onLongClickListener) {
304d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz        this.onLongClickListener = onLongClickListener;
305d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz    }
306d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz
307d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz    @Implementation
308d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz    public boolean performLongClick() {
309d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz        if (onLongClickListener != null) {
310d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz            onLongClickListener.onLongClick(realView);
311d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz            return true;
312d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz        } else {
313d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz            return false;
314d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz        }
315d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz    }
316d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz
317d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz    @Implementation
3185411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams    public void setOnKeyListener(View.OnKeyListener onKeyListener) {
3195411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams        this.onKeyListener = onKeyListener;
3205411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams    }
3215411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams
322de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
323c6f46aeb970c9111e2e79b806451f63b4853950bIan Fisher & Tyler Schultz    public Object getTag() {
324c6f46aeb970c9111e2e79b806451f63b4853950bIan Fisher & Tyler Schultz        return this.tag;
325c6f46aeb970c9111e2e79b806451f63b4853950bIan Fisher & Tyler Schultz    }
326c6f46aeb970c9111e2e79b806451f63b4853950bIan Fisher & Tyler Schultz
327de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
328c6f46aeb970c9111e2e79b806451f63b4853950bIan Fisher & Tyler Schultz    public void setTag(Object tag) {
329c6f46aeb970c9111e2e79b806451f63b4853950bIan Fisher & Tyler Schultz        this.tag = tag;
330c6f46aeb970c9111e2e79b806451f63b4853950bIan Fisher & Tyler Schultz    }
33118141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard
332de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
33318141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard    public final int getHeight() {
334a1ef7deaed03310ed6ec51621125f69bb16ac8fcChristian Williams & Ryan Richard        return bottom - top;
33518141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard    }
33618141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard
337de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
33818141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard    public final int getWidth() {
339a1ef7deaed03310ed6ec51621125f69bb16ac8fcChristian Williams & Ryan Richard        return right - left;
34018141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard    }
34118141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard
342de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
343924f851cb0ec279b6974744ce623f25bdc657551Ryan Richard    public final int getMeasuredWidth() {
344a1ef7deaed03310ed6ec51621125f69bb16ac8fcChristian Williams & Ryan Richard        return getWidth();
345a1ef7deaed03310ed6ec51621125f69bb16ac8fcChristian Williams & Ryan Richard    }
346a1ef7deaed03310ed6ec51621125f69bb16ac8fcChristian Williams & Ryan Richard
347de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
348a1ef7deaed03310ed6ec51621125f69bb16ac8fcChristian Williams & Ryan Richard    public final void layout(int l, int t, int r, int b) {
349a1ef7deaed03310ed6ec51621125f69bb16ac8fcChristian Williams & Ryan Richard        left = l;
350a1ef7deaed03310ed6ec51621125f69bb16ac8fcChristian Williams & Ryan Richard        top = t;
351a1ef7deaed03310ed6ec51621125f69bb16ac8fcChristian Williams & Ryan Richard        right = r;
352a1ef7deaed03310ed6ec51621125f69bb16ac8fcChristian Williams & Ryan Richard        bottom = b;
353a1ef7deaed03310ed6ec51621125f69bb16ac8fcChristian Williams & Ryan Richard
354a1ef7deaed03310ed6ec51621125f69bb16ac8fcChristian Williams & Ryan Richard// todo:       realView.onLayout();
355924f851cb0ec279b6974744ce623f25bdc657551Ryan Richard    }
356adfaceabbda4c8c51f24a0def8926075bd7306adChristian Williams
357de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
35818141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard    public void setPadding(int left, int top, int right, int bottom) {
35918141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard        paddingLeft = left;
36018141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard        paddingTop = top;
36118141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard        paddingRight = right;
36218141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard        paddingBottom = bottom;
36318141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard    }
36418141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard
365de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
36618141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard    public int getPaddingTop() {
36718141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard        return paddingTop;
36818141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard    }
36918141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard
370de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
37118141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard    public int getPaddingLeft() {
37218141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard        return paddingLeft;
37318141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard    }
37418141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard
375de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
37618141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard    public int getPaddingRight() {
37718141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard        return paddingRight;
37818141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard    }
37918141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard
380de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
38118141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard    public int getPaddingBottom() {
38218141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard        return paddingBottom;
38318141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard    }
38451fe0b279e9f5568683d9ef67921f922a51c05d5Christian Williams & Tyler Schultz
385de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
38644ade170c5bc611222ed25d5b1f8e7745104057dChristian Williams    public Object getTag(int key) {
38744ade170c5bc611222ed25d5b1f8e7745104057dChristian Williams        return tags.get(key);
38844ade170c5bc611222ed25d5b1f8e7745104057dChristian Williams    }
38944ade170c5bc611222ed25d5b1f8e7745104057dChristian Williams
390de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
39144ade170c5bc611222ed25d5b1f8e7745104057dChristian Williams    public void setTag(int key, Object value) {
39244ade170c5bc611222ed25d5b1f8e7745104057dChristian Williams        tags.put(key, value);
39344ade170c5bc611222ed25d5b1f8e7745104057dChristian Williams    }
3945411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams
39565e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams    @Implementation
3964241c0d59435626c1858d15e5e3612674a666ec0Lowell Kirsh & Ryan Richard    public void requestLayout() {
3974241c0d59435626c1858d15e5e3612674a666ec0Lowell Kirsh & Ryan Richard        didRequestLayout = true;
3984241c0d59435626c1858d15e5e3612674a666ec0Lowell Kirsh & Ryan Richard    }
3994241c0d59435626c1858d15e5e3612674a666ec0Lowell Kirsh & Ryan Richard
4004241c0d59435626c1858d15e5e3612674a666ec0Lowell Kirsh & Ryan Richard    public boolean didRequestLayout() {
4014241c0d59435626c1858d15e5e3612674a666ec0Lowell Kirsh & Ryan Richard        return didRequestLayout;
4024241c0d59435626c1858d15e5e3612674a666ec0Lowell Kirsh & Ryan Richard    }
4034241c0d59435626c1858d15e5e3612674a666ec0Lowell Kirsh & Ryan Richard
4044241c0d59435626c1858d15e5e3612674a666ec0Lowell Kirsh & Ryan Richard    @Implementation
40565e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams    public final boolean requestFocus() {
40665e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams        return requestFocus(View.FOCUS_DOWN);
40765e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams    }
40865e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams
40965e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams    @Implementation
41065e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams    public final boolean requestFocus(int direction) {
41165e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams        setViewFocus(true);
41265e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams        return true;
41365e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams    }
41465e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams
4155411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams    public void setViewFocus(boolean hasFocus) {
4169729911f8638b6bb4d55b3d67e6d68a6b3f19dc7Phil Goodwin        this.isFocused = hasFocus;
4175411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams        if (onFocusChangeListener != null) {
4185411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams            onFocusChangeListener.onFocusChange(realView, hasFocus);
4195411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams        }
4205411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams    }
4215411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams
422de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
42365e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams    public boolean isFocused() {
4249729911f8638b6bb4d55b3d67e6d68a6b3f19dc7Phil Goodwin        return isFocused;
42565e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams    }
42665e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams
42765e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams    @Implementation
4285411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams    public boolean hasFocus() {
4299729911f8638b6bb4d55b3d67e6d68a6b3f19dc7Phil Goodwin        return isFocused;
4305411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams    }
4315411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams
432de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
43365e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams    public void clearFocus() {
43465e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams        setViewFocus(false);
43565e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams    }
43665e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams
43765e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams    @Implementation
4385411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams    public void setOnFocusChangeListener(View.OnFocusChangeListener listener) {
4395411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams        onFocusChangeListener = listener;
4405411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams    }
4411c46c94a5affe7beeb8c6bfcb5ec0ed509e5fdbdRyan Richard
442de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
4431c46c94a5affe7beeb8c6bfcb5ec0ed509e5fdbdRyan Richard    public void invalidate() {
4441c46c94a5affe7beeb8c6bfcb5ec0ed509e5fdbdRyan Richard        wasInvalidated = true;
4451c46c94a5affe7beeb8c6bfcb5ec0ed509e5fdbdRyan Richard    }
446924f851cb0ec279b6974744ce623f25bdc657551Ryan Richard
447de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
448924f851cb0ec279b6974744ce623f25bdc657551Ryan Richard    public void setOnTouchListener(View.OnTouchListener onTouchListener) {
449924f851cb0ec279b6974744ce623f25bdc657551Ryan Richard        this.onTouchListener = onTouchListener;
450924f851cb0ec279b6974744ce623f25bdc657551Ryan Richard    }
451924f851cb0ec279b6974744ce623f25bdc657551Ryan Richard
452de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
453924f851cb0ec279b6974744ce623f25bdc657551Ryan Richard    public boolean dispatchTouchEvent(MotionEvent event) {
454924f851cb0ec279b6974744ce623f25bdc657551Ryan Richard        if (onTouchListener != null) {
455924f851cb0ec279b6974744ce623f25bdc657551Ryan Richard            return onTouchListener.onTouch(realView, event);
456924f851cb0ec279b6974744ce623f25bdc657551Ryan Richard        }
457924f851cb0ec279b6974744ce623f25bdc657551Ryan Richard        return false;
458924f851cb0ec279b6974744ce623f25bdc657551Ryan Richard    }
4592ff94a9e4df5b0d3eb21bda70793b27d9f1f353cChristian Williams & Phil Goodwin
460ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
461da9cd404c0db2ebcef4ecfb50836de00b56622f1Christian Williams     * Returns a string representation of this {@code View}. Unless overridden, it will be an empty string.
46240c6251719cccc0a84ae99c976d2836b14374ce6Christian Williams     * <p/>
463da9cd404c0db2ebcef4ecfb50836de00b56622f1Christian Williams     * Robolectric extension.
464ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
4652ff94a9e4df5b0d3eb21bda70793b27d9f1f353cChristian Williams & Phil Goodwin    public String innerText() {
4662ff94a9e4df5b0d3eb21bda70793b27d9f1f353cChristian Williams & Phil Goodwin        return "";
4672ff94a9e4df5b0d3eb21bda70793b27d9f1f353cChristian Williams & Phil Goodwin    }
46886e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams
469ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
470ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * Dumps the status of this {@code View} to {@code System.out}
471ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
47286e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams    public void dump() {
47386e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams        dump(System.out, 0);
47486e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams    }
47586e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams
476ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
477ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * Dumps the status of this {@code View} to {@code System.out} at the given indentation level
478ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
47986e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams    public void dump(PrintStream out, int indent) {
48086e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams        dumpFirstPart(out, indent);
48186e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams        out.println("/>");
48286e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams    }
48386e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams
48486e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams    protected void dumpFirstPart(PrintStream out, int indent) {
48586e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams        dumpIndent(out, indent);
48686e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams
48786e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams        out.print("<" + realView.getClass().getSimpleName());
48886e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams        if (id > 0) {
48986e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams            out.print(" id=\"" + shadowOf(context).getResourceLoader().getNameForId(id) + "\"");
49086e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams        }
49186e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams    }
49286e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams
49386e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams    protected void dumpIndent(PrintStream out, int indent) {
49486e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams        for (int i = 0; i < indent; i++) out.print(" ");
49586e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams    }
4964d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
497ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
498ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * @return left side of the view
499ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
500bbf6ae3d37d2303d8463094096ef0bb9906fd658Christian Williams    @Implementation
5014d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public int getLeft() {
5024d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        return left;
5034d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
5044d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
505ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
506ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * @return top coordinate of the view
507ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
508bbf6ae3d37d2303d8463094096ef0bb9906fd658Christian Williams    @Implementation
5094d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public int getTop() {
5104d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        return top;
5114d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
5124d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
513ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
514ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * @return right side of the view
515ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
516bbf6ae3d37d2303d8463094096ef0bb9906fd658Christian Williams    @Implementation
5174d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public int getRight() {
5184d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        return right;
5194d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
5204d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
521ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
522ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * @return bottom coordinate of the view
523ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
524bbf6ae3d37d2303d8463094096ef0bb9906fd658Christian Williams    @Implementation
5254d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public int getBottom() {
5264d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        return bottom;
5274d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
5284d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
529ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
530ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * @return whether the view is clickable
531ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
532bbf6ae3d37d2303d8463094096ef0bb9906fd658Christian Williams    @Implementation
5334d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public boolean isClickable() {
5344d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        return clickable;
5354d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
5364d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
537ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
538de2143a1bef92c4ef270d3391b9201e8b8af7051Christian Williams     * Non-Android accessor.
539ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     *
540ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * @return whether or not {@link #invalidate()} has been called
541ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
5424d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public boolean wasInvalidated() {
5434d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        return wasInvalidated;
5444d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
5454d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
546ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
547ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * Clears the wasInvalidated flag
548ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
5494d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public void clearWasInvalidated() {
5504d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        wasInvalidated = false;
5514d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
5524d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
553ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
554de2143a1bef92c4ef270d3391b9201e8b8af7051Christian Williams     * Non-Android accessor.
555ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
5564d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public void setLeft(int left) {
5574d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        this.left = left;
5584d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
5594d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
560ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
561de2143a1bef92c4ef270d3391b9201e8b8af7051Christian Williams     * Non-Android accessor.
562ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
5634d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public void setTop(int top) {
5644d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        this.top = top;
5654d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
5664d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
567ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
568de2143a1bef92c4ef270d3391b9201e8b8af7051Christian Williams     * Non-Android accessor.
569ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
5704d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public void setRight(int right) {
5714d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        this.right = right;
5724d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
5734d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
574ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
575de2143a1bef92c4ef270d3391b9201e8b8af7051Christian Williams     * Non-Android accessor.
576ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
5774d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public void setBottom(int bottom) {
5784d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        this.bottom = bottom;
5794d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
5804d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
581ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
582de2143a1bef92c4ef270d3391b9201e8b8af7051Christian Williams     * Non-Android accessor.
583ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
5844d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public void setPaddingLeft(int paddingLeft) {
5854d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        this.paddingLeft = paddingLeft;
5864d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
5874d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
588ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
589de2143a1bef92c4ef270d3391b9201e8b8af7051Christian Williams     * Non-Android accessor.
590ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
5914d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public void setPaddingTop(int paddingTop) {
5924d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        this.paddingTop = paddingTop;
5934d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
5944d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
595ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
596de2143a1bef92c4ef270d3391b9201e8b8af7051Christian Williams     * Non-Android accessor.
597ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
5984d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public void setPaddingRight(int paddingRight) {
5994d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        this.paddingRight = paddingRight;
6004d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
6014d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
602ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
603de2143a1bef92c4ef270d3391b9201e8b8af7051Christian Williams     * Non-Android accessor.
604ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
6054d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public void setPaddingBottom(int paddingBottom) {
6064d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        this.paddingBottom = paddingBottom;
6074d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
6084d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
609ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
610de2143a1bef92c4ef270d3391b9201e8b8af7051Christian Williams     * Non-Android accessor.
611ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
6124d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public void setFocused(boolean focused) {
6134d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        isFocused = focused;
6144d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
6158de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz
6168de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz    /**
6178de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz     * Non-Android accessor.
6188de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz     *
6198de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz     * @return true if this object and all of its ancestors are {@code View.VISIBLE}, returns false if this or
6208de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz     *         any ancestor is not {@code View.VISIBLE}
6218de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz     */
6228de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz    public boolean derivedIsVisible() {
6238de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz        View parent = realView;
6248de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz        while (parent != null) {
6258de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz            if (parent.getVisibility() != View.VISIBLE) {
6268de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz                return false;
6278de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz            }
6288de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz            parent = (View) parent.getParent();
6298de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz        }
6308de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz        return true;
6318de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz    }
632c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz
633c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz    /**
634c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz     * Utility method for clicking on views exposing testing scenarios that are not possible when using the actual app.
635c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz     *
636c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz     * @throws RuntimeException if the view is disabled or if the view or any of its parents are not visible.
637c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz     */
638c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz    public boolean checkedPerformClick() {
639c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz        if (!derivedIsVisible()) {
640c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz            throw new RuntimeException("View is not visible and cannot be clicked");
641c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz        }
642c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz        if (!realView.isEnabled()) {
643c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz            throw new RuntimeException("View is not enabled and cannot be clicked");
644c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz        }
645c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz
646c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz        return realView.performClick();
647c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz    }
6485101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz
64906dfb798c2833348ed593991759fb581f7c7b20dPhil Goodwin & Tyler Schultz    public void applyFocus() {
65006dfb798c2833348ed593991759fb581f7c7b20dPhil Goodwin & Tyler Schultz        if (noParentHasFocus(realView)) {
65106dfb798c2833348ed593991759fb581f7c7b20dPhil Goodwin & Tyler Schultz            Boolean focusRequested = attributeSet.getAttributeBooleanValue("android", "focus", false);
65206dfb798c2833348ed593991759fb581f7c7b20dPhil Goodwin & Tyler Schultz            if (focusRequested || realView.isFocusableInTouchMode()) {
65306dfb798c2833348ed593991759fb581f7c7b20dPhil Goodwin & Tyler Schultz                realView.requestFocus();
65406dfb798c2833348ed593991759fb581f7c7b20dPhil Goodwin & Tyler Schultz            }
65506dfb798c2833348ed593991759fb581f7c7b20dPhil Goodwin & Tyler Schultz        }
6565101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz    }
6575101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz
6585189dc7b67bf8426200b68a998442ba821a27222Phil Goodwin & Tyler Schultz    private void applyIdAttribute() {
6595189dc7b67bf8426200b68a998442ba821a27222Phil Goodwin & Tyler Schultz        Integer id = attributeSet.getAttributeResourceValue("android", "id", 0);
6605189dc7b67bf8426200b68a998442ba821a27222Phil Goodwin & Tyler Schultz        if (getId() == 0) {
6615189dc7b67bf8426200b68a998442ba821a27222Phil Goodwin & Tyler Schultz            setId(id);
6622bc51e5a1e4d54158f7ff81af442d306fcd9a449Phil Goodwin & Tyler Schultz        }
6632bc51e5a1e4d54158f7ff81af442d306fcd9a449Phil Goodwin & Tyler Schultz    }
664d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz
665b53a662c0c9502e86039aa5d0c3fb7fb3f22e6bbChris Van Vranken    private void applyTagAttribute() {
666d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz        Object tag = attributeSet.getAttributeValue("android", "tag");
667d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz        if (tag != null) {
668d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz            setTag(tag);
669d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz        }
670d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz    }
6712bc51e5a1e4d54158f7ff81af442d306fcd9a449Phil Goodwin & Tyler Schultz
6726be1495845e002cf1888bf1fe6b2ef1f43a0198dPhil Goodwin & Tyler Schultz    private void applyVisibilityAttribute() {
6736be1495845e002cf1888bf1fe6b2ef1f43a0198dPhil Goodwin & Tyler Schultz        String visibility = attributeSet.getAttributeValue("android", "visibility");
6745101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz        if (visibility != null) {
6755101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz            if (visibility.equals("gone")) {
6765101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz                setVisibility(View.GONE);
6775101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz            } else if (visibility.equals("invisible")) {
6785101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz                setVisibility(View.INVISIBLE);
6795101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz            }
6805101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz        }
6815101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz    }
6825101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz
68349e04b12550327c269ed8b826c71b1affe503336Phil Goodwin & Tyler Schultz    private void applyEnabledAttribute() {
68449e04b12550327c269ed8b826c71b1affe503336Phil Goodwin & Tyler Schultz        setEnabled(attributeSet.getAttributeBooleanValue("android", "enabled", true));
6855101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz    }
68619d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz
6874cee28dd02fadbaec9b236f04ff15057fd866077Phil Goodwin & Tyler Schultz    private void applyBackgroundAttribute() {
68840c6251719cccc0a84ae99c976d2836b14374ce6Christian Williams        String source = attributeSet.getAttributeValue("android", "background");
68940c6251719cccc0a84ae99c976d2836b14374ce6Christian Williams        if (source != null) {
69040c6251719cccc0a84ae99c976d2836b14374ce6Christian Williams            if (source.startsWith("@drawable/")) {
69140c6251719cccc0a84ae99c976d2836b14374ce6Christian Williams                setBackgroundResource(attributeSet.getAttributeResourceValue("android", "background", 0));
69240c6251719cccc0a84ae99c976d2836b14374ce6Christian Williams            }
69340c6251719cccc0a84ae99c976d2836b14374ce6Christian Williams        }
6946d2ed84f8604e5022dd0576567bf3a0bd0e22403Macarse    }
6956d2ed84f8604e5022dd0576567bf3a0bd0e22403Macarse
6966c887826366610c9e44c21a9fec6020219226283Gautier Hayoun    private void applyOnClickAttribute() {
6976c887826366610c9e44c21a9fec6020219226283Gautier Hayoun        final String handlerName = attributeSet.getAttributeValue("android",
698d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz                "onClick");
6996c887826366610c9e44c21a9fec6020219226283Gautier Hayoun        if (handlerName == null) {
7006c887826366610c9e44c21a9fec6020219226283Gautier Hayoun            return;
7016c887826366610c9e44c21a9fec6020219226283Gautier Hayoun        }
7026c887826366610c9e44c21a9fec6020219226283Gautier Hayoun
7036c887826366610c9e44c21a9fec6020219226283Gautier Hayoun        /* good part of following code has been directly copied from original
7046c887826366610c9e44c21a9fec6020219226283Gautier Hayoun         * android source */
7056c887826366610c9e44c21a9fec6020219226283Gautier Hayoun        setOnClickListener(new View.OnClickListener() {
7066c887826366610c9e44c21a9fec6020219226283Gautier Hayoun            public void onClick(View v) {
7076c887826366610c9e44c21a9fec6020219226283Gautier Hayoun                Method mHandler;
7086c887826366610c9e44c21a9fec6020219226283Gautier Hayoun                try {
7096c887826366610c9e44c21a9fec6020219226283Gautier Hayoun                    mHandler = getContext().getClass().getMethod(handlerName,
710d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz                            View.class);
7116c887826366610c9e44c21a9fec6020219226283Gautier Hayoun                } catch (NoSuchMethodException e) {
7126c887826366610c9e44c21a9fec6020219226283Gautier Hayoun                    int id = getId();
7136c887826366610c9e44c21a9fec6020219226283Gautier Hayoun                    String idText = id == View.NO_ID ? "" : " with id '"
7146c887826366610c9e44c21a9fec6020219226283Gautier Hayoun                            + shadowOf(context).getResourceLoader()
715d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz                            .getNameForId(id) + "'";
7166c887826366610c9e44c21a9fec6020219226283Gautier Hayoun                    throw new IllegalStateException("Could not find a method " +
7176c887826366610c9e44c21a9fec6020219226283Gautier Hayoun                            handlerName + "(View) in the activity "
7186c887826366610c9e44c21a9fec6020219226283Gautier Hayoun                            + getContext().getClass() + " for onClick handler"
7196c887826366610c9e44c21a9fec6020219226283Gautier Hayoun                            + " on view " + realView.getClass() + idText, e);
7206c887826366610c9e44c21a9fec6020219226283Gautier Hayoun                }
7216c887826366610c9e44c21a9fec6020219226283Gautier Hayoun
7226c887826366610c9e44c21a9fec6020219226283Gautier Hayoun                try {
7236c887826366610c9e44c21a9fec6020219226283Gautier Hayoun                    mHandler.invoke(getContext(), realView);
7246c887826366610c9e44c21a9fec6020219226283Gautier Hayoun                } catch (IllegalAccessException e) {
7256c887826366610c9e44c21a9fec6020219226283Gautier Hayoun                    throw new IllegalStateException("Could not execute non "
7266c887826366610c9e44c21a9fec6020219226283Gautier Hayoun                            + "public method of the activity", e);
7276c887826366610c9e44c21a9fec6020219226283Gautier Hayoun                } catch (InvocationTargetException e) {
7286c887826366610c9e44c21a9fec6020219226283Gautier Hayoun                    throw new IllegalStateException("Could not execute "
7296c887826366610c9e44c21a9fec6020219226283Gautier Hayoun                            + "method of the activity", e);
7306c887826366610c9e44c21a9fec6020219226283Gautier Hayoun                }
7316c887826366610c9e44c21a9fec6020219226283Gautier Hayoun            }
7326c887826366610c9e44c21a9fec6020219226283Gautier Hayoun        });
7336c887826366610c9e44c21a9fec6020219226283Gautier Hayoun    }
7346c887826366610c9e44c21a9fec6020219226283Gautier Hayoun
73506dfb798c2833348ed593991759fb581f7c7b20dPhil Goodwin & Tyler Schultz    private boolean noParentHasFocus(View view) {
73619d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz        while (view != null) {
73706dfb798c2833348ed593991759fb581f7c7b20dPhil Goodwin & Tyler Schultz            if (view.hasFocus()) return false;
73819d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz            view = (View) view.getParent();
73919d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz        }
74006dfb798c2833348ed593991759fb581f7c7b20dPhil Goodwin & Tyler Schultz        return true;
74119d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz    }
742d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz
7430ed02e080ff9f471642662ba0678db1d42221343Michael Portuesi    /**
7440ed02e080ff9f471642662ba0678db1d42221343Michael Portuesi     * Non-android accessor.  Returns touch listener, if set.
745d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz     *
7460ed02e080ff9f471642662ba0678db1d42221343Michael Portuesi     * @return
7470ed02e080ff9f471642662ba0678db1d42221343Michael Portuesi     */
7480ed02e080ff9f471642662ba0678db1d42221343Michael Portuesi    public View.OnTouchListener getOnTouchListener() {
749d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz        return onTouchListener;
7500ed02e080ff9f471642662ba0678db1d42221343Michael Portuesi    }
751d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz
75246309a9995c013790cbc40ae207f10973350b14fMichael Portuesi    /**
75346309a9995c013790cbc40ae207f10973350b14fMichael Portuesi     * Non-android accessor.  Returns click listener, if set.
754d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz     *
75546309a9995c013790cbc40ae207f10973350b14fMichael Portuesi     * @return
75646309a9995c013790cbc40ae207f10973350b14fMichael Portuesi     */
75746309a9995c013790cbc40ae207f10973350b14fMichael Portuesi    public View.OnClickListener getOnClickListener() {
758d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz        return onClickListener;
75946309a9995c013790cbc40ae207f10973350b14fMichael Portuesi    }
760ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williams
761b76cabccd9f35b57fe486faf7d5763952c07c1a9Josh Lauer & Christian Williams    @Implementation
762ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williams    public void setDrawingCacheEnabled(boolean drawingCacheEnabled) {
763ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williams        this.drawingCacheEnabled = drawingCacheEnabled;
764ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williams    }
765ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williams
766b76cabccd9f35b57fe486faf7d5763952c07c1a9Josh Lauer & Christian Williams    @Implementation
767ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williams    public boolean isDrawingCacheEnabled() {
768ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williams        return drawingCacheEnabled;
769ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williams    }
770ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williams
771b76cabccd9f35b57fe486faf7d5763952c07c1a9Josh Lauer & Christian Williams    @Implementation
772ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williams    public Bitmap getDrawingCache() {
773ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williams        return Robolectric.newInstanceOf(Bitmap.class);
774ae26238c7d01caef84ceddd8ffb42c32306918d6Josh Lauer & Christian Williams    }
77540c6251719cccc0a84ae99c976d2836b14374ce6Christian Williams
77634f3d7cb9f41c9480d7b7b4e03be6df4c1c8021fRich Humphrey    @Implementation
77734f3d7cb9f41c9480d7b7b4e03be6df4c1c8021fRich Humphrey    public void post(Runnable action) {
77834f3d7cb9f41c9480d7b7b4e03be6df4c1c8021fRich Humphrey        Robolectric.getUiThreadScheduler().post(action);
77934f3d7cb9f41c9480d7b7b4e03be6df4c1c8021fRich Humphrey    }
780b020d9a038a8d1274806e1cccbc015f559396f05Christian Williams
781b020d9a038a8d1274806e1cccbc015f559396f05Christian Williams    @Implementation
782b020d9a038a8d1274806e1cccbc015f559396f05Christian Williams    public void postDelayed(Runnable action, long delayMills) {
783b020d9a038a8d1274806e1cccbc015f559396f05Christian Williams        Robolectric.getUiThreadScheduler().postDelayed(action, delayMills);
784b020d9a038a8d1274806e1cccbc015f559396f05Christian Williams    }
785289938e9153024d2146a7130de98fdc16efd5aa2Tim Labeeuw & Tyler Schultz
786289938e9153024d2146a7130de98fdc16efd5aa2Tim Labeeuw & Tyler Schultz    @Implementation
787289938e9153024d2146a7130de98fdc16efd5aa2Tim Labeeuw & Tyler Schultz    public void postInvalidateDelayed(long delayMilliseconds) {
788289938e9153024d2146a7130de98fdc16efd5aa2Tim Labeeuw & Tyler Schultz        Robolectric.getUiThreadScheduler().postDelayed(new Runnable() {
789289938e9153024d2146a7130de98fdc16efd5aa2Tim Labeeuw & Tyler Schultz            @Override
790289938e9153024d2146a7130de98fdc16efd5aa2Tim Labeeuw & Tyler Schultz            public void run() {
791289938e9153024d2146a7130de98fdc16efd5aa2Tim Labeeuw & Tyler Schultz                realView.invalidate();
792289938e9153024d2146a7130de98fdc16efd5aa2Tim Labeeuw & Tyler Schultz            }
793289938e9153024d2146a7130de98fdc16efd5aa2Tim Labeeuw & Tyler Schultz        }, delayMilliseconds);
794289938e9153024d2146a7130de98fdc16efd5aa2Tim Labeeuw & Tyler Schultz    }
795d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz
7963f78da998ce73c1c7c25798a7e7e4f19287eff23Michael Portuesi    @Implementation
7973f78da998ce73c1c7c25798a7e7e4f19287eff23Michael Portuesi    public Animation getAnimation() {
798d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz        return animation;
7993f78da998ce73c1c7c25798a7e7e4f19287eff23Michael Portuesi    }
800d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz
8013f78da998ce73c1c7c25798a7e7e4f19287eff23Michael Portuesi    @Implementation
8023f78da998ce73c1c7c25798a7e7e4f19287eff23Michael Portuesi    public void setAnimation(Animation anim) {
803d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz        animation = anim;
8043f78da998ce73c1c7c25798a7e7e4f19287eff23Michael Portuesi    }
805d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz
8063f78da998ce73c1c7c25798a7e7e4f19287eff23Michael Portuesi    @Implementation
8073f78da998ce73c1c7c25798a7e7e4f19287eff23Michael Portuesi    public void startAnimation(Animation anim) {
808d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz        setAnimation(anim);
809d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz        animation.start();
8103f78da998ce73c1c7c25798a7e7e4f19287eff23Michael Portuesi    }
811d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz
8123f78da998ce73c1c7c25798a7e7e4f19287eff23Michael Portuesi    @Implementation
8133f78da998ce73c1c7c25798a7e7e4f19287eff23Michael Portuesi    public void clearAnimation() {
814d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz        if (animation != null) {
815d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz            animation.cancel();
816d723e05df54299b88daa5b626c460d733d9bcf6dLenny Turetsky & Tyler Schultz        }
8173f78da998ce73c1c7c25798a7e7e4f19287eff23Michael Portuesi    }
818a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz
819a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz    @Implementation
820a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz    public void scrollTo(int x, int y) {
821a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz        this.scrollToCoordinates = new Point(x, y);
822a739b57a6b1a99f14d586f609f0f62f48b8e2284Ian Fisher & Tyler Schultz    }
8236eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz}
824