As documentation says
Name of the method in this View's context to invoke when the view is clicked.
Perfect, but is it "somehow" possible to create a static method and use it everywhere I need, not to define inside each Activity class. And yes I'm aware of defining the method inside base Activity class. All I'm looking for is to just write full name of method and let it uses it. Possible ?
Thanks
You cannot assign a static method to the onClick xml property. You'll have to add the method you specify there to any activity that consumes the layout. You can have that method in each activity call a static method that actually handles the click, but there's no way to avoid having the instance methods altogether.
It's not possible. Android searches for this method in an activity instance. That is why it must belong to an instance.
My suggestion is you create a class that handles all the functions that the buttons does
and call that function on the Activity's onClick method.
Example
public class AppModel {
public static void button1Function(){
//do something
}
}
then on your activities
public void button1Clicked(View view){
AppModel.button1Function();
}
I think this looks like the MVC design paradigm. Click here for further reading.
Why don't you create an entire new class having your static method?
You can load this class wherever you want then...
Related
Using java with android studio, I'm trying to be able to change the app's orientation from places besides the MainActivity. I can pass the context to a (non-static) field of another class, and call it's methods such as getSystemService(), etc, but it won't let me call setRequestedOrientation() from anywhere but the main activity and I don't understand why. Does anyone know an answer?
For example:
from the mainactivity which extends AppCompatActivity i can call this:
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
And if I pass the context like so from mainactivity:
U.Orientate hey=new U.Orientate(this);
I cannot call context.setRequestedOrientation(int) from Orientate's constructor, the method is not even there.
I have read if we want listener in dialog, we have to implement interface to our parent activity or fragment and use it as listener.
But what if we want to have custom listener ?
I don't want to make my parent activity/fragment bigger. I have read also we shouldn't use an injection via method for listener and we cannot use second constructor in our dialog.
So question is: How to create custom listener and inject it to dialog without expand parent (activity/fragment) ?
I hope I can help.
I assume that you need customlistener that stored in another class.
first step if you need to have custom listener is creating interface class, and put some fun or method inside.
this website will explain how to create custom listener, even though it's wrote in java, you will easily implement if you understand the concept
Create custom listener<<
Before some time, i started looking for a pattern to decouple UI from a logic of my app. I decided to use MVP, but there is one significant problem which i cant solve.
How can i inject a instance of presenter into view, if classes that implements Application, are launched from static method. There is also no choice to launch specific instance of class implementing Application, so parameters in constructor are useless.
Also i do not use FXML, my view class is coded in java.
PS: Sorry for my english, as it's not my native language
You can pass a reference from say Main.java to a Presenter. In Main do this:
Presenter p = new Presenter(); // This is your Presenter class
p.setReference(this); // Call a method in the presenter
// and here is a method in Main.java just as an example
public StackPane getRootView(){
return this.rootView;
}
Then in Presenter you have:
private Main main;
public void setReference (Main main) {
this.main = main;
}
Your presenter can now call methods in Main e.g.
StackPane sp = main.getRootView();
You could also do this in the constructor of Presenter.
I have written a sample code to answer to this problematic.
https://github.com/oterrien/JavaFX_Presenter.git
The view interface provides the intention of the view.
For example:
getting and setting text
getting and setting result1
getting and setting result2
getting and setting event handler for the Add button
The concret view is created from FXML file. Each field of the control is defined with #FXML. The action to be triggered when the button is clicked is also a method and is prefixed by #FXML.
The concret view implements the interface by providing a mapping between #FXML fields and getting/setting methods. And the triggered method does just call the event handler.
The concret view is also responsible of creating the presenter (which refers itself as view).
That is the important point. The presenter acts upon the model and the view. It retrieves data from repositories (the model), and formats it for display in the view.
For that purpose, the presenter should be able to call the view in order to set data and retrieve data once updated by user. That is why, the presenter contains a reference of the view. But it should also provide action to be done when view's event handlers are called.
When a user clicks on button "Add", the method which is bound with FXML is called. This method call the EventHandler which has been set by the presenter. In other words, the presenter is responsible of registering its own method to the view's EventHandler.
Finally, testing the presenter just consists in creating a mock of the view.
I am creating an expert system engine with a custom scripting engine, and some of the commands are integrated with the main xml gui. As an example, there is a 'respond' command that accepts strings and sets them in an EditText. The respond command is essential to the functionality of the app, but I cannot access the EditText with findViewById because the command routine resides in another class. Even if it is bad form, how can I access GUI elements from other classes?
Thank you.
how can I access GUI elements from other classes?
If the other class is an Activity, you cannot. You should pass the EditText's contents in an Intent or by some other means.
If the other class isn't an Activity, simply make the EditText a public field variable. Or you can pass this other class a reference to your Activity or the root View and use methods like findViewById() without much fuss.
Provide the EditText object to 'the other class' by using a custom method (like public void setEditText(EditText myEditText), or something similar), or as a parameter in its constructor (depending on your situation).
Another possibility is to send the complete Activity that defined the EditText, so you can use findViewById() to grab the EditText. But I would not recommend it (bad practice, I think) unless you have lots of objects that you need to access.
I had this same problem. My code in my activity had too much code, and I wanted to create external classes to do some of the processing in there. However, one process included using an EditText, and you can't instantiate that in a class that has no UI. So the easiest solution is to make your EditText myEditText variable public and static in the activity, and then when you use it in your external class, just use dot notation with the original activity it came from, and it should work. The static keyword is what makes it a global variable, accessible by other classes/activities.
public static EditText myEditText; // put this in your Activity
ActivityName.myEditText.someMethod(); // use of EditText in your external class
I have a custom View class that extends Spinner. I'm trying to figure out what the correct way to talk to the Activity that it's embedded in is, when the user makes a selection. I see that the OnItemSelected listener gets a reference to the Adapter, but I'm not clear on whether or not I should be using this adapter and walking up its parent chain somehow, or if I should just talk directly to the context (for some reason that doesn't feel safe, even though I can't think of a way in which it might fail, offhand).
the right way to do that, is to "listen" to your custom view by exposing an interface which your view holding a reference to instance of him, and you hosting activity should implement. exactly like the OnItemSelected interface and any events which android views are exposing is been implemented. this is the observer design pattern.
for example:
public class MyCustomSpinner extends Spinner {
public MyCustomSpinner(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public interface IMyEventListener {
public void onEventOccurred();
}
private IMyEventListener mEventListener;
public void setEventListener(IMyEventListener mEventListener) {
this.mEventListener = mEventListener;
}
protected void someMethodWhichDoingSomthingAndShouldRaiseAlsoTheEvent() {
/*
* Some Code which the function doing //more code...
*/
if (mEventListener != null) {
mEventListener.onEventOccurred();
}
}
}
this is how you will use it from your activity:
mMyCustomSpinner.setEventListener(new IMyEventListener() {
#Override
public void onEventOccurred() {
// TODO Auto-generated method stub
}
});
I'm trying to figure out what the correct way to talk to the Activity that it's embedded in is, when the user makes a selection.
You don't want to "talk to the Activity that it's embedded in". You want to talk to the controller responsible for the View. Today, that might be an Activity. Tomorrow, that might be a Fragment.
I see that the OnItemSelected listener gets a reference to the Adapter, but I'm not clear on whether or not I should be using this adapter and walking up its parent chain somehow
That implies that the View knows the specific type of Adapter, since the Adapter interface does not have any sort of getContext() method. Moreover, it ties you to talking to the Activity, which is not a good plan at this point, as mentioned above.
Personally, I'm a bit dubious about having a custom Spinner subclass in the first place. But, assuming there's a good reason for it, you should follow Tal Kanel's advice (posted while I was writing this) and design a custom listener interface for this custom event that is being declared by your custom View. Have the controller (Activity or Fragment) supply an implementation of that interface -- this could be directly implemented on the controller, or implemented as an anonymous inner class (as in Tal Kanel's answer), etc. Have your custom View call method(s) on the listener interface as needed.
The correct way is using a listener of some sort. I think you can make direct reference, your code would just not be reusable for another project then...
A simple solution -
((ParentClass) context).functionToRun();
Where ParentClass is the class name of the activity.