I have been searching everywhere for a list of supported methods in RemoteViews but come up empty. Can anyone link a resource or list all available methods supported by RemoteViews? Thanks.
I am assuming that you are referring to the methods that can be used by RemoteViews methods like setBoolean().
The way to determine if a method is supported is to look at the source code and see whether the method has the #RemotableViewMethod annotation. If it does, that is available for those ad-hoc RemoteViews "setters".
So for example, the first #RemotableViewMethod-annotated method in the Android 7.1 edition of View is setContentDescription().
Note that these annotations may change over time. They should not be removed (unless perhaps the underlying method is deprecated), but ones can be added. So, you will want to check the source associated with your minSdkVersion.
Related
I have created a Builder class which initializes the Picasso library object in variety of ways, properties like gravity, resize(x,y) etc.
In one particular case, if isCenterCropGravity(int gravity) is called. The gravity is operational if the resize method is also called while creating the object.
In order to achieve so, I want to create a custom lint check, within which, if the centerCropGravity() method is called before resize() method, a lint error message warning should be displayed, now I've never written custom lint check and any available resource on the internet is not remotely related to the solution i want to achieve.
I have one custom class having initializeScrollBars() in its constructor.
In API 21, the method was removed, so i am not able to build the app on Lollipop 5.0.I have searched and found that, there is no alternative provided by android officially.
(https://developer.android.com/sdk/api_diff/21/changes/android.view.View.html).
I have checked this link: initializeScrollbars is undefined? and noticed that one developer suggest us to remove the method and let it on the View class by defining R.styleable.View_scrollbars attr which is not internal.
I just don't get it.
Google have answered for this issue as:
"The API has been removed because R.styleable is not public or stable. There is no safe way to pass a TypedArray into that method. Don't call the method."(Ref: https://github.com/GDG-Korea/PinterestLikeAdapterView/issues/31)
Can anyone light me a path how to remove the method
initializeScrollbars() from the custom view?
Can i simply remove initializeScrollbars() from constructor ?
What is the best way to initialize scrollbars of a custom view.?
I want to make a small change to the Android standard TimePicker class. Specifically, I'm trying to change it so it works in 15 minute increments, rather than 1 minute increments.
This post helped me constrain the range of minute values to {0, 15, 30, 45}, as required in my app. But as I pointed out in a follow up comment, the minute spinner still shows previous minute as current value - 1, and the next minute as current value + 1, which creates a sloppy-feeling user interface.
I looked into the relevant Android source code, and it appears that the changes I would need to make are pretty simple. But when I tried copying the source code into my project I got about a zillion errors relating to the package declaration, where to find Widget, how to resolve R.id variables, etc.
So my question is:
What's the best way to make a small change to a given class from Android source code, and incorporate it into your own project?
In my case, I just need to make a few small changes to TimePicker and NumberPicker, but I'm not sure how to properly set this up in my project.
Thanks for any suggestions.
But when I tried copying the source code into my project I got about a zillion errors relating to the package declaration
Your source file's directory needs to match the package name. And since you cannot overwrite android.widget.TimePicker, you will either need to move that class to a new package or give it a new name.
where to find Widget
That implies that you copied TimePicker into one of your packages. That is fine, but then you need to add in the appropriate import statements for classes that TimePicker referred to from its original package. Or, you need to keep your (renamed) TimePicker in android.widget, adding this package to your project. This is rudimentary Java.
how to resolve R.id variables
If TimePicker relies upon resources that are not part of the Android SDK, you will need to copy those resources from the AOSP into your project as well.
What's the best way to make a small change to a given class from Android source code, and incorporate it into your own project?
IMHO, that cannot be answered readily in the abstract. Generally speaking, you do the sorts of things that I listed above.
You are best off subclassing the relevant classes and overriding the methods you would like to change.
In Java, you can do the following in a subclass:
The inherited fields can be used directly, just like any other
fields.
You can declare a field in the subclass with the same name as
the one in the superclass, thus hiding it (not recommended).
You can
declare new fields in the subclass that are not in the superclass.
The inherited methods can be used directly as they are.
You can write a new instance method in the subclass that has the same signature as the one in the superclass, thus overriding it.
You can write a new static method in the subclass that has the same signature as the one in the superclass, thus hiding it.
You can declare new methods in the subclass that are not in the superclass.
You can write a subclass constructor that invokes the constructor of the superclass, either implicitly or by using the keyword super.
More info on subclassing in Java
OOTB, Robolectric does not support Locales that well. Therefore, if your app is dependent on locales (which a lot of apps are if they are i18n'nd properly) this can be a royal pain. Long story short, I created my own ShadowFooGeocoder and ShadowFooAddress that allow me to simulate the locale I want. They're basically re-implementations of the existing shadows.
However, when I bind my class as such: bindShadowClass(ShadowFooGeocoder.class), this works great. At runtime, the correct shadow is returned. The problem is that I want to set up the simulations on this object and I'm not sure how. shadowOf(instance) where instance is an injected GeoCoder returns ShadowGeoCoder. I've tried working directly with the ShadowWrangler, but that also returns a ShadowGeocoder.
How can I get at my shadowed class that I've bound through the bindShadowClass(...) call so I can set my expectations (simulations)?
Note: This is a repost of the same question on the Robolectric group here. I posted here because my success rate of getting anyone to answer questions on the group is fairly low. I'm hoping for a better result here.
What I've basically done here is extend ShadowGeocoder like this:
#SuppressWarnings({"UnusedDeclaration"})
#Implements(Geocoder.class)
public class ShadowFooBarGeocoder extends ShadowGeocoder {
// implementation stuff
}
Then I would bind it using the bindShadowClasss(...) and when I retreive the shadow via the static shadowOf(...) call I get back a "ShadowGeocoder" which is an instance of ShadowFooBarGeocoder. I then cast it to that type and perform whatever work I need to.
In the source code of Activity.java, I see some methods bellow :
public View findViewById(int id) {
return getWindow().findViewById(id);
}
and the definition of getWindow method:
public Window getWindow() {
return mWindow;
}
But as the following rules:
Avoid Internal Getters/Setters
In native languages like C++ it's
common practice to use getters (e.g. i
= getCount()) instead of accessing the field directly (i = mCount). This is
an excellent habit for C++, because
the compiler can usually inline the
access, and if you need to restrict or
debug field access you can add the
code at any time.
On Android, this is a bad idea.
Virtual method calls are expensive,
much more so than instance field
lookups. It's reasonable to follow
common object-oriented programming
practices and have getters and setters
in the public interface, but within a
class you should always access fields
directly.
Without a JIT, direct field access is
about 3x faster than invoking a
trivial getter. With the JIT (where
direct field access is as cheap as
accessing a local), direct field
access is about 7x faster than
invoking a trivial getter. This is
true in Froyo, but will improve in the
future when the JIT inlines getter
methods.
so I want to know why android developers not access this mWindow object directly? If the JIT of the current android versions cannot inline the access, getWindow().findViewById(id) will costs more time than mWindow.findViewById(id), and findViewById is a rather frequently used method.
First: you can't access it because it's private.
Why is it private?
As you said, accessing members directly is faster. On the other hand, you are invoking a method that isn't very fast as it will lookup for some view in the view hierarchy. So using a method instead of a direct access will incur in a small overhead in terms of percentage of the total time that it would take to perform that task.
Anyway, I believe that the reason for this is encapsulation.
You are invoking something you don't own (that is the Android SDK). So, you shouldn't make any assumptions of whats happening "in the other side". Simply use this method and expect that it will return the view you want (or null if it doesn't exists).
Maybe the next version of android will use a different method to lookup a view, not calling getWindow(). If you use this method, they (Google/Android) can simply mark the method as deprecated and "forward" your invocation to the newest implementation. If you were calling directly getWindow(), maybe you would be looking for something that is no longer placed in there.
You can't access the mWindow property directly - it's private.
And I wouldn't care about the speed of findViewById, since you only need to call it once for every view in your layout in your onCreate() method and store the views in members of your activity. You do call findViewById only once per view, don't you? ;-)
However, if you really care about these things, you could call getWindow() for yourself, store it into a local variable and call findViewById on it directly. I wouldn't recommend this because all your performance increasements here are not worth the time and anyway will be obsolete with future versions of the JIT.
If you do this I would be very interested in the amount of microseconds you saved. :-)
We have a reason to smile now...
The android documentation which says to avoid internal getters and setters will change soon, supposedly progruard was added to Gingerbread platform which does a fine job of inlining accessor's, please refer to "Avoid Internal Getters/Setters" is bad advice and these two SO posts.
https://stackoverflow.com/a/6716573/892055
https://stackoverflow.com/a/4930538/892055