Cannot get a switch listener working with setOnCheckedChange(onCheckedChange) - android

I'm having a problem having a switch button listener to work correctly. It is in my main activity as is:
public class MainActivity extends WearableActivity {
private Switch mySwitch;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Enables Always-on
setAmbientEnabled();
// React to settings change
mySwitch= findViewById(R.id.mySwitch);
mySwitch.setOnCheckedChangeListener(this); // <--------
}
public void onCheckedChange(CompoundButton s, boolean isChecked) {
...
}
}
At the arrow line, I tried with this (like a sample on the internet). It is marked in Android Studio as an error. AS suggests me to cast to a CommpoundButton.onCheckedChange (or similar). When I start the app, it crashs saying MainActivity cannot be casted to that. I cannot do also setOnCheckedChangeListener(onCheckedChange);
What I am doing wrong?

You need to implement OnCheckedChangeListener if you want to use this as a option for setOnCheckedChangeListener().
public class MainActivity extends WearableActivity implements CompoundButton.OnCheckedChangeListener{
This is because setOnCheckedChangeListener() will only accept an instance of OnCheckedChangeListener, so you can't simply use this since the Activity that this is pointing to isn't an instance of OnCheckedChangeListener.
However, since OnCheckedChangeListener is an interface, this is easily rectified by implementing OnCheckedChangeListener. Thanks to how inheritance works in Java, Activity automatically becomes an instance of OnCheckedChangeListener once the interface has been implemented.
It looks like this was the option you were going for since you're also overriding the onCheckedChange() method inside your Activity.

Related

Access button reference from other class

I have somthing like that:
public class A()
{
private Button myButton;
public void setMyButton(Button myButton)
{
this.myButton = myButton;
}
public Button getMyButton()
{
return myButton;
}
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
setMyButton(button);
}
public class B()
{
public void exampleMethod()
{
A aObject = new A();
Button button = aObject.getMyButton();
}
}
Button in class B is always null. I tryied that:
In class A
public Button myButton;
In class B
A aObject = new A();
Button button = aObject.myButton;
but it is not working too.
I am sure that first is button initiate, then geting button reference. I checked that using logs.
I don't know what is going on, becasue "getMyButton" in class A work fine. How can I get reference of button from class A in class B?
What is the best way to do that?
Looks like you are creating new java object of your activity on your own. Please try to get existing object of an created activity; so that you will get activity context and activity properties as well.
The button is always null because its set in onCreate, which is not automatically called. Let me guess, A is supposed to be an Activity subclass, based on the signature, right? In that case you're doing things really wrong.
*You cannot create an Activity via new, it won't be properly initialized.
*Accessing views of an Activity like that is really weird. It makes more sense to pass the view into B, as B is likely owned by A. If the Activity A doesn't own B, you're probably doing something really wrong. Pretty much if you need to do this you've probably misarchitected something.
The way that you are doing will only works in JAVA and not in ANDROID.
Its because of ACTIVITY class. Activity class reference will be created only when its life cycle is created and you cannot pass the UI elements of one activity to Another.
As the button is associated with the 'A' Class in your case and if you want this in Class 'B' you have to start Activity and its life cycle and also setContentView(R.layout.activity_main);
Other way is get the data that you want from any class and publish the value in 'A' class itself. this can be done by startActivityForResult();

What is the best way to organize android development code?

I know that every situation will be different, but I just wanted see if there was a general recommendation.
Currently, I have my activities (screens) dynamically creating custom button objects and custom edit text objects. Each of these objects have listeners to see if their state has changed. These object classes have all the logic for the screen. The activity's only job is to assign objects to the widgets I created in XML.
Part of me thinks it should be opposite, where the activity contains all the logic for all the widgets on the screen and simply waits for the objects to notify it when the listeners go off.
Which way is more "standard" ?
I use the following way. I have a common EventHandler sub class in every activity or fragment and I add a single instance belonging to activity to each UI item. EventHandler implements OnClickListener, OnChanged.., and so on.
I would also recommend looking at this library, if you are familiar with DI concept:
https://github.com/roboguice/roboguice/
Here is an example of code of mine:
package com.x.y;
public class DashboardActivity extends FragmentActivity {
private EventHandler eventHandler = new EventHandler();
#SomeAnnotationForInit(R.id.some_id)
private Button feedButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dashboard_activity);
initGui();
}
private void initGui() {
feedButton.setOnClickListener(eventHandler);
}
private class EventHandler implements View.OnClickListener {
#Override
public void onClick(View view) {
if(view.equals(...)) {
//TODO:
}
}
}
}

How does setOnclickListner(this) work?

There are multiple ways to register callbacks when a Button is clicked. If I go by the following way:
public class MainActivity extends Activity implements OnClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(this);
}
#Override
public void onClick(View v) {
Toast.makeText(this, "Hello onCLick", Toast.LENGTH_SHORT).show();
}
}
I don't understand how the method setOnClickListener(this) identifies that it should call onClick() method?
This refers to the activity. Because the Activity implements an OnClickListener calling button.setOnClickListener(this) gives the onClickListener that the Activity implements to setOnClickListener.
I recommend you look up info about implementing interfaces in Java if you want tot know more about this practise.
if you are aware about oops 'this' refer the reference of current object of class. a good explanation is define here
In above case MainActivity reference is refer as this here.
public void setOnClickListener(OnClickListener l)
is setter method define in class Button which hold the reference on "OnClickListener".
when you set setOnClickListener(this) it define you are passing OnClickListener reference as your activity so to make your activity as type on OnClickListener you have to implement the interface OnClickListener in your activity class as it is showing in your code.
public class MainActivity extends Activity implements OnClickListener
Its a callback listener which have method "onClick" you have to override that method
and when button is clicked that method is call by Button class so the event listener (which is you activity in current scenario) can listen to it.
I think I understand your confusion. When you read other SO answers or references like the View.OnClickListener, it feels like all the sentences are telling the same thing but nothing that really helps click.
What happens is, when a Button is clicked, it will notify all the objects that are listenning for it. You are subscribing your activity as a listener, to this event with the line
button.setOnClickListener(this);
So, on an event of a click, button knows that it should call the activity's onClick event.
I don't understand how the method setOnClickListener(this) identifies
that it should call onClick() method?
(Therefore, it s the button that calls the listener.onClick() method, in case there's a confusion there.)
Also, #nourikhalass has a point, you should first make sure that interfaces make sense to you.
Is it any clearer?
Your code has
MainActivity implements OnClickListener
but actually it is:
MainActivity implements View.OnClickListener
Maybe that is what confuses you.
"This" refers to current object.
To handle button clicks, an object must implement the "OnClickListener" interface and define what to do when clicks are received in "onClick" method. Then you can register that object as a listener for your button clicks.
In your case, your activity implements OnClickListener, and onClick shows a toast:
public class MainActivity extends Activity implements OnClickListener {
...
#Override
public void onClick(View v) {
Toast.makeText(this, "Hello onCLick", Toast.LENGTH_SHORT).show();
}
Therefore, your activity can handle button clicks, so you register it as a listener for your button:
button.setOnClickListener(this);
As "this" implements the required interface, is a valid listener.

Pre-Written android code throws nullPointerException

I dont know why this code throws a nullPointerException. I did not written this part of code and im pretty new with this staff. I tried my best but could not able to find an answer.
public class ProgramExamActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setTitle("Screen #1");
}
public void onClick(View v) {
switch(v.getId()) {
case R.id.btn2:
setContentView(R.layout.screen2);
setTitle("Screen #2");
break;
}
}
First, this
setContentView(R.layout.screen2);
setTitle("Screen #2");
you can't, you shouldn't call this more than once.
And second if you want to use OnClickListener, you need to register it for some widget and in your code there is any widget.
In your case your class need to implement View.OnClickListener if you don' want to work with Listeners as anonymous classes
public class Program... extends Activity implements View.OnClickListener { ... }
Then you need to register it like this:
Button btn = (Button) findViewById(R.id.btn2);
btn.setOnClickListener(this);
Note: if you want to start another Activity with different title and content, you have to use Intents and call startActivity().
More about Intents and there is tutorial Android: How to switch between Activities.
Add listener of click event as
public class ProgramExamActivity extends Activity implements OnClickListener{
then, register your component with this listener.
Suppose you want to add click on any of your Button like btn1.
then add code in OnCreate
btn1.setOnClickListener(ProgramExamActivity.this);

Best practice to access Activity from Views

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 :)
}
}

Categories

Resources