Im looking through a project here and it has a way of using onClick that is different to what ive seen any other time.
Usually you set the listener for the button during onCreate or whatever.
Here in the activities xml it has android:onClick="navigateToUrl". Then this seems to kick off the method navigateToUrl in the classes code.
Im just wondering what is the difference between the two methods?
They work the same way. With the xml version, the framework adds an onClickListener during inflation that uses reflection on the Context its called from looking for a function with that name, and calls it. So its slightly less efficient, but not enough to really get worried about. The big advantage is a less cluttered onCreate, the big disadvantage is that to figure out what a view does when clicked you have to read xml rather than code. Which you use is a matter of personal preference. I'm currently in the explicit onClickListener group, because I prefer not to have behind the scenes magic.
For the latter, you need to keep a public method always. If you do not want to keep your method publicly visible, you would prefer to have a listener implemented.
Related
I'm new to android development and I see there are 2 different ways to make a button perform a specific task.
The 1st way is to have a setOnClickListener() within your onCreate function.
The 2nd is to create a separate method in its Activity page and call it using the activity's XML using android:onClick="thisFunction"
I have always found it easier to call functions using android:onClick in the XML.
Would this way make the buttons perform slower?
When would you experts prefer one way over another?
In my opinion, it's always better to set the onClick in the code, since the xml way only works well with activities. When you try to do that with fragments, it will ask you to choose an activity to handle the onClick() from the xml. Imagine having a single activity app, with lots of fragments, and having all of it's onClick() methods spread across the MainActivity code. It's quite a mess.
Regarding performance setOnClickListener() vs onClick() inside xml, I think it's pretty much the same nowadays.
I know how to use the View.isInEditMode method.
What I don't fully understand is when should I use it. That is, what should I prevent from running in EditMode.
There are the obvious cases, where the custom view does all kind of crazy things like DB access, networking, threads etc. where it is clear you should avoid them while in EditMode.
I created a several custom views that don't do anything of the above. They only use the regular drawing API, or load resources such as drawables.
When running on device they look exactly as expected, but inside the layout designer they either don't look as they should or even just fail to render due to some mysterious exception (Usually NullPointerException).
So, are there any limitations in EditMode on these APIs?
Custom views should work just fine as long as they only call parts of the view framework, not any application code. That's a good separation to have for views anyway: they should contain view state, not app logic.
Typically you only have to use View#isInEditMode if your custom view is trying to access classes from its constructor (or measure or draw methods) where those calls for example try to access application framework code like say the FragmentManager. In that case you skip those calls with View#isInEditMode.
It's hard to say more about what the problem you're seeing is without knowing more. In particular, what exactly is the NullPointerException you're seeing (full stack trace).
It could also be a layoutlib bug. Try switching the render version (in the render toolbar) to a different version.
I am using setContentView(R.layout.main) to switch the views in the same activity. I am calling some asynchronous task and populating the data on the main layout file after that I am changing the view by calling setContentView(R.layout.main) method.
I came to know that we should not use setContentView method multiple times for same activity. Though it is working fine for me.
Can anyone explain why we should not use setContentView method multiple times for the same activity to change the views?
Will it create any memory related exceptions? Could someone please clarify?
I think switching Views is not a good idea, because android platform already have strong framework to handle the transition in between the views and maintaining the state of each view associated with the Activity its always better to stick with the existing framework instead of thinking of some complex implementation that you have to go through to do all these things. If you do not need any of these things to taken care in your application and if only if you have only two or three screen in your entire application you can try switching the views. That even based on how your views are structured if you have complex logic and lot of data needed to create these views this wont be a good way of doing it.One more thing if you are adding more views say functionality to your application the load that need to be handled by the Activity will go high. In this case you will be declaring and initializing all views inside that particular Activity so maintaining all these views instances is heavy. If you want to know more about the Activty and Task kindly refer this link
Well every time you call setContentView() you'll have to find all the layouts again besides that I think you "can" do it. But as discussed here this is ill adviced as it clearly goes against the android guidelines. Also Commonsware have some very important points here one of the most important being that you will be prone to leak memory as you forget to clean up stuff from your views etc. which Android normally would handle for you.
In short you should follow Android guidelines and use Fragments or start a new Activity.
According to the developer docs setContentView(int layoutResID) is used to
Set the activity content from a layout resource. The resource will be inflated, adding all top-level views to the activity.
In best practice this method is used to Inflate your Activity layout on start up. This does not mean that it will cause issues in the future if you keep using this method. To quote a answer in this question
The setContentView on your Activity actually calls the setContentView on the Window used by the activity, which itself does a lot more than just inflating the layout.
I suggest that you find a alternative way to switch layouts like using a ViewPager with Fragments or some other Tabbing approach but in the end it all comes down to what you want to do.
This question might also give you what you're looking for.
With so many ways of implementing an OnClickListener within Android, I'm wondering whether there's a best practice or a more recommended way of doing it over the others (ie: I remember reading certain ways require more memory than others)?
At the moment I know of four ways to implement the OnClickListener, these are:
Make your Activity implement an OnClickListener interface.
Inner Class OnClickListener.
Inline Class OnClickListener.
Use android:onClick attribute in XML definition of a Button.
Out of the four options I'm leaning towards the XML implementation as it seems cleaner, can anyone else give their opinion?
I don't know regarding memory efficiency, but Here's my approach.
I don't like it, It requires multiple if-else (or switch) inside your onClick if you have multiple buttons
I use this if the 3rd option causes my method, for example onCreate() to be too big and messy
My favorite. it allows you to find out what each button does very easily, but I use it usually if its onClick isn't too long, to keep the code readable
I hardly use it, it keeps the code cleaner, but I'm not used to this one, since I don't use it in Java's SWING.
But in the bottom line, like #Lazy_Ninja said, it all comes down to taste. All 4 of them works.
I think what matters, when choosing, is keeping the code clean and readable.
Well it depends. At first I used to like the number 1(Make your Activity implement an OnClickListener interface) because the source look neat that way. But at the end I settled with 2.Inner Class OnClickListener, because I found it more easier to read and more easier to implement, especially if you use eclipse and know the shortcuts of auto completion.
At the end I think it depends on taste.
Will the performance be any better using onClick? If I use onClick I do not have to set an android:id (also avoid's a new View.OnClickListener), does this improve performance at all? Or is the same effect of a findViewById occuring behind the scenes?
This page gives both methods as an option but little guidance on any benifit.
http://developer.android.com/reference/android/widget/Button.html
Here's a blog post where they deem onClick as "easier" and an "improvement" for post 1.6 applications;
http://android-developers.blogspot.com/2009/10/ui-framework-changes-in-android-16.html
This new feature reduces both the
amount of Java and XML you have to
write, leaving you more time to
concentrate on your application.
I believe that the inclusion of android:onClick has been a very bad idea.
You are coupling presentation with logic
Unless you are using a plugin that supports it, you will have to remember to refactor the xml file if you decide to change your method name
It's just not clear the relationship between a button in your xml and a method in your activity that reacts to the click events unless you explicitly see it defined in your Java file. With the android:onClick approach you can even forget that you have a button in your layout or which is the method that is handling its onClick event.
I would suggest you stick to defining your OnClickListeners programatically and keep a strict separation of concerns, as Corey Sunwold pointed out in his comment.
I am trying to think about how to test this.... But I believe there is no performance difference between the two, they are just different interfaces for the same thing.
I use android:onClick when I just need my Button to be clickable.
If I need to do something else to the Button, for example enable/disable it, I would use setOnClickListener() as mgv said.
Also remember that android:onClick doesn't work in Android 1.5.
You might consider using an onTouchListener instead. I've found it to be faster, particularly if you want the action to occur on press as opposed to release.