How to update model value in android - android

I am using AutoValue in my models, I want to update the isTrue() value of the model when the user does something. So I need help. Here is my model.
#AutoValue
public abstract class Xyz implements Parcelable {
#SerializedName("isTrue")
public abstract boolean isTrue();
#Nullable
#SerializedName("lead_image_url")
public abstract String lead_image_url();
public static TypeAdapter<Readable> typeAdapter(Gson gson) {
return new AutoValue_Readable.GsonTypeAdapter(gson);
}
}

The use-case for #AutoValue is creating
Generated immutable value classes ...
If you want to change a value, you'd have to create a new instance of the type, updating this one value.
This can be easily implemented with auto-value-with. Just add a with-method to your type.
public abstract Xyz withIsTrue(boolean isTrue);
The extension will implement the method copying all data to the new instance.

Related

Why does LocationListener have a constructor if it is an interface?

I have seen that constructors aren't allowed within an interface, however how is this allowed?:
locationListener = new LocationListener() {
etc }
Yes you are right interfaces can't have constructors but what you described is Anonymous Class. In this line you are creating object of new class without name that extends LocationListener (and implementation of it is between curly brackets).
If you want to get know some more about Anonymous Classes look here: https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html
This is Anonymous class approach. To make it clear, here is an example.
interface Animal {
public void cry();
}
To create an object of Animal instance, you need to implement the Animal interface first.
class Lion implements Animal {
public void cry() {
System.out.println("Roar");
}
}
Then create an object using the usual approach:
Animal theLion = new Lion();
Another way is to create an Animal object using the Anonymous class.
Animal theTiger = new Animal() {
public void cry() {
System.out.println("Grrr");
}
}
Now, both object should be able to call the cry method as:
theLion.cry();
theTiger.cry();
Cheers!

Is it necessary to extend every model class with RealmObject while working with realm?

I am using Realm ORM for my app. I have 3 model classes of which two extends RealmObject while the other one does not.
public class Party extends RealmObject implements Parcelable {
#PrimaryKey
public int id;
public String name;
public String name_en;
public String name_ne;
public String address;
public String phoneNumber;
public String taxRegistrationNumber;
public String partyType;
the second class holds a field of type Party. But this does not extends RealmObject
public class CreatePurchaseOrder implements Parcelable {
public int voucherNumber;
public Date date;
public Party party;
String agent;
The third class holds a field for CreatePurchaseOrder and extends RealmObject
[public class CreatePurchaseOrderRow extends RealmObject implements Parcelable {
#PrimaryKey
public int id;
private int serialNumber;
private String specification;
private float quantity;
private float rate;
private String remarks;
private boolean fulfilled;
private CreatePurchaseOrder createPurchaseOrder;
With this approach it generates an error message
screenshot of error message
So is it necessary to extend every Model class with RealmObject?
Technically you don't have to extend RealmObject directly from your model class.
The docs say:
Realm model classes are created by extending the RealmObject base class.
Which implies that if you don't extend RealmObject, your class is not a Realm model, thus it can't be stored in a realm.
However you can also implement the RealmModel interface and annotate your model class with #RealmClass
#RealmClass
public class MyModel implements RealmModel {
}
as mentioned here:
Why do model classes need to extend RealmObject?
We need to add Realm specific functionality to your model classes. It also allows us to use generics in our APIs, making it easier to read and use. If you don’t want to extend a base class you can instead implement the RealmModel interface.
and here:
An alternative to extending the RealmObject base class is implementing the RealmModel interface and adding the #RealmClass annotation.
It is a different means to achieve the same goal. The issue you experience is the same though. You cannot store plain objects in a realm. You must hook up your model class to Realm using one of two ways mentioned above.
Do note that if you use the 2nd approach, the usage is different:
// With RealmObject
myModel.isValid();
// With RealmModel
RealmObject.isValid(myModel);

Extending an Android Parcelable class

I have a CustomAddress class that extends the android.location.Address class that implements Parcelable.
I am trying to make my CustomAddressimplement Parcelableto but am stuck when creating my class from a parcel. What I want to when creating CustomAddressfrom a parcel is first fill in all the fields from the super class Addressand then my own fields. So I have implemented the CREATORfield:
public static final Parcelable.Creator<CustomAddress> CREATOR
= new Parcelable.Creator<CustomAddress>() {
public CustomAddress createFromParcel(Parcel in) {
return new CustomAddress(in);
}
public CustomAddress[] newArray(int size) {
return new CustomAddress[size];
}
};
But in my CustomAddress(Parcel in)creator, I can't call super(in)because it doesn't exist in android.location.Address. I can only access android.location.Address.CREATOR. So how do I fill in my fields using CREATOR?
EDIT: link to the android Address class https://developer.android.com/reference/android/location/Address.html
Here is a similar question and Mark Murphy's excellent answer: https://stackoverflow.com/a/10841502/1140682
So, in your case, you would make CustomAddress extend Address (as you already do), call the super() method in the constructor and then read your own attributes from the passed Parcel. Same has to be done (in same order) in the writeToParcel() method, of course here adding your attributes to the parcel.

How can I inject parameter through constructor in Roboguice? [android]

This question is probably exact duplicate of this one
Pass parameter to constructor with Guice
Difference is that I use roboguice for android, not just Guice, so answers there does not work for me.
Question is - how can I pass initialize parameters into created object? I.e. I have injected interface which should be initialize with some parameter which roboguice does not know.
What I see in link I provide, I should create factory interface and register it like this
void configure(Binder binder) {
binder.install(new FactoryModuleBuilder()
.implement(FooInterface.class, Foo.class)
.build(FooFactory.class));
}
But I can't find FactoryModuleBuilder class. I use Intellij IDEA, it can show me every class which I can access at current place and I can be 100% sure that there is no classes which starts with 'Factory' word.
How can I create my factory using roboguice?
UPDATED
I forgot to download guice-assistedinject. But still I can't figure out where should I register this factory.
UPDATE 2
Why I need that? Because there should be situation where some abstraction has dependency which could not be resolved by Roboguice. This dependency could be any type, even simple string or number.
In my case I have NumberPicker control on UI and I want to move all UI specific tasks in MyNumberPickerWrapper class. And when I create this wrapper I inject its dependency (this control) through constructor.
It's not the point if I am right with such approach, but that there could be a plenty of another more applicable example where constructor injection needed and this injected classes could not be created by Roboguice
I followed the steps of the answer given in Pass parameter to constructor with Guice and did slight modifications to run it under roboguice. Works completely fine for me.
add guice-assistinject library to gradle script
dependencies { compile 'com.google.inject.extensions:guice-assistedinject:4.+' }
Create Factory interface that with create method that accepts parameters the object constructor requires and returns object's interface
public interface ICustomObjectFactory {
ICustomObject create(String queueName);
}
Add #Inject annotation to constructor of the object and #Assisted annotation to each parameter coming from factory.
public class CustomObject implements ICustomObject {
protected String name;
#Inject
public CustomObject(#Assisted String name){
this.name = name;
}
}
Add binding into the Module that you are using
public class SomeModule extends AbstractModule {
#Override
protected void configure() {
install(new FactoryModuleBuilder()
.implement(ICustomObject.class, CustomObject.class)
.build(ICustomObjectFactory.class));
}
}
Inject factory and create instances of your object
public class SomeClass {
#Inject ICustomObjectFactory factory;
public SomeClass () {
ICustomObject first = this.factory.create("first");
ICustomObject second = this.factory.create("second");
}
}
I faced this same problem and I succeed thanks to Pavel's answer. I only have had to struggle with some errors, and I don't know if it's due to the versions of the libraries used, but for me didn't work without modifying the annotation of the constructor, replacing #Inject by #AssistedInject. With that, the code of the class that implements the interface looks like this.
public class CustomObject implements ICustomObject {
protected String name;
#AssistedInject
public CustomObject(#Assisted String name){
this.name = name;
}
}

How to use Parcelable if class requires additional parameters in construcor

I'm trying to create class with generics that will have ability to serialize its state using Parcelable interface.
The problem is that class has to contain constructor with single parameter - Parcel, but in my case I need to create class with additional parameters.
Besides, Parcelable.Creator doesn't allow to use generics.
Here is an example:
public class Sample<T> {
...
public Sample(Context ctx, SomeInterface iface, Parcel parcel) {...}
...
}
What is the best practice to do it?
Already found the solution - I moved all members related to object state into separate Parcelable class and added the following constructor:
public Sample(..., ParcelableState state)

Categories

Resources