The different OnClickListener implementation ways - java

What is the difference between:
public class MainActivity extends Activity {
public void onCreate (Bundle savedInstanceState) {
button1 = (Button) findViewById(R.id.btn1);
button1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// Click code
}
)};
}
}
And:
public class MainActivity extends Activity implements OnClickListener {
public void onCreate (Bundle savedInstanceState) {
button1 = (Button) findViewById(R.id.btn1);
button1.setOnClickListener(this);
}
public void onClick(View arg0) {
switch(arg0.getId()) {
case R.id.button1:
// Click code
break;
}
}
}
They have both the exact same functionality and results.

The first method uses an anonymous inner class that implements the interface method. By using this approach, you receive events only for that particular View.
In the second method, you entire Activity class implements the OnClickListener interface. You can set the OnClickListener of every View to this, and receive all the click events in one method, where you can then filter them and act upon them.
The first method translates to:
Button.OnClickListener anonymous_listener = new Button.OnClickListener() { ... };
button.setOnClickListener(anonymous_listener);
Which is to say that it dynamically creates and stores a new OnClickListener instance when you use it.
In the second method, your entire class uses one single instance of the OnClickListener, that is passed to all the Views you want to listen for clicks on.

Related

Activity cannot be transfered into a onclicklistener

I made one of the simplest programs that creates a login page, however, I cannot add an OnClickListener to my button, and I do not know why. I'm really new to Android Studio and have no idea what to do. When I hover over the error it says "In View cannot be applied".
I've tried these bits of code found on the internet, but the error doesn't leave, and the machine says that the #Override does not override what's above.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_teacher_in_j);
regist1 = (Button)findViewById(R.id.btnregister1);
regist1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent teachtoregist = new Intent(TeacherInJ.this, TeacherRegisterInJ.class);
startActivity(teachtoregist);
}
});
etUsername = (EditText) findViewById(R.id.editText2);
etPassword = (EditText) findViewById(R.id.editText3);
bLogin = (Button) findViewById(R.id.btnlogin);
bLogin.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnlogin:
//Start activity one
break;
When I hover over the error it says "In View cannot be applied".
I've tried these bits of code found on the internet, but the error doesn't leave, and the machine says that the #override does not override what's above.
Both the above problems are because you didn't add the implements keyword to your Activity. You need to add it so the Activity can be regarded as OnClickListener interface by the button.
You need to do something like this (See the comments inside the code):
// see below the implements View.OnClickListener line that
// need to be added so the Activitiy can be regarded as the listener.
public class TeacherInJ extends AppCompatActivity implements View.OnClickListener {
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_teacher_in_j);
...
// now you can use this as the listener. It's because you have
// set the current Activity class as the View.OnClickListener
// this is refer to current Activity object.
bLogin.setOnClickListener(this);
}
// Now you can add the #Override to the onClick method from
// the View.OnClickListener.
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnlogin:
//Start activity one
break;
}
}
}

View being passed as a parameter in Kotlin/Android

New to kotlin/android so excuse my beginner skills.
However, why is View being passed in onClick(v: View) where the type should usually be? (e.g Int, String) etc.
I didn't think this was possible/allowed.
My code:
class MainActivity : AppCompatActivity(), View.OnClickListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
choose_1_player.setOnClickListener(this)
}
override fun onClick(v: View) {
when (v.id){
R.id.choose_1_player -> println("Hello")
R.id.choose_2_player -> println("Hello")
}
}
}
Is it because the function is written in Java and not Kotlin?
Because
1.We click on a View it may be a Button , TextView ,EditText or any layout so on the basis of Integer ID difficult to match with actual views.
2.View has many information including its Id ,that can be used like (Tag , Text etc).
3.Also view has its parent Layout Information can be used .
Please find more details at below link:
Why do we have to add 'View' as parameter in onClick method and what it does?
View class has interface with method onClick(View view).
/**
* Interface definition for a callback to be invoked when a view is clicked.
*/
public interface OnClickListener {
/**
* Called when a view has been clicked.
*
* #param v The view that was clicked.
*/
void onClick(View v);
}
MainActivity class is implementing View.OnClickListener interface, which has the following signature:
public interface OnClickListener {
void onClick(View v);
}
So onClick method is implemeted and it receives View as the parameter.
v - is a view which was clicked.
Addition:
The syntax of the overridden onClick method in Kotlin is the following:
override fun onClick(v: View) { ... }
where v - is a view which was clicked; View - is the data type of object v from Android SDK. It is a parent class for many children, such as Button, TextView etc. That means onClick method can receive a Button, TextView, ImageView and other views that inherit from View. Here works one of the principles of OOP - Polymorphism.
The View attribute inform which View you clicked (every visual component of Android is a View) so you can use this information to identify "who" is calling the onClick.
If in my layout I have 3 buttons (button1, button2, button3) I can do something like this (in Java):
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
button1 = findViewById(R.id.button1);
button2 = findViewById(R.id.button2);
button3 = findViewById(R.id.button3);
button1.setOnClickListener(this);
button2.setOnClickListener(this);
button3.setOnClickListener(this);
}
#Override
public void onClick(View view) {
switch(view.id) {
case R.id.button1:
button1Action();
break;
case R.id.button2:
button2Action();
break;
case R.id.button3:
button3Action();
break;
}
}
Or you can do something like this and ignore the View attribute
public class MainActivity extends AppCompatActivity {
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
button1 = findViewById(R.id.button1);
button2 = findViewById(R.id.button2);
button3 = findViewById(R.id.button3);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
button1Action();
}
});
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
button2Action();
}
});
button3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
button3Action();
}
});
}
PS.: I didn't run this code. Probably it has some errors.

Closing a view class and opening another view class

I call a view class from my activity. Then the view class calls the same activity. Here is the problem, once the activity comes back up, it won't register any more button pushes.(I'm trying to call another view class. Here is some code:
View Class
public class AnimationView extends View {
Activity myActivity;
//...
public AnimationView(Context context, Activity activity) {
super(context);
//...
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//...
myActivity.setContentView(R.layout.activity_home);
}
}
Home Activity
public class HomeActivity extends AppCompatActivity {
private AnimationView mDrawViewA;
///...
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
mDrawViewA = new AnimationView(this,this);
start = (Button) findViewById(R.id.startButton);
//...
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//...
setContentView(mDrawViewA);
//calls more views
//......
});
}
I realize now maybe I should have been calling the view classes in different activities, but I would very much like a get all the view classes working within the same activity.
The problem is you're calling setContentView every time you press the "start" button. This method will overwrite the current layout (if any) with the new value you're setting.
What you can do to get the result you're expecting, which, from what I understand, is to add a new AnimationView to your current layout on every button click, you can try something like this:
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AnimationView animationView = new AnimationView(getApplicationContext());
// I'm using ConstraintLayout as an example, since I don't know exactly what layout you're using
ConstraintLayout.LayoutParams params = new ConstraintLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
// Set the layout params the way you want
addContentView(animationView, params); // This is where the magic happens
}
});
In short, addContentView is the method you should use when you want to add new views into your activity's root layout.
PS.: It's a terribly bad practice to let the views "know" the activity controlling it. It's always the opposite way around: the activity/fragment knows the view(s) it's controlling.

How to reference button for onClickListener?

I am trying to create an Android app, and i want to create a on click listener, here is what I have so far.
public void amazonListener() {
amazonButton = (Button) findViewById(R.id.amazonButton);
}
As you see, i am in the very early stages, but where I first referenced amazonButton (before the = sign) button, it turns into red text and it says Cannot resolve symbol 'amazonButton'. Also, I have referenced this method in the onCreate method
This is how you'd go about creating a button and setting a click listener to it.
public class MainActivity extends YouTubeFailureRecoveryActivity {
Button amazonButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
amazonButton = (Button) findViewById(R.id.amazonButton);
amazonButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Define what should happen when the button is clicked.
}
});
}
}
You can also put the initializations in a single method and call that method, like you've tried :
public class MainActivity extends YouTubeFailureRecoveryActivity {
Button amazonButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initializeViews();
}
private void initializeViews() {
//Make sure you've declared the buttons before you initialize them.
amazonButton = (Button) findViewById(R.id.amazonButton);
amazonButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Define what should happen when the button is clicked.
}
});
// Add more Views initialization here ...
....
}
}
You need to give the type of the variable when you declare it.
Button amazonButton = (Button) findViewById(R.id.amazonButton);
The alternative is to declare it (but not initialize it) outside of any method and then initialize it later.
Button amazonButton;
/* ... */
private void amazonListener() {
amazonButton = (Button) findViewById(R.id.amazonButton);
}

Can't Instantiate the type

Have this code in my mainactivity.java file:
public class MainActivity extends Activity {
Button btnSendSMS;
/** Called when the activity is first created. */
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnSendSMS = (Button) findViewById(R.id.btnSendSMS);
btnSendSMS.setOnClickListener(new View.OnClickListener());
}
ADT says that : btnSendSMS.setOnClickListener(new View.OnClickListener());
cannot be instantiated.
You cannot intantiate a View.OnClickListener with an empty constructor. You need to instantiate an anonymous class for that.
Example:
btnSendSMS.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO your code
};
});
If you want to add anonymous click listener do it that way
btnSendSMS.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick (View v) {
// your code
}
});
btnSendSMS.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
1)That's the implementation you need!
2)Try to rebuild your project anyway!
ADT says that : btnSendSMS.setOnClickListener(new
View.OnClickListener()); cannot be instantiated.
I believe View.OnClickListener() is either an abstract class or an interface. In java You cannot instantiate an interface or an Abstract class, thus you get an error. I believe you need an anonymous inner class in place of instantiation.
btnSendSMS.setOnClickListener(new ViewOnClickListener() {
//your implemneting method from ViewOnClickListener
});

Categories