Keeping things short and simple, which is better for managing android click events when working with buttons?
Assigning it to an ID in the XML Construct lines?
android:id="#+id/ButtonEventName"
and working with it by detecting press event via Java?
Taken from the login activity template based in android studio:
Button mEmailSignInButton = (Button) findViewById(R.id.email_sign_in_button);
mEmailSignInButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
attemptLogin();
}
});
or assigning the button to an onclick method:
android:onClick="EventName"
the integrate Java side:
public void EventName(){}
Which is more effective and reliable and recommended when working with button events?
Both methods have their good and bad sides. I don't know which one is more effective though.
Using id + onClickListener is more complex code, but it gives you opportunity to do run-time check for errors. In your example that would mean additional null check.
Second approach is much simpler to read, but if you don't have EventName method app will crash
I prefer second one because it is simpler, and it is always easier to follow logic and find errors in less code.
I also have to add that while first solution does provide means of avoiding app crash, at the end that does not matter too much because if findViewById returns null you basically have same buggy, code that is in mismatch with layout xml and adding null check (that should be superfluous in final working app) just additionally pollutes the code.
Point 1 -
Creating it in code allow you to shield method access by making the method private, whereas doing it the xml way leads to exposure of the method.
Point 2 - android:onClick is for API level 4 onwards, so if you're targeting < 1.6, then you can't use it.
Otherwise as per my understanding, these 2 are similar.
It is really up to you, but keep in mind that android:onClick="EventName" will not work if you define it in an xml that will be inflated as part of a Fragment and you try to receive the button press on the Fragment itself. The onClick property only searches Activities for the method name you specified.
I would recommend you look into ButterKnife
Related
Despite its not best UX. I wonder what is the best solution to start several different Activity(Dialog) with different callback implementation. I assume starting each dialog needs to be from static fabric method with context.startactivity(dialog1). Each dialog looks exactly the same besides some title and message but callback for ok and cancel buttons are different. I want to separate implementation of dialog callbacks(ok, cancel) from generic dialog behavior. What if I can't pass actions while starting activity from static method, I don't find Bundle to fit this case.
How about this, create an enum for the dialogs.
Based on the enum you can either have the values for everything be in the enum itself or switch on the enum in your code at the appropriate places.
recommend creating different click listeners for the yes and no buttons.
In those click listeners you can switch(enum) and for each case have the specific business logic. OR create different click listeners and use a factory that will allocate the listeners based on the enum.
either solution works depending on how you want to code it. They both have their own pros and cons.
There is an AlertDialog.Builder class that you may be able to use depending on what your dialogs look like. There is also the dialogfragment class that you can extend to help out with the dialogs.
if you want to show the users several dialogs you will need some sort of queue that you populate with all the dialogs that you want to show and then show them one after another, IMHO, use different views and just replace the view in an activity so you can slide it in or animate it in somehow.
You can make them look like cards and then just change the text inbetween that way switching on the clicklisteners based on the type of the current view will be easy and you can even have the enums provide the views using the R.layout.layout_name as a value in the enum.
I know that is a lot and maybe some of it is unclear, Please ask questions and i will do my best to respond in a timely manner.
I have this ImageView which on clicked should Show toast and also making api on click of the image View, so I decided to use Debounce operator in Rx
but now thost is not visible on every click. below is the code
cartSubscriptionDecrement = RxView.clicks(holder.databinding
.cartQuantityLayout.ivDecreaseQuantity)
.debounce(1000, TimeUnit.MILLISECONDS)
.subscribe { next ->
cartQuantityEvent.onCartQuantityDecremented(cartSubscriptionDecrement!!)
}
I need to show toast on every single click of imageView.
I tried to have a separate onclick method for Image View but during debugging I found that the control is never coming to onclick method this is my another onclick method
How do I achieve this toast on every click while not making an api call in every click (make use of Debounce operator).
There are multiple ways to do what you're asking. I've included the simplest below, but will need to think more about potential side effects from using doOnNext.
The code for this example lives on Github here if you're interested in running the app. Just realized the package name is wrong, but the example will run just fine.
The most relevant code to the example is below. The key is that you'll need to debounce after you show the Toast rather than before.
RxView.clicks(image1)
.doOnNext(imageClickedEvent -> {
// Show toast every time onNext is called (this will also log to LogCat)
showToast();
})
.debounce(1000, TimeUnit.MILLISECONDS)
.subscribe(clickEvent -> {
makeApiCall();
});
I tried to have a separate onclick method for Image View but during debugging I found that the control is never coming to onclick method this is my another onclick method
I believe this is the case because RxClicks sets a listener on the ImageView, and that occurs after the framework sets the onClick listener and you can only have one OnClickListener on a View if I recall correctly. So what's happening is the RxView.clicks(imageView) is receiving the click event rather than the method you created separately.
You have to apply ".subscribeOn(AndroidSchedulers.mainThread())" to all RxBinding events, such as "RxView.clicks()"
I understand professionals use the former to tailor the onClick method to their exact specification, but cant I just use the onClick attribute and specify the same desired actions within a method.
i.e. [In xml file:] onClick="doSomething" & then
[in MainActivity.java:]
public void doSomething(View view){
//define and start intent
//Show a toast, etc
}
Why not just use the latter option? Thanks
Why not just use the latter option?
Go right ahead.
On bigger projects, it is unlikely that the activity will be managing the button directly:
You might be using fragments, in which case the fragment is more likely to manage the button than is the activity
You might be using MVP, MVVM, MVI, etc. GUI architectures, in which case some other "presenter" object is more likely to manage the button than is the activity
You might be using the data binding framework, in which case you might still be using android:onClick in a layout resource, but directing the event to something other than the activity (e.g., a fragment, a presenter)
And so on
Yes you can do so,both are doing the same thing but using the onClickListener is a better choice ,you can set the listener when you want that button to be active thus your Button and Activity are in cooordinaton.
If you use onClick in your xml file ,it will always call that method doesn't matter what is happening in your activity.
I am trying to learn android programming and I am stuck at one point, in terms of deeply understanding the concept.
So there is this code which listens the click event for a view (a button). Code is from a site by the way, and working just fine. But I am obsessed with understanding it to the nuts and bolts.
clearButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// do some stuff
}
});
I have questions in some different levels:
1. So the parent function (clearButton.setOnClickListener) is the event handler, as far as I can tell, which is trigerred when the button is clicked. And yet we are passing it an object's method, which, as far as I can tell, another event listener. Both of them are named as "ClickListener" so I am confused. Are two of them really event listeners?
2. Where did the View object (one which passed as the callback) came from? Is it implicitly created by the system? I have no such definition in my MainActivity.java file.
3. I clumsly tried to write it with parent function invoking another simple function which just displays an AlertDialog, but I was badly failed, since clearButton.setOnClickEventListener expects a View to be returned from callback (I think:)). Is there any other way to accomplish it or this is the only way setting an event listener to a view? Do I have to accept it the way it is and embrace it, instead of struggling with it :) I ask this only to understand the logic of the structure, code works just fine.
4. What is the view passed to the View.OnClickListener function? Is it the current view (I doubt it is)? What is the use case of the view passed to the View.
5. Where can I (or can I) review the code of the View.OnClickListener function to better understand it?
6. All this exercise trigerred another question in my mind about callbacks, but it is probably subject of another question altogether :)
It's a little bit hard to explain, but you are passing what you can treat as a function.
View is included in the Android Framework.
You can also set the onClick listener via the xml. Check this very helpful post.
From how I understand it, it's the view it is tied to. For example, it is an onClickListener for a button1, the view is referring to button1.
View.OnClickListener
...Okay. I think it would be good for you to go through tutorials first (I suggest udacity :D )
Not very definitive, but I hope this gives you an idea somehow. Happy Learning and Coding! Cheers! :D
my question has to do with using different layouts for different screen densities on the Android platform.
Let's say that I have four main.xml files (each in their respective folders for their corresponding screen densities: ldpi, mdpi, hdpi, and xhdpi) and let's say that they're all identical to start with. But let's say I want to get rid of some of the UI elements for the ldpi layout. How do I handle things on the Java side to avoid a null pointer exception when it tries to find that view in the ldpi layout on a ldpi phone? Should I just check and see if findviewbyid returns null and move on from there?
I realize that you're supposed to keep things uniform in your apps, but on occasion it just seems like it'd make more sense to just get rid of a convenient but otherwise unnecessary UI element. I love having the extra real-estate on these new phones, but if/when it comes time to make a ldpi layout, I'd rather not just cram everything in there when it'd look better just to get rid of some stuff, if that makes any sense!
It is a Good question. Null checking can be one of the solutions.
another solution is checking screen properties. look at this example:
public static boolean isTabletPC(Context context) {
boolean isHoneycomb = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB;
boolean hasLargeScreen = (context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE;
return isHoneycomb & hasLargeScreen;
}
This is handled the same way as handling any optional element. Check if it exists (not null) and handle accordingly. In case of a non-existent View, findViewById will return null and you can operate further on the View inside a if(null != view){} block or if there are multiple optional elements that can be grouped, you can use an instance variable.
HoneycombGallery demo gives an idea of how you can detect device properties using layouts (although in the demo, it is done for fragments, it can be applied for any View)
From api lvl 11 you would probably want to use fragments for that. This way your java code always deals with views that are definately there, and your layout can show (or not) certain fragments that take care of their own business.
I would advice against littering your code with checks for what kind of screen you have, and checking if a certain view might be in the screen.
If you look at figure one on the linked page, you see a clear example of what i mean: