Is there a way to make android studio perform automatic type casting for objects without the need to do that manually?
I don't think there's a way to do this automatically and IMHO this would be not that useful. There might be some cases where you don't want a cast (or a cast different to the one Android Studio suggests). If it would be done automatically you might not notice it it could lead to strange (i.e. unexpected) behaviour which is quite difficult to detect later.
What Android Studio can do for you: It can give you a warning and suggest a cast. For example, when you do a findViewById() call and want to assign the result to a View object you do something like this:
Button btn = findViewById(R.id.button);
Android Studio will highlight the line because you need to cast the returned View object to a Button.
By moving the cursor to the line and pressing Alt+Enter you can select the option "Add cast.." and it will insert the cast for you:
Button btn = (Button) findViewById(R.id.button);
Related
Why is there so much casting in the Android code?
Almost half of my code constantly consists of casts like:
EditText yourEditText= (EditText) findViewById(R.id.yourEditText);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
Is there some better way to approach this? (especially a way you can detect where you did go wrong before runtime)
Because if you want to assign a supertype to a specific subtype variable, you need to downcast it to the actual type. Much of the Android framework is from an era before Java generics was available.
Is there some better way to approach this?
If you only need the View from a findViewById() return, make the variable type a View.
You can also use generics to hide the casts. For example:
public <T extends View> T getView(#ResInt int resId) {
return (T) findViewById(resId);
}
This way you can assign like
EditText yourEditText = getView(R.id.yourEditText);
and the correct type is automatically inferred.
especially a way you can detect where you did go wrong before runtime
It's still runtime and you'll get ClassCastException if R.id.yourEditText is in fact not an EditText.
For getSystemService() there's already a method like that in API level 23. Implementing this pattern for older API levels is left as an exercise to the reader :)
It's mostly casting errors when you Replace in the layout file a LineairLayout -> RelativeLayout and forget to do it in the code. And suddenly everything breaks at run time while my editor does not show any errors and the code just compiles
Note that Android Lint will detect many errors like this and will report "Unexpected cast" errors.
I am trying to create a Live-Template in Android Studio that will somewhat speed up creation of findViewById(...)
Part of it is self-learning, and part is curious in creating such live-templates.
I want to be able to type in the following...
Button find + (enter)
...and that should create something like this...
Button btnAdd = (Button) findViewById(R.id.btnAddition);
My current implementation has issues...
...and these issues stem from the use of completeSmart(). Whenever you use completeSmart(), the template ignores everything after that call and ends editing.
For example, If I moved the CAST named-variable up one slot (above ID), then the cast would be automatically filled out and it would not let me easily edit ID anymore. Same as below picture, but without btnAddition. Just ...findViewById(R.id.);
With my current setup, I have CAST on the very bottom so I can easily edit all of the named-variables; however, the use of completeSmart() does not let the template end (Place the cursor by the $END$ marker - Line 29 in the picture below) when I am complete.
Instead, it places the cursor right after the cast, like so...
...when it should be placed on the start of the next line. This template does put a new line in, but the cursor does not go there at the end. Why?
So I want this...
1 ) Since I already but in Button, I want to cast to be Button. I should not have to type in in twice!
you should use method typeOfVariable()
you can change like this:
I use eclipse for android development, and I find it very annoying that every time I create an activity or add new views to my activity, I need to create the references to views in my layout. I am looking for some kind of eclipse plugin that can generate the calls to findViewById() from the layout. I couldn't really find anything because I didn't know what it would be named. It would be very useful and time saving if that kind of plugin existed.
EDIT: The answers you gave are great. Can these tools also add more references to an existing activity so I don't have to manually do that when I add a view to the layout?
You can use https://github.com/JakeWharton/butterknife library for View Injections.
You can also get eclipse plugin https://marketplace.eclipse.org/content/lazy-android for the same.
But the ButterKnife library is frequently being contributed by android devs than the mentioned eclipse plugin. With this library, you can also avoid instantiating listeners yourself by just using like,
#OnClick(R.id.submit) void submit() {
// TODO call server...
}
For View injections, simply,
#InjectView(R.id.user) EditText username;
#InjectView(R.id.pass) EditText password;
So, it will compile as,
username = (EditText) findViewById(R.id.user);
password = (EditText) findViewById(R.id.pass);
Try the morcinek code generator. Its really simple to use.
This are the steps to install the plugin:
http://tmorcinek.wordpress.com/2011/11/30/eclipse-plugin-for-automatic-generation-of-activity-code-from-xml-layout-file/
After install process you may want to configurate a package to get the classes built by the generator, on the IDE -> Window -> Preferences on Bookmark Android Code Generator you can change that parameter.
The plugin does need a better interface for custom activities, still you could get the code, its really simple to make the changes you need, at least the inline listeners.
This solution doesnt work to modify classes you already have, that would be a really good improvement... i'll give it a try in a couple days with more time.
Maybe this question has been ask already, but could not find any answer for almost 2hours of internet search.
There is a graphical UI designer wich is coming along with the last android SDK.
Looks pretty cool and well done.
Nevertheless I * cannot find how to attach an event to the control through the graphical editor.
Of course I can add it manually into the xml, but in that case, what's the purpose of having such tool without that function ?
I mean all the other SDK I had in other languages always include that function.
I've also not been able to find doc about how to use this tool. Quite sad...
Thanks
If you want to add a click event handler, select the button (widget) in the GUI that you want to listen for, and look for the property onClick. Enter the name of the method you want to call when the user clicks on that widget, like.. onMyButtonClick
Then add the method to your Activity
public void onMyButtonClick(View v) {
// I heard the button click
}
The GUI builder is getting there, and is not yet as easy to use as the one in XCode, but it's not hard when you get used to it.
Is it somehow possible that instead of:
Button btnNextWord = (Button) this.findViewById(R.id.btnNextWord);
Eclipse automatically generates for me something like:
Button btnNextWord = this.btnNextWord;
or
Button btnNextWord = R.id.getBtnNextWord(this);
??
No, because what you're doing in requesting a reference to a child element that has a certain name and Eclipse isn't actually loading in the layout xml so it can't know what is in it.
I know this is a very late response but it might help someone who read.
You can use the android annotations library for doing something similar to what you want.
As you can see on their page, you can write a field in the code like this:
#ViewById
ListView bookmarkList;
The library will findById an item with id R.id.bookmarkList and cast it to ListView.
Or you can use the annotation like this
#ViewById(R.id.myTextView)
TextView someName;
if you want to give a better name to the field.
DISCLAIMER:
I never used the library so I'm not sure whether you can use just that annotation or you're bound to use their whole set of annotations.