I am struggling with preventing call all methods in class hierarchy chain.
Lets say i have a base class:
class BaseModel
{ /* Some basic fields goes here */ }
class ModelCompany extends BaseModel
{ /* Fields goes here */ }
Then I want to post two different events:
BaseModel oneEvent = new BaseModel();
ModelCompany otherEvent = new ModelCompany();
EventBus.getDefault().post(oneEvent);
EventBus.getDefault().post(otherEvent);
Somewhere in the activity:
onEvent(BaseModel ev1){}
onEvent(ModelCompany ev2){}
The thing is that both onEvent method will be executed in this case. How to prevent it and post message to exact method?
It is possible in EventBus 3 with EventBusBuilder.eventInheritance()
Related
I am creating a Listener class that a couple instances of a custom button in different Activities/Fragments are using. This class has listener methods that will update the respective ViewModel for that Activity/Fragment.
How do you define a ViewModel in a non-activity/fragment class? The documentation says to implement ViewModelStoreOwner, but I'm not really sure on how and what I should be implementing. I'm assuming if I don't implement it correctly, I'll have some sort of memory leak...
public class Listeners implements View.OnClickListener, ViewModelStoreOwner {
#NonNull
#org.jetbrains.annotations.NotNull
#Override
public ViewModelStore getViewModelStore() {
return // what do I do here, and how do I tell it to close the scope appropriately
// when the context is destroyed?
}
// Implement OnClick...
}
Am I just trying to abstract too much here? Does Android really just revolve around Activities and Fragments thus requiring me to have annoyingly long files? The above class is my attempt to reduce redundant implementations of a button listener between two activity/fragments
EDIT:
Is it wrong to just pass the store owner of the activity that this listener instance will eventually reside in? For example:
// Custom class constructor
public Listeners(ViewModelStoreOwner storeOwner) {
mModel = new ViewModelProvider(storeOwner).get(Model.class);
}
// Calling/parent activity/fragment/context
Listeners listeners = new Listeners(this);
mButton.setOnClickListener(listeners);
Unless someone posts an answer to this that says otherwise (and that this is a bad idea), I ended up utilizing the latter solution I updated my question with.
I passed the store owner into the custom Listener class as a parameter, then used this value to initialize my ViewModelProvider inside the custom class.
I believe this is safe, since the class is instantiated within the scope of that parent Fragment/Activity anyway.
So for instance, if you were calling this class from an activity/fragment:
// Calling from Activity
Listeners listeners = new Listeners(this);
// Calling from Fragment
Listeners listeners = new Listeners(requireActivity());
And the relevant class definition:
public Listeners(ViewModelStoreOwner storeOwner) {
mModel = new ViewModelProvider(storeOwner).get(Model.class);
}
I want to define a class with just one constructor with body . When i set parameter of class i can't define the body of primary constructor.
I want the class have only one constructor.
Foe example
I have a class that extends CursorWrapper. This class have parameter that need to superclass implementation. I need a constructor with one parameter that do it:
class wrapper(cursoe: Cursor): CursoreWrapper {
// i need to call super(cursor). But where?
}
If you want to call cursor, it means your CursorWrapper (clearly typo here) is at least an abstract class, and not an interface.
Judging by your question, it also receives cursor (another typo) as an argument, so we get something like this:
open class CursorWrapper(cursor: Cursor)
Now, to invoke this constructor, you simply call it when you inherit from the class:
class Wrapper(cursor: Cursor): CursorWrapper(cursor) // <- this is your super(cursor)
Now let's assume that you also have another function on CursorWrapper that you need to call during construction.
open class CursorWrapper(cursor: Cursor) {
fun bla() {
// You want to call this for some reason as super.bla()
}
}
You can use init() block for that.
class Wrapper(cursor: Cursor): CursorWrapper(cursor) {
// i need to call super(cursor). But where?
init {
super.bla()
}
}
In my Android Application I've some objects which represent different kinds of operations.
public class OperacionDivisa implements IOperacion {
public class OperacionLargo implements IOperacion {
public class OperacionMedio implements IOperacion {
public class OperacionOpciones implements IOperacion {
Each kind of operation implements IOperation interface so I can make an ArrayList of IOperations and store all operations in a single ArrayList.
Now I'd like to do the inverse process. I want to get the arraylist of operations from Firebase (which has already been achieved) and I'd like to show the operations in a ListView
I created a custom adapter as follows:
public class ListViewAdapterOperaciones extends ArrayAdapter<IOperacion>
The issue is that I need to cast each object to its original class to show in a textview different attributes. So this is not useful.
IOperacion operacion = (IOperacion) getItem(position);
So, for each object I'd like to show some data in the listView but I haven't been able to figure out how to do this. Any help would be appreciated.
Thanks in advance.
Use an if statement (or similar) to check instanceof, then use the objects as the subclass.
if (operacion instanceof OperacionLargo) {
// Large operation
} else if (operacion instanceof OperacionDivisa) {
// Other operation
}
I need a little help with my Interface. I think that i doesn't understand them at all.
So i created this interface to notify every classes that implements it when a certain event occurs.
public interface OnColorsChangeListener {
void onColorsChangeListener(ColorsProp colorsProp);
}
My class that hold the interface:
private OnColorsChangeListener mCallback;
... // other code
// the event occurs here so i call:
mCallback.onColorsChangeListener(mProps);
// but of course here i get an NPE becouse this is undefined in this class.. well, with some replies here i'll understand better how to use that for reach my point
The class that implements it:
public class ClassTest implements OnColorsChangeListener {
... // other code
#Override
public void onColorsChangeListener(ColorsProp colorsProp) {
Log.d(TAG, "Color changed! " + colorsProp.color);
}
i put this in 4/5 classes to be notified in the same time for the color change. I'm quite sure the reason is that I didn't understand very well how them works, so can anyone point me to the right direction? Thank you!
Explanation by example:
You have to instantiate your callback, & it has to be an instance of your class
private OnColorsChangeListener mCallback;
mCallback = new ClassTest();
mCallback.onColorsChangeListener(mProps);
However if you want multiple callbacks you will need to use the Observer pattern.
Simple example:
private List<OnColorsChangeListener> mCallbacks = new ArrayList<OnColorsChangeListener>();
mCallbacks.add(new ClassTest());
mCallbacks.add(new OtherClass());
for(OnColorsChangeListener listener : mCallbacks) {
listener.onColorsChangeListener(mProps);
}
Obviously if you have the class, somewhere else you would not new it up, you would use that reference:
mCallbacks.add(mClassTest);
Observer Pattern Wikipedia
An interface is just a way to group together a bunch of related methods. Implementing this interface then requires you to implement all the methods grouped together by the interface.
The Java Tutorials has a good read on the subject:
What is an interface?
Here's a Stackoverflow thread regarding listener interfaces in android:
How to create our own Listener interface in android?
In short, you don't use the interface directly since it only specifies which methods implementing classes are supposed to implement.
Well, I'm at a dilemma here. I made my own class that uses the Bluetooth class from android but I'm not sure where to put it. Extending the android Bluetooth class seems like a good idea but I need to override the onActivityResult() which is only available to an activity class. So, where would I put my class so that I have access to onActivityResult() (keeping in mind the idea here is to use as few dependencies as possible)?
In other words, I want to move the Bluetooth code from the main activity to a separate class.
You should to use separate file for each class. You can create a folder "engine". For example: com.mycorp.myapp.engine. You can get access to onActivityResult() very simple. For example: MainActivity.onActivityResult(). Note: function should be public.
Or you can pass your activity to your CustomBluetooth's constructor.
public class CustomBluetooth {
private Activity mActivity;
/* Constructor */
public CustomBluetooth (Activity pActivity ) {
super();
this.mActivity = pActivity;
}
/* Your functions */
public int getResult() {
return this.mActivity.onActivityResult();
}
}
Alex. P.S. Sorry for my English:)
Add an interface to your Bluetooth class and implement the interface in your activity.