NullReferenceException in MvvmCross Messenger - android

This is code in my ViewModel
public ICommand GoToCartCommand{
get{
return new MvxCommand (() => {
var cartViewModel = Mvx.Resolve<CartViewModel>();
if (cartViewModel != null)
{
cartViewModel.cartlist.Add(new CartItemViewModel() { Name = Name, ID = ID, UnitPrice = double.Parse(Price), Quantity = 1, Description = Description, Image = Image });
}
cartListCount = cartViewModel.cartlist.Count;
var messanger = Mvx.Resolve<IMvxMessenger>();
var message = new MyMessage(this,"Product has been added",cartListCount);
messanger.Publish(message);
});
}
}
public class MyMessage : MvxMessage
{
public int CartList_Count{ get; set;}
public string Message{ get; set;}
public MyMessage(object sender,string _message,int _cartlist_count) : base(sender) {
this.Message = _message;
this.CartList_Count = _cartlist_count;
}
}
This is code in my View :
var messenger = Mvx.Resolve<IMvxMessenger>();
_token = messenger.Subscribe<MyMessage>(OnInputIsNeeded,MvxReference.Strong);
private void OnInputIsNeeded(MyMessage _Message)
{
Toast.MakeText (this.Activity,_Message.Message, ToastLength.Short).Show();
}
My problem here is when I comeback to this view after going to next view OnInputisNeeded the method is called two times.
And when go back from this view and when I again come to this view and click button I get a NullReferenceException.
What is the solution?
What is the meaning of this:
Nothing registered for messages of type MvxSubscriberChangeMessage
How do i register MvxSubscriberChangeMessage?

Related

Xamarin.Forms Imagesource issue

I have a view with an image: <Image Source="{Binding MainUrl}"/>
Image binding value : My image source on loading from database
the value of MainUrl variable is stored in an sqlite table.public string LogoUrl { get; set; }
viewmodel :
private string _logoUrl;
public string LogoUrl
{
get { return _logoUrl; }
set
{
SetValue(ref _logoUrl, value);
OnPropertyChanged(nameof(LogoUrl));
}
}
the user has the option to change the image using filepicker :
var file = await FilePicker.PickAsync(options);
if (file == null)
{
return;
}
var stream = await file.OpenReadAsync();
MainUrl = ImageSource.FromStream(() => stream);
LblImportLogo = file.FullPath;
Parameter.LogoUrl = file.FullPath;
when I choose an image with filepicker, this one is well displayed and the the path is saved into sqlite table but when I restart the application, the image is no longer displayed despite the path being well informed (this one is external). the problem is in all platforms, UWP,android and IOS. can you help me find a solution.
Mainpage.xaml.cs :
public MainPage()
{
var parameterStore = new SQLiteParameterStore(DependencyService.Get<ISQLiteDb>());
var pageService = new PageService();
ViewModel = new MainPageViewModel(parameterStore, pageService);
InitializeComponent();
NavigationPage.SetHasBackButton(this, false);
NavigationPage.SetHasNavigationBar(this, false);
}
protected override void OnAppearing()
{
ViewModel.LoadDataCommand.Execute(null);
base.OnAppearing();
}
public MainPageViewModel ViewModel
{
get { return BindingContext as MainPageViewModel; }
set { BindingContext = value; }
}
MainPageViewModel :
......
private ImageSource _mainurl;
public ImageSource MainUrl
{
get { return _mainurl; }
set
{
SetValue(ref _mainurl, value);
OnPropertyChanged(nameof(MainUrl));
}
}
......
private async Task LoadData()
{
var parameters = await _parameterStore.GetAll();
var elts = parameters.Count();
if (elts < 1)
{
//set default values
mainParameter = new Parameter();
mainParameter.LogoUrl = "default.jpg";
MainUrl = mainParameter.LogoUrl;
}
else
{
//set parameters
mainParameter = parameters[0];
MainUrl = ImageSource.FromFile(mainParameter.LogoUrl);
}
}

Cannot set property of object in Kotlin using var

I am trying to set the property of an object I've created in Android Studio using Kotlin. I am using a for loop to make a new object each time and add it to an array. When I initialize my object and try to set the topId it says "Val cannot reassigned" even though I'm declaring it a var.
for (i in 1..5) {
var topRanNum = generateRandomNum(topSize)
var top = currentSeasonTops[topRanNum]
var topLoopCounter = 0
var topId = top.id
var newOutfit: Outfit = Outfit()
if(top.wornCount < 5 ) {
newOutfit.topId = top.id
}
}
Outfit Class
public Outfit() {}
public Outfit(Long topId, Long bottomId, String topPhotoPath, String bottomPhotoPath) {
this.topId = topId;
this.bottomId = bottomId;
this.topPhotoPath = topPhotoPath;
this.bottomPhotoPath = bottomPhotoPath;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTopPhotoPath() {
return topPhotoPath;
}
public String getBottomPhotoPath() {
return bottomPhotoPath;
}
public Long getTopId() {
return topId;
}
public Long getBottomId() {
return bottomId;
}
This happens because you need to declare an accessible setter from outside in Java for topId or make the variable accessible from outside.
E.g.
public void setTopId(Long topId) {
this.topId = topId;
}

Add items to a List in Firebase in Android

I am having a hard time trying to figure out how to add more items dynamically to a List in Firebase. As of now I am able to add just one item at the correct firebase location. The user needs to be able to add more items to the list. I am using a custom model class for the data. I would greatly appreciate any help, Thanks.
FloatingActionButton floatSave = (FloatingActionButton) rootView.findViewById(R.id.fabSave);
floatSave.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
myFirebaseRef = new Firebase("https://you.firebaseio.com/");
myFirebaseRef = new Firebase("https://you.firebaseio.com/" + "/users/" + myFirebaseRef.getAuth().getUid());
String partyname = partyName.getText().toString();
String when = fromDateEtxt.getText().toString();
String timeOf = fromTimeEtxt.getText().toString();
String userItems1 = addThisItem.getText().toString();
userItems.add(userItems1);
Map<String,Object> values = new HashMap<>();
values.put("partyname", partyname);
values.put("When", when);
values.put("timeOf", timeOf);
values.put("userItems", userItems);
myFirebaseRef.push().setValue(values);
}
});
//Here is how I try to add additional items to the "userItems" List
final Button addItem = (Button) rootView.findViewById(R.id.buttonAddItem);
addItem.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SharedPreferences pref = getActivity().getSharedPreferences("MyPref", 0);
SharedPreferences.Editor editor = pref.edit();
String savedParty = pref.getString("thisPostKey", null);
myFirebaseRef = new Firebase("https://you.firebaseio.com/users/8d5d9915-54d8-4fc1-b92f-b45569e8089b/"+ savedParty + "/userItems");
String additem = addThisItem.getText().toString();
userItems.add(additem);
myFirebaseRef.push().setValue(additem);
System.out.println("There are " + thisKey + savedParty);
}
});
public class PartyPost {
private String partyname;
private String timeOf;
private String when;
private List userItems;
public PartyPost(String partyname, String timeOf, String when, List userItems) {
// empty default constructor, necessary for Firebase to be able to deserialize blog posts
this.partyname = partyname;
this.timeOf = timeOf;
this.when = when;
this.userItems = userItems;
}
public void setPartyname(String partyname) {
this.partyname = partyname;
}
public void setTimeOf(String timeOf) {
this.timeOf = timeOf;
}
public void setWhen(String when) {
this.when = when;
}
public void setUserItems(List<String> userItems) {
this.userItems = userItems;
}
public String getPartyname() {
return partyname;
}
public String getTimeOf() {
return timeOf;
}
public String getWhen() {
return when;
}
public List getUserItems() {
return userItems;
}
}
{
"users" : {
"8d5d9915-54d8-4fc1-b92f-b45569e8089b" : {
"-KDcHcfvc3CM-d8TWPE9" : {
"When" : "2-2-2017",
"partyname" : "Super Bowl",
"timeOf" : "5:00PM",
"userItems" : [ "Beer" ]
},
"-KDcHcjRbxXzCvRFa-No" : {
"userItems" : {
"-KDcLXIJ7I9TUFEDyyrA" : "Chips"
}
}
}
}
}
Your /userItems node has child node and per the question it has one child.
"userItems" : {
"-KDcLXIJ7I9TUFEDyyrA" : "Chips"
}
It appears you want to add additional children to that node. To add another child, you will need the path to that specific userItems node, here is pseudo-code
thisUsersUserItemsRef = /users/8d5d9915-54d8-4fc1-b92f-b45569e8089b/-KDcHcjRbxXzCvRFa-No/userItems
then push() the values
values.put("another_user_item", "docs ftw");
thisUsersUserItemsRef.push().setValue(values);
This will result in
"-KDcHcjRbxXzCvRFa-No" : {
"userItems" : {
"-KDcLXIJ7I9TUFEDyyrA" : "Chips",
"-JHoijoiqjodj8jkadiQ" {
"another_user_item": "docs ftw"
}
}
}

Binding Class in MVVM Light to RelayCommand in Xamarin

I am trying to bind the following class to a relaycommand.
public class UserAuth
{
public string UserName { get; set; }
public string Password { get; set; }
}
This is my MainActivity Class:
public partial class MainActivity : ActivityBaseEx
{
private Binding<string, UserAuth> _userInformation;
private Binding<string, UserAuth> _cool;
public LoginViewModel LoginViewModel
{
get
{
return App.Locator.Login;
}
}
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
_userInformation = this.SetBinding(()=> **....... WHAT GOES HERE!! I can do this for a simple string, but cannot figure it out for a class!**
// Get our button from the layout resource and attach an event to it
var signInButton = FindViewById<Button>(Resource.Id.btnSingIn);
signInButton.SetCommand("Click", LoginViewModel.LoginCommand, _userInformation);
}
}
This is my RelayCommand in my View Model
public RelayCommand<UserAuth> LoginCommand
{
get
{
return _loginCommand ?? (_loginCommand = new RelayCommand<UserAuth>(
async (userAuth) =>
{
_isLoading = true;
try
{
// var loggedIn = await _loginService.AuthenticateUser("emediaqa1", "p098765");
var loggedIn = await _loginService.AuthenticateUser(userAuth.UserName, userAuth.Password);
_isLoading = false;
}
catch (Exception ex)
{
var dialog = ServiceLocator.Current.GetInstance<IDialogService>();
dialog.ShowError(ex, "Error Authenticating", "OK", null);
}
_isLoading = false;
}));
}
}
My problem is with this line:
_userInformation = this.SetBinding(()=> // WHAT GOES HERE!! I can do this for a simple
//string, but cannot figure it out for a class!
Please help!
Thanks!!
I use something like this in the MainActivity.OnCreate:
_usernameBinding = this.SetBinding(() => Vm.userAuth.Username, () => Username.Text, BindingMode.TwoWay);
_passwordBinding = this.SetBinding(() => Vm.userAuth.Password, () => Password.Text, BindingMode.TwoWay);
So you need 2 bindings, one for userName and one for Password.

How to pass List via intent from one activity to another activity in android using xamarin

i am new to Xamarin. I need to pass List of data as from one activity to another activity via intent .and get those data in another activity screen and process those data's. Please suggest a solution.
Thanks in advance
Use IList of generic type to pass data to the required data from one activity to another.
IList<String> Mon_year = new List<String>();
then pass this List in the intent
i.PutStringArrayListExtra("month_year",Mon_year);
In Another activity(where you want to get the sent data)
IList<String> Mon_year = Intent.GetStringArrayListExtra("month_year") ;// here u get the Ilist of String data...
I approached this a bit differently. I created a base class which inherited from Java.Lang.Object, ISerializable so that I could use Bundle.PutSerializable(string key, ISerializable value) to pass my objects between Activities.
[Flags]
public enum ObjectState
{
Normal = 0,
New = 1,
Modified = 2,
Removed = 4
}
public abstract class ObjectBase : Java.Lang.Object, ISerializable
{
public Guid Id { get; set; }
public ObjectState State { get; set; }
protected ObjectBase(IntPtr handle, JniHandleOwnership transfer) : base(handle, transfer)
{
}
protected ObjectBase()
{
}
[Export("readObject", Throws = new[] { typeof(IOException), typeof(Java.Lang.ClassNotFoundException) })]
private void ReadObject(ObjectInputStream stream)
{
this.Deserialize(stream);
}
[Export("writeObject", Throws = new[] { typeof(IOException), typeof(Java.Lang.ClassNotFoundException) })]
private void WriteObject(ObjectOutputStream stream)
{
this.Serialize(stream);
}
protected virtual void Deserialize(ObjectInputStream stream)
{
this.Id = Guid.Parse(stream.ReadUTF());
this.State = (ObjectState)stream.ReadInt();
}
protected virtual void Serialize(ObjectOutputStream stream)
{
stream.WriteUTF(this.Id.ToString());
stream.WriteInt((int)this.State);
}
}
public class Person : ObjectBase
{
public string Name { get; set; }
public int Age { get; set; }
public bool IsMarried { get; set; }
public DateTime? Anniversary { get; set; }
protected override void Deserialize(ObjectInputStream stream)
{
base.Deserialize(stream);
if (stream.ReadBoolean())
this.Name = stream.ReadUTF();
this.Age = stream.ReadInt();
this.IsMarried = stream.ReadBoolean();
if (stream.ReadBoolean())
this.Anniversary = DateTime.Parse(stream.ReadUTF());
}
protected override void Serialize(ObjectOutputStream stream)
{
base.Serialize(stream);
stream.WriteBoolean(this.Name != null);
if (this.Name != null)
stream.WriteUTF(this.Name);
stream.WriteInt(this.Age);
stream.WriteBoolean(this.IsMarried);
stream.WriteBoolean(this.Anniversary != null);
if (this.Anniversary != null)
stream.WriteUTF(this.Anniversary.Value.ToString(CultureInfo.InvariantCulture));
}
}
I can then pass a list of Person objects to a new Activity by doing:
List<Person> persons = new List<Person>();
var intent = new Intent(this, typeof(MyActivity));
var bundle = new Bundle();
for (int i = 0; i < persons.Count; i++)
{
var p = persons[i];
bundle.PutSerializable("Person" + i, p);
}
intent.PutExtras(bundle);
this.StartActivity(intent);
Then Recieve the objects like so:
protected override void OnCreate(Bundle bundle)
{
List<Person> persons = new List<Person>();
int i = 0;
while (bundle.ContainsKey("Person" + i))
{
var p = (Person) bundle.GetSerializable("Person" + i);
persons.Add(p);
i++;
}
base.OnCreate(bundle);
}
For passing a list of content from one activity to other activity you can use parcelable class. Its a type of bundle in which we can pass any type of content from one activity to other activity. The only thing is you just need to customize the parcelable class according to your need.
Please visit this Link or download this sample project so that you can understand more about passing list of content from one activity to other activity.
Hope this will solve your problem.

Categories

Resources