I found a material design widget for android and want to implement EditText with onClick to set the text with DateDialog.
But from this issue of the lib : https://github.com/rey5137/material/issues/144
I can't figure it out, how to set onClick Listener on Material EditText. I have same issue with this lib, and based on my experiment, implementing onFocusChange is not solving the problem
The author just say the EditText component is extended from FrameLayout, and get the id with findviewbyid method.
That means the library is not that good, but to answer your question, seems he means that his widget is something like this
<FrameLayout>
<!-- something else -->
<EditText></EditText>
</FrameLayout>
when you set the onClickListener on the widget, actually you have just set the onClickListener on the FrameLayout. When you actually click the on it, the real EditText get the touch event and processed it, therefore the touch event is not passed to the FrameLayout as it has already been handled.
Related
I realize that a similarly-worded question has been asked before, but this is different. I am pretty new at developing android apps and I have three questions regarding the difference(s) between the android:onclick="" XML attribute and the setOnClickListener method.
What are the differences between the two? Is the difference between the two implementations found at compile time or run time or both?
What use cases are favorable to which implementation?
What difference(s) does the use of fragments in Android make in implementation choice?
Difference Between OnClickListener vs OnClick:
OnClickListener is the interface you need to implement and can be set
to a view in java code.
OnClickListener is what waits for someone
to actually click, onclick determines what happens when someone
clicks.
Lately android added a xml attribute to views called android:onclick,
that can be used to handle clicks directly in the view's activity
without need to implement any interface.
You could easily swap one listener implementation with another if you need to.
An OnClickListener enable you to separate the action/behavior of the click event from the View that triggers the event. While for simple cases this is not such a big deal, for complex event handling, this could mean better readability and maintainability of the code
Since OnClickListener is an interface, the class that implements it has flexibilities in determining the instance variables and methods that it needs in order to handle the event. Again, this is not a big deal in simple cases, but for complex cases, we don't want to necessary mix up the variables/methods that related to event handling with the code of the View that triggers the event.
The onClick with function binding in XML Layout is a binding between onClick and the function that it will call. The function have to have one argument (the View) in order for onClick to function.
Both function the same way, just that one gets set through java code and the other through xml code.
setOnClickListener Code Implementation:
Button btn = (Button) findViewById(R.id.mybutton);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
myFancyMethod(v);
}
});
// some more code
public void myFancyMethod(View v) {
// does something very interesting
}
XML Implementation:
<?xml version="1.0" encoding="utf-8"?>
<!-- layout elements -->
<Button android:id="#+id/mybutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click me!"
android:onClick="myFancyMethod" />
<!-- even more layout elements -->
Performance:
Both are the same in performance. Xml is pre-parsed into binary code while compiling. so there is no over-head in Xml.
Limitation:
android:onClick is for API level 4 onwards, so if you're targeting < 1.6, then you can't use it.
I'm shocked nobody talked about this but be careful, although android:onClick XML seems to be a convenient way to handle click, the setOnClickListener implementation do something additional than adding the onClickListener. Indeed, it put the view property clickable to true.
While it's might not be a problem on most Android implementations, according to the phone constructor, button is always default to clickable = true but other constructors on some phone model might have a default clickable = false on non Button views.
So setting the XML is not enough, you have to think all the time to add android:clickable="true" on non button, and if you have a device where the default is clickable = true and you forget even once to put this XML attribute, you won't notice the problem at runtime but will get the feedback on the market when it will be in the hands of your customers !
In addition, we can never be sure about how proguard will obfuscate and rename XML attributes and class method, so not 100% safe that they will never have a bug one day.
So if you never want to have trouble and never think about it, it's better to use setOnClickListener or libraries like ButterKnife with annotation #OnClick(R.id.button)
Simply:
If you have android:onClick = "someMethod" in xml, it looks for the public void someMethod in your Activity class. OnClickListener is called right from your Activity and it is linked to some particular View. For example someButton.setOnClickListener and in the code below is said what has to be done when someButton is pressed.
Hope it helps :)
As said before: they both are a way to add logic in response to an event, in this case a 'click' event.
I would go for a separation between logic and presentation, just like we do in the HTML/JavaScript world: Leave the XML for presentation and add event listeners by means of code.
There are a couple of reasons why you might want to programmatically set an OnClickListener. The first is if you ever want to change the behaviour of your button while your app is running. You can point your button at another method entirely, or just disable the button by setting an OnClickListener that doesn't do anything.
When you define a listener using the onClick attribute, the view looks for a method with that name only in its host activity. Programmatically setting an OnClickListener allows you to control a button's behaviour from somewhere other than its host activity. This will become very relevant when we use Fragments, which are basically mini activities, allowing you to build reusable collections of views with their own lifecycle, which can then be assembled into activities. Fragments always need to use OnClickListeners to control their buttons, since they're not Activities, and won't be searched for listeners defined in onClick.
If you have several buttons using only one method, I suggest doing it in java. But if you have a button with one specific method, onClick in XML would be better.
It's more convenient to always use android:onClick attribute unless you have a good reason not to, for example, if you instantiate the Button at runtime or you need to declare the click behavior in a Fragment subclass.
I think main difference between them is:
OnClick: When you click on the button with your finger.
OnClickListner: It is may be a wider choice that be implemented in various codes.
For example when you type url "ymail.com", yahoo finds your username and your password from your browser and enable click state button to open your mail. This action should be implemented only in onClickListener.
This is my idea!
Its possible to have a listener to all buttons without setting the onClickListener in each button across all activities? and without making a extends button with the listener already set.
No. Each view has to be told what to listen to. You can specify it in xml if you prefer with the onClick attribute, but you'll still need to specify it on each object.
If all the buttons are doing the exact same thing, you can include that in the List kind of a layout and have one button with just one onCLick() event
For my project I need a functionality to dynamically add and remove views(textedit or buttons, etc).
I saw this similar functionality in Android "Add Contact" screen, where plus button add new fields and minus button delete the fields.
I found that EditContactActitivity.java is the file behind "Add Contacts".
I tried to find the methods that are called when plus or minus buttons are pressed but unable to find it, seems like "Add Contact" code is spreaded over multiple files. I am having difficulty understanding Android source code because documentation is unavailable.
Any advice?
You can add and remove views by calling .add() or .remove() on the reference to your main layout and passing the view you wish to add or remove;
Here is a simple example of an onCreate method that demonstrates adding and removing a button:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout myMainLayout = (LinearLayout)findViewById(R.id.yourMainLayout);
Button b = new Button(this);
//you can have some b.setXXX calls here to set text, view, click listeners etc...
myMainLayout.add(b);
//to remove
myMainLayout.remove(b);
}
I would consider researching Visibility of views rather than going through all this trouble. For example. I have an app where I have a 'record' entry screen that is relatively simple that appears as a Dialogs content. A few views/viewgroups are currently using visibility of gone, to not appear at all. If the user edits the record to add more detail, I launch an Activity that uses the same xml layout, but instantiates some of the currently 'gone' views and changes their visibility to 'visible'.
It is programmatically easy to toggle a view's visibility so I think it is really the way to go.
The only limitation I'm aware of here, would be the views order or position.
lets assume i have a LinearLayout , horizontal that contains a TextView and afterward a Spinner or another clicable TextView or an EditText.
I want that a click on any part of the line (if the layout has padding then the layout area as well!) will deleage the onTouchEvent to the Right part of the layout (EditText, TextView or Spinner) as if they were clicked themselves.
Doing it myself will require me either create my own versions of those widgets (too much work for little effect :-( ) or putting listeners on many items for the touch events and delegate them. I'm pretty sure Android has some methods or properties to do that, just didn't see any so far.
Can anyone help ?
I had to do something similar to this a while back, and ended up writing my own delegate and assigning the onclicklisteners for all of the components in my layout to that delegate. It's cumbersome, but not too painful to implement, and it turned out well.
Point being, I didn't see anything in the API to handle that sort of thing. The only other thing I might offer is that it is certainly possible to assign an onclicklistener to a component and simply send the event to another component's onclicklistener like so:
thislinearlayout.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
getOtherComponent().performClick();
}
});
You can do the same thing with touch listeners.
I would like to implement a ListView, which I can do no problem w/ my cursor. Right now depending on which row you click on it takes you to a new activity based on the information pressed on that row (just like it should, and as expected). I would like to have a button however to delete the row, so a user can press any part of the row to launch the new activity, but if they press the button on that row, it deletes the row (or launches a delete activity/function).
If you can look # DroidRecord, they have a similar layout as I am looking to achive.
Thanks!
Chris.
As Mariano Kamp said, adding buttons to a row will make it "untouchable", but in my experience, this problem goes away if you set these properties on the buttons:
android:focusable="false"
android:focusableInTouchMode="false"
See also How to fire onListItemClick in Listactivity with buttons in list?
Another possible workaround - you can use an ImageView instead of the button, and set the ImageView's onClickListener (For example, when you're inflating the cell view).
ImageView is not focusable so it doesn't prevent OnListItemClick() from being dispatched, and when you click on the image only the image's listener fires.
what is your question? How to add a button to a list row?
Very simple, just as you expect it will be added to the row's layout.
Unfortunately though that will also make the whole row "untouchable". The Google developer I asked said that this is by design (as far as I remember), and that you should use TouchDelegate to cope with this. As there are no samples, not even in the android source, and only very thin documentation that didn't work for me
Anyway, it seems that not many applications use a button in the list row. I only know about mine (newsrob, see Articles List) and the Alarm clock. Maybe you could use a context menu?
Otherwise the ugly solution would be to add to call setOnClickListener() on your row view in the getView method.
Cheers
It's not the answer to your question, but the long-click/tab is generally the place to pop up a context menu and put extra actions, like delete. You can read how to do it here: How do you implement context menu in a ListActivity on Android?
I would like to thank BoD for its hint on removing the focusable state to the button(s), it saved my day.
But for information, since the button is no more focusable - state_focused on < selector > xml - , its design won't display anymore to the user.
Those buttons will still get the state pressed though, but also when clicking anywhere else on the parent view (anywhere BUT another button) !
Keep that in mind, it could not be a good solution for your own case, but it does work well.
I tried this to be able to click on the buttons but it didn't work for me
android:focusable="false"
android:focusableInTouchMode="false"
so what I did was to change the activity layout to scrollview and then add a linerLayout inside of it.
after that you can add buttons to the layout and each button will be clickable.