I'm trying to understand what is View.OnClickListener().
I have read this site: http://developer.android.com/reference/android/view/View.html, but I cannot understand who is the client and who is the listener.
Please explain in details. Thanks in advance.
From docs:
Interface definition for a callback to be invoked when a view is
clicked.
reference
Simply said: So when you implement this, you are able to handle click events for your Views - all widgets as Button, ImageView etc..
When you implement this you have to implement onClick method. When you click on some View, this method is immediately called.
public void onClick(View v) {
switch(v.getId()) {
// do your work
}
}
But don't forget that you have to register your OnClickListener for specific widget
someButton.setOnClickListener(this);
Most likely you need to learn Android basics and i recommend it to you.
Note: You can use Listeners also as anonymous classes
This is an Interface to implement for classes which want to get a notification if a View element got clicked.
For instance:
public class FooActivity extends Activity implements View.OnClickListener {
public void onCreate(...) {
View v = findViewById(...);
v.setOnClickListener(this);
}
public void onClick(View v) {
// method which is invoked when the specific view was clicked
}
}
Related
I'm developing a chat application. There are chatrooms and inside these rooms there are messages. When a user clicks on the chatroom I want to go to another activity where messages are displayed.
In my adapter class, I have this onclick() method written in onBindViewHolder where I would normally make an intent along with the data I need. Something like this:
#Override
public void onBindViewHolder(#NonNull ChatRoomAdapter.ChatRoomViewHolder holder, final int position) {
holder.mRoomTitle.setText(mChatRooms.get(position).getTitle());
holder.mRoomDescription.setText(mChatRooms.get(position).getDescription());
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(this, NextActivity.java);
intent.putExtra("test", mChatRooms.get(position).getTitle());
}
});
}
But I'm trying the MVP architecture design and I want to pass roomTitle to the Interactor/presenter class of my next activity. How can I achieve this?
In RecyclerView adapter you need to pass a onItemClickListener in the adapter.
Refer to the Google's MVP sample - > https://github.com/googlesamples/android-architecture/tree/todo-mvp/
Especially refer the TaskItemListener in TaskFragment. They are doing the same thing what you are trying to achieve. In this they open Task details (new activity) from List of tasks(recyclervView).
/**
* Listener for clicks on tasks in the ListView.
*/
TaskItemListener mItemListener = new TaskItemListener() {
#Override
public void onTaskClick(Task clickedTask) {
mPresenter.openTaskDetails(clickedTask);
}
#Override
public void onCompleteTaskClick(Task completedTask) {
mPresenter.completeTask(completedTask);
}
#Override
public void onActivateTaskClick(Task activatedTask) {
mPresenter.activateTask(activatedTask);
}
};
And then pass it to adapter of Recycler view
mListAdapter = new TasksAdapter(new ArrayList<Task>(0), mItemListener);
And on item click
rowView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mItemListener.onTaskClick(task);
}
});
Follow this article to know more about MVP.
You can do one thing that creates a method in the next activity's presenter
setRoomTitle(String roomTitle);
Whenever, you click and send intent and get in next Activity call that
mPresenter.setRoomTitle(roomTitle);
Is it make sense? So, you can sent your title or other data in next activity's presenter.
Let me know if you have more query then.
Thanks.
Happy coding :)
The adapter is only responsible for binding the view and the data together. Your business logic should go into the controller class which is your Activity or Fragment containing the RecyclerView. This way you can reuse it for any other Activity, and it also makes debugging/maintaining a lot easier since you know that your logic code is in one place.
But how do you link both together? It's simply done by implementing a callback interface and passing it to your adapter. A callback interface could be something like this:
interface OnClickCallback{
void onClick(String title);
}
Just add a member variable to your adapter class called mCallback for example and affect a reference to it through the adapter constructor or through a setter method.
You can either make your Activity implement this interface and pass itself as the reference or you can instantiate it in an object and pass it instead.
Then just write this:
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mCallback.onClick(mChatRooms.get(position).getTitle());
}
});
The onClick method should create an intent to your new Activity with an extra containing the title. In your new Activity's onCreate method, you can retrieve the title value by using:
String title = getIntent().getStringExtra(YOUR_TITLE_KEY_HERE);
I have trouble understanding this code. I get that findViewById will get the button widget and then it'll cast it. Then, it's going to use the button to call the setOnClickListener method. However, I don't know what is that argument being passed into the setOnClickListener and I have never seen code like that before. How is it that it creates a new object but is able to create a method of its own within another method's argument? Would be great if someone could explain that. Also, what type of object is the setOnClickListener method taking in?
btn = (Button)findViewById(R.id.firstButton);
btn.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
tv.setText(months[rand.nextInt(12)]);
tv.setTextColor(Color.rgb(rand.nextInt(255)+1, rand.nextInt(255)+1, rand.nextInt(255)+1));
}
});
It works like this. View.OnClickListenere is defined -
public interface OnClickListener {
void onClick(View v);
}
As far as we know you cannot instantiate an object OnClickListener, as it doesn't have a method implemented. So there are two ways you can go by - you can implement this interface which will override onClick method like this:
public class MyListener implements View.OnClickListener {
#Override
public void onClick (View v) {
// your code here;
}
}
But it's tedious to do it each time as you want to set a click listener. So in order to avoid this you can provide the implementation for the method on spot, just like in an example you gave.
setOnClickListener takes View.OnClickListener as its parameter.
This is the best way to implement Onclicklistener for many buttons in a row
implement View.onclicklistener.
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
This is a button in the MainActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bt_submit = (Button) findViewById(R.id.submit);
bt_submit.setOnClickListener(this);
}
This is an override method
#Override
public void onClick(View view) {
switch (view.getId()){
case R.id.submit:
//action
break;
case R.id.secondbutton:
//action
break;
}
}
That what manual says about setOnClickListener method is:
public void setOnClickListener (View.OnClickListener l)
Added in API level 1 Register a callback to be invoked when this view
is clicked. If this view is not clickable, it becomes clickable.
Parameters
l View.OnClickListener: The callback that will run
And normally you have to use it like this
public class ExampleActivity extends Activity implements OnClickListener {
protected void onCreate(Bundle savedValues) {
...
Button button = (Button)findViewById(R.id.corky);
button.setOnClickListener(this);
}
// Implement the OnClickListener callback
public void onClick(View v) {
// do something when the button is clicked
}
...
}
Take a look at this lesson as well Building a Simple Calculator using Android Studio.
its an implementation of anonymouse class object creation to give ease of writing less code and to save time
It works by same principle of anonymous inner class where we can instantiate an interface without actually defining a class :
Ref: https://www.geeksforgeeks.org/anonymous-inner-class-java/
I have a question that seems simple but I cannot figure out what is the best practice for that :)
What is the best practice to access from a View, a method on the Activity that launched the View?
For example, I have an Activity with a layout that contains a Button and a Textfield. I want when I click on the Button, to call a method on my Activity that update the Textfield with some value. I come with multiple solutions:
1 - Inner class for the OnClickListener directly on the Activity so I can the method of the Activity with MyActivity.this.updateTextField() on onClick method
2 - Outer class for the OnClickListener, on my onClick method I can do: ((MyActivity)getContext()).updateTextField()
3 - Reference the Activity on my OnClickListener class when I instantiate it:
myButton.setOnClickListener(new MyOnclickListener(MyActivity));
I don´t want solution 1 because I don´t like that much inner class and I want reusable code. Solution 2 seems good but can produce error on runtime if my context is not an activity. Solution 3 seems good also but "heavy".
What is the best practice on Android to tell from the View to its Actitity that something needs to be done on the Activity?
Thanks!
implement activity with onclickListener and add unimplemented method onclick
just check for the view to see which button is clicked incase you are using multiple buttons
Although I mostly find myself end up with inner classes, there are other options.
You can create an interface like the following and let your activity implement it:
public interface UpdateableTextField {
public void updateTextField();
}
Now let the Activities that you want implement this interface.
Now, create a class that implements View.OnclickListener and set the constructor to get UpdateableTextField as a parameter:
public class MyListener implements View.OnclickListener {
UpdateableTextField updatable;
public MyListener(UpdateableTextField updatable) {
this.updateable = updatable;
}
#Override public void onClick(View v) {
// do some stuff
updateable.updateTextField();
}
}
And last, in the Activity:
public class MyActivity extends Activity implementes UpdateableTextField{
#Override public void onCreate(Bundle savedInstanceState) {
// usuall stuff
MyListener listener = new MyListener(this);
someView.setOnClickListener(listener);
// other stuff
}
#Override public void updateTextField() {
// well, update the text field :)
}
}
public class Menu extends Activity {
/** Called when the activity is first created. */
public void onCreate(Bundle icicle) {
//myIntent.setClassName("hello.World", "hello.World.mybuttonclick");
// myIntent.putExtra("com.android.samples.SpecialValue", "Hello, Joe!"); // key/value pair, where key needs current package prefix.
//startActivity(myIntent);
//Button myButton = (Button) findViewById(R.id.my_button);
super.onCreate(icicle);
setContentView(R.layout.main);
}
public void updateLayout(){
Intent myIntent = new Intent(Menu.this, mybuttonclick.class);
startActivity(myIntent);
// TextView sayHello = (TextView) findViewById(R.id.Hello);
}
}
Hey guys, I am a new android java student and we have to develop a simple hello world app.. I am finding some difficulty getting my onClick() activity to work, using android:Onclick in xml.. what i am trying to do is change the content view do display a simply a different layout and saying hello.. i am using setContentLayout to do this, every time i click said button tho the android app crashes out.. am i doing something wrong?
regards,
Stefan
When you set a click listener in xml you must have the method defined inside the activity you are clicking in. Lets say you set the onClick in xml to be "buttonClicked", you must create a method looking exactly like the one below.
public void buttonClicked(View view)
{
//Your code here
}
The thing to notice is that the method is a public void with only a single parameter of type View. XML defined click listeners must be like this to work. The view object in the example above is the view that was clicked.
You update layout function needs to read
public void updateLayout(View view)
In response to your question, there are a number of things that are issues causing the complication that you described. Let it first be said, that you don't have to do anything any particular way, provided that you make concessions for certain things. Android is a very flexible platform and Java, as an OOP language allows you to do things that many non OOP languages do not.
Whenever you create a "clickable" item, like a Button, if you want to have your program respond, you must have something "listen" to it. This is known as a Listener. In your case, you are looking for an OnClickListener. The OnClickListener does not have to be a part of the Activity necessarily. It just has to be a class that implements View.OnClickListener. Then, you have tell the setOnClickListener() method of the Button who its listener is. The following example shows what is necessary without your declaration in XML (but it is important).
class Menu extends Activity implements View.OnClickListener
{
public void onCreate(Bundle icicle)
{ setContentView(R.layout.main);
Button btn = (Button)findViewById(R.id.BUTTON_ID_AS_DEFINED_BY_YOUR_XML);
btn.setOnClickListener(this);
}
public void onClick(View view)
{ int id = view.getId();
if (id == R.id.BUTTON_ID_AS_DEFINED_BY_YOUR_XML)
updateLayout()//Do your Click event here
}
public void updateLayout()
{ //updateLayout code...
}
}
Something that needs to be noted is the OnClick() above. Every OnClickListener must use the same signature as theOnClick() That means itmust have the same return and same arguments even if it has a different name. For what you are trying to do (in XML), you have set your android:OnClick to updateLayout. This means that `updateLayout() must be declared as follows:
public void updateLayout(View view)
Now, getting the update method to actually work: While you provide your code, we don't actually know what errors you are getting. It is always much easier to solve a problem if we have a copy of the Logcat output that includes the error you are receiving. Once, we have that we can target your error specifically and I can edit my answer to include what you may additionally need.
FuzzicalLogic
So, I am again, asking a very basic question. I apologize for my ineptness but I guess I read the given tutorials on these topics poorly. My question is as follows:
I would like to use a "listener" pattern to handle button presses on my GUI. I believe an onClickListener is what I need to use to handle these button presses. However, I'm not sure if I should be creating and handling events that occur after the GUI is created within an onCreate method. The following code is within my onCreate method for one of my Activities:
View.OnClickListener upDownListener = new View.OnClickListener()
{
#Override
public void onClick(View v)
{
if(v == (upOneButton))
{
Log.d("OptionSelect", "Up One Button Pressed.");
ops.getOptionList().get(0).incrementProbability(4);
} . . .
This method being called updates some GUI text with a different number. It is being called, but the GUI isn't responding. I imagine this has to do with my attempt to use it within the onCreate method.
In short, what is a good and simple way to deal with user events within a GUI and where should this occur?
Thank you so much.
EDIT: Log.d() does in fact get called. Also, ops is an object of type OptionSelect which happens to be the type of the class in which the onCreate() call is made. Will that become an issue? Also, here is the method for incrementProbability():
public void incrementProbability(int numberOfOptions)
{
probability += (numberOfOptions - 1);
if(probability > 100)
{
Log.i("OptionSelect", "Exceeded Maximum by " + (probability - 100));
probability = 100;
}
}
Also, here is relevant code I should've included that is updating my GUI at the end of the onClick() method:
private void refreshDisplay(TextView a, TextView b, TextView c, TextView d)
{
a.setText(getOptionList().get(0).getProbability() + "");
b.setText(getOptionList().get(1).getProbability() + "");
c.setText(getOptionList().get(2).getProbability() + "");
d.setText(getOptionList().get(3).getProbability() + "");
a.invalidate();
b.invalidate();
c.invalidate();
d.invalidate();
}
Thanks for the help so far!
I personally prefer to have my Activities implement listener interfaces and add an onClick method to the Activity itself such as...
public class MyActivity extends Activity
implements View.OnClickListener {
...
#Override
public void onClick(View v) {
...
}
}
I then just use...
myGuiObject.setOnClickListener(this);
...whenever I want to set that method as the listener for any GUI object.