ListView not saving changes after updating its screen - c#

every time i update my screen (change rotation or leave the screen and then go back to it) it doesn't save the updated list and i go back to the default list. thank you in advance <3
MovieActivity:
public class MovieActivity : Activity, ListView.IOnItemClickListener, Android.Views.View.IOnClickListener, ListView.IOnItemLongClickListener
{
public static List<Movie> movieList { get; set; }
MovieAdapter movieAdapter;
ListView lv;
Button btnAdd;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.movie_page);
// Create your application here
btnAdd = FindViewById<Button>(Resource.Id.btnAdd);
Bitmap vannila_sky_pic = Android.Graphics.BitmapFactory.DecodeResource(Application.Context.Resources, Resource.Drawable.Vanilla_Sky);
Bitmap jimmyneutron_pic = Android.Graphics.BitmapFactory.DecodeResource(Application.Context.Resources, Resource.Drawable.Jimmy_Neutron_Boy_Genius_film);
Movie m1 = new Movie(90, "Vanilla Sky", "James", vannila_sky_pic);
Movie m2 = new Movie(124, "jimmy neutron", "arthur", jimmyneutron_pic);
movieList = new System.Collections.Generic.List<Movie>();
movieList.Add(m1);
movieList.Add(m2);
movieAdapter = new MovieAdapter(this, movieList);
lv = FindViewById<ListView>(Resource.Id.lv);
lv.Adapter = movieAdapter;
lv.OnItemClickListener = this;
lv.OnItemLongClickListener = this;
btnAdd.SetOnClickListener(this);
}
protected override void OnResume()
{
base.OnResume();
if (movieAdapter != null)
{
movieAdapter.NotifyDataSetChanged();
}
}
public void OnItemClick(AdapterView parent, View view, int position, long id)
{
Intent intent = new Intent(this, typeof(EditMovieActivity));
Movie temp = MovieActivity.movieList[position];
intent.PutExtra("pos", position);
StartActivity(intent);
}
public void OnClick(View v)
{
if(v == btnAdd)
{
Intent intent = new Intent(this, typeof(EditMovieActivity));
StartActivity(intent);
}
}
public bool OnItemLongClick(AdapterView parent, View view, int position, long id)
{
MovieActivity.movieList.RemoveAt(position);
movieAdapter.NotifyDataSetChanged();
return true;
}
}
EditMovieActivity:` public class EditMovieActivity : Activity, Android.Views.View.IOnClickListener
{
Button btnSave, btnAddPic;
EditText etTitle, etDirector, etAvg, etLength;
Bitmap bitmap;
int pos = -1;
ImageView iv;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.edit_movie);
iv = FindViewById<ImageView>(Resource.Id.ivMovie);
btnSave = FindViewById<Button>(Resource.Id.btnSave);
btnAddPic = FindViewById<Button>(Resource.Id.btnAddPic);
etTitle = FindViewById<EditText>(Resource.Id.etTitle);
etDirector = FindViewById<EditText>(Resource.Id.etDirector);
etAvg = FindViewById<EditText>(Resource.Id.etAvg);
etLength = FindViewById<EditText>(Resource.Id.etLength);
pos = Intent.GetIntExtra("pos", -1);//-1 is default
btnAddPic.SetOnClickListener(this);
btnSave.SetOnClickListener(this);
if (pos != -1)// update
{
Movie temp = MovieActivity.movieList[pos];
Toast.MakeText(this, "position is " + pos, ToastLength.Long).Show();
etTitle.Text = temp.getTitle();
etDirector.Text = temp.getDirector();
etAvg.Text = "" + temp.getAvg();
etLength.Text = "" + temp.getLength();
bitmap = temp.getBitmap();
iv.SetImageBitmap(temp.getBitmap());
}
else // new movie
{
Toast.MakeText(this, "lets add new item ", ToastLength.Long).Show();
}
}
public void OnClick(View v)
{
if (v == btnAddPic)
{
Intent intent = new Intent(Android.Provider.MediaStore.ActionImageCapture);
StartActivityForResult(intent, 0);
}
else
if (v == btnSave)
{
int length = int.Parse(etLength.Text);
int avg = int.Parse(etAvg.Text);
string title = etTitle.Text;
string director = etDirector.Text;
Movie m = null;
if (pos != -1)//updates
{
m = new Movie(length, title, director, bitmap);
MovieActivity.movieList[pos] = m;
Finish();
}
else// adds new movie
{
m = new Movie(length, title, director, bitmap);
MovieActivity.movieList.Add(m);
Finish();
}
}
}
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if (requestCode == 0)//coming from camera
{
if (resultCode == Result.Ok)
{
bitmap = (Android.Graphics.Bitmap)data.Extras.Get("data");
iv.SetImageBitmap(bitmap);
}
}
}
}`
Movie:
public class Movie
{
private int length;
private string title;
private string director;
private int avg;
private Android.Graphics.Bitmap bitmap;
public Movie(int length, string title, string director,Android.Graphics.Bitmap bitmap )
{
this.length = length;
this.title = title;
this.director = director;
this.avg = 0;
this.bitmap = bitmap;
}
public void setBitmap(Android.Graphics.Bitmap bitmap)
{
this.bitmap = bitmap;
}
public Android.Graphics.Bitmap getBitmap()
{
return bitmap;
}
public void setAvg(int avg)
{
this.avg = avg;
}
public int getAvg()
{
return avg;
}
public void setDirector(string director)
{
this.director = director;
}
public string getDirector()
{
return director;
}
public void setTitle(string title)
{
this.title = title;
}
public string getTitle()
{
return title;
}
public void setLength(int length)
{
this.length = length;
}
public int getLength()
{
return length;
}
}
MovieAdapter:
class MovieAdapter:BaseAdapter<Movie>
{
Android.Content.Context context;
List<Movie> objects;
public MovieAdapter(Android.Content.Context context, System.Collections.Generic.List<Movie> objects)
{
this.context = context;
this.objects = objects;
}
public List<Movie> GetList()
{
return this.objects;
}
public override long GetItemId(int position)
{
return position;
}
public override int Count
{
get { return this.objects.Count; }
}
public override Movie this[int position]
{
get { return this.objects[position]; }
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
Android.Views.LayoutInflater layoutInflater = ((MovieActivity)context).LayoutInflater;
Android.Views.View view = layoutInflater.Inflate(Resource.Layout.movie_layoutxml, parent, false);
TextView tvTitle = view.FindViewById<TextView>(Resource.Id.tvTitle);
TextView tvDirector = view.FindViewById<TextView>(Resource.Id.tvDirector);
TextView tvLength = view.FindViewById<TextView>(Resource.Id.tvlength);
TextView tvAvg = view.FindViewById<TextView>(Resource.Id.tvAvg);
ImageView ivCover = view.FindViewById<ImageView>(Resource.Id.ivCover);
Movie temp = objects[position];
if(temp != null)
{
ivCover.SetImageBitmap(temp.getBitmap());
tvAvg.Text = "" + temp.getAvg();
tvTitle.Text = temp.getTitle();
tvLength.Text ="" + temp.getLength();
tvDirector.Text = temp.getDirector();
}
return view;
}
}

According to your description, listview don't update when you change some listview item.
I do one sample that you can take a look, create public static List and ListAdapter.
public class MainActivity : AppCompatActivity
{
public static List<Earthquake> earthquakes;
ListView lvw;
public static EarthquakeListAdapter listadapter;
Button btnadd;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
earthquakes = new List<Earthquake>
{
new Earthquake{Place="Nepal", DateOccured="May 12, 2015" },
new Earthquake{Place="Solomon Sea", DateOccured="May 7, 2015" },
new Earthquake{Place="Papua New Guinea", DateOccured="May 5, 2015" },
new Earthquake{Place="Nepal", DateOccured="April 25, 2015" },
new Earthquake{Place="Taiwan", DateOccured="April 20, 2015" },
new Earthquake{Place="Papua New Guinea", DateOccured="March 29, 2015" },
new Earthquake{Place="Flores Sea", DateOccured="Febdruary 27, 2015" },
new Earthquake{Place="Mid-Atlantic range", DateOccured="Febdruary 13, 2015" }
};
lvw = FindViewById<ListView>(Resource.Id.lvwEarthquakes);
btnadd = FindViewById<Button>(Resource.Id.button1);
btnadd.Click += Btnadd_Click;
listadapter= new EarthquakeListAdapter(this, earthquakes);
lvw.Adapter = listadapter;
lvw.ItemLongClick += Lvw_ItemLongClick; ;
lvw.ItemClick += Lvw_ItemClick;
}
protected override void OnResume()
{
Log.Debug("OnResume", "OnResume called, app is ready to interact with the user");
base.OnResume();
listadapter = new EarthquakeListAdapter(this, earthquakes);
lvw.Adapter = listadapter;
}
private void Lvw_ItemLongClick(object sender, AdapterView.ItemLongClickEventArgs e)
{
var item = earthquakes[e.Position];
MainActivity.earthquakes.Remove(item);
List<Earthquake> items = MainActivity.earthquakes;
listadapter = new EarthquakeListAdapter(this, earthquakes);
lvw.Adapter = listadapter;
}
private void Lvw_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
{
Intent intent = new Intent(this, typeof(editActivity));
//Earthquake temp = MainActivity.earthquakes[e.Position];
string position = e.Position.ToString();
intent.PutExtra("p", position);
StartActivity(intent);
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
public class Earthquake
{
public string Place { get; set; }
public string DateOccured { get; set; }
}
public class EarthquakeListAdapter : BaseAdapter<Earthquake>
{
List<Earthquake> earthquakes;
Activity context;
/// <summary>
/// Constructor
/// </summary>
/// <param name="context"></param>
/// <param name="earthquakeList"></param>
public EarthquakeListAdapter(Activity currentContext, List<Earthquake> earthquakeList) : base()
{
this.earthquakes = earthquakeList;
this.context = currentContext;
}
public override Earthquake this[int position]
{
get { return earthquakes.ToArray()[position]; }
}
public override int Count
{
get { return earthquakes.Count; }
}
public override long GetItemId(int position)
{
return position;
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
View view = convertView;
if (view == null)
{
view = context.LayoutInflater.Inflate(Android.Resource.Layout.SimpleListItem2, null);
view.FindViewById<TextView>(Android.Resource.Id.Text1).Text = earthquakes.ToArray()[position].Place;
view.FindViewById<TextView>(Android.Resource.Id.Text2).Text = earthquakes.ToArray()[position].DateOccured;
}
return view;
}
}
public class editActivity : Activity
{
EditText edittext1;
EditText edittext2;
int position;
Button button;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.editlayout1);
// Create your application here
edittext1 = FindViewById<EditText>(Resource.Id.editText1);
edittext2 = FindViewById<EditText>(Resource.Id.editText2);
button = FindViewById<Button>(Resource.Id.button1);
button.Click += Butto1_Click;
string text = Intent.GetStringExtra("p");
position = Convert.ToInt32(text);
edittext1.Text = MainActivity.earthquakes[position].Place;
edittext2.Text = MainActivity.earthquakes[position].DateOccured;
}
private void Butto1_Click(object sender, EventArgs e)
{
MainActivity.earthquakes[position] = new Earthquake() { Place = edittext1.Text, DateOccured = edittext2.Text };
OnBackPressed();
}
}

Related

Check custom listview items on Activity start

I have a custom Listview in my C# Android, each row contains one textview and one checkbox. I am saving the value (or the text) of the selected row's textview in a public list named usercoin. Each time the user opens the app, the list usercoin will contain the text of the his textview selected items, and I am doing that using SQLite. The problem is I want to re-check the items which the user have previously selected automatically when the activity starts which are stored in the usercoin list as I have previously noted. But I am not able to achieve this.
MainActivity.cs
ListView mListView;
MyAdapter adapter;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
mListView = FindViewById<ListView>(Resource.Id.listview);
List<TableList> list = new List<TableList>();
list.Add(new TableList("Germany",false));
list.Add(new TableList("France", false));
list.Add(new TableList("Finland", false));
list.Add(new TableList("Germany", false));
list.Add(new TableList("France", false));
list.Add(new TableList("Germany", false));
list.Add(new TableList("France", false));
list.Add(new TableList("Finland", false));
adapter = new MyAdapter(this, list);
mListView.Adapter = adapter;
mListView.ItemClick += MListView_ItemClick;
}
private void MListView_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
{
var t = list[e.Position];
string selected = t.name;
var ll = e.View as LinearLayout;
var cb = ll.GetChildAt(2) as CheckBox;
if (cb.Checked)
{
cb.Checked = false;
adapter.changeState((int)cb.Tag, false);
}
else
{
cb.Checked = true;
adapter.changeState((int)cb.Tag, true);
}
}
class MyAdapter : BaseAdapter
{
Context mContext;
List<TableList> mitems;
public MyAdapter(Context context, List<TableList> list)
{
this.mContext = context;
this.mitems = list;
}
public override int Count
{
get
{
return mitems.Count;
}
}
public override Java.Lang.Object GetItem(int position)
{
return mitems[position];
}
public override long GetItemId(int position)
{
return position;
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
DataViewHolder holder = null;
if (convertView == null)
{
convertView = LayoutInflater.From(mContext).Inflate(Resource.Layout.CoinList, null, false);
holder = new DataViewHolder();
holder.tv = convertView.FindViewById<TextView>(Resource.Id.CoinName);
holder.iv = convertView.FindViewById<ImageView>(Resource.Id.imageView1);
holder.cb = convertView.FindViewById<CheckBox>(Resource.Id.checkBox1);
convertView.Tag = holder;
}
else
{
holder = convertView.Tag as DataViewHolder;
}
holder.cb.Tag = position;
holder.tv.Text = mitems[position].Name;
holder.cb.Focusable = false;
holder.cb.Checked = mitems[position].bl;
holder.iv.SetImageResource(Resource.Drawable.dapao);
holder.cb.CheckedChange += Cb_CheckedChange;
return convertView;
}
private void Cb_CheckedChange(object sender, CompoundButton.CheckedChangeEventArgs e)
{
var cb = sender as CheckBox;
if (e.IsChecked && !mitems[(int)cb.Tag].bl)
{
mitems[(int)cb.Tag].bl = true;
this.NotifyDataSetChanged();
}
else if (!e.IsChecked && mitems[(int)cb.Tag].bl)
{
mitems[(int)cb.Tag].bl = false;
this.NotifyDataSetChanged();
}
}
internal void changeState(int tag, bool v)
{
mitems[tag].bl = v;
this.NotifyDataSetChanged();
}
}
public class DataViewHolder : Java.Lang.Object
{
public ImageView iv { get; set; }
public TextView tv { get; set; }
public CheckBox cb { get; set; }
}
public class TableList : Java.Lang.Object
{
private string v;
public TableList(string name, bool b)
{
this.Name = name;
this.bl = b;
}
public string Name { get; set; }
public bool bl { get; set; }
}
}
}
For example, when the user first run the app and select France and Germany from the listview, next time he re-opens the app, the usercoin list will contain France and Germany. Now the question is how can I check the checkboxes corresponding to those values in the listview. I have tried to do so by including this code in MyAdapter : BaseAdapter class:
if (Class1.usercoin.Contains(item.CoinAbr))
{
Class1.adapter[(int)holder.cb.Tag].bl = true;
this.NotifyDataSetChanged();
}
But when this code get executed, the previously checked items are checked plus some other items which the user haven't checked previously are also checked. So how can I check the previously checked items in the Listview on the app start ? Please help me to find a solution.

Xamarin Location Service OnLocationChanged dont trigger

We have one problem where it happen randomly on certain devices which is the OnLocationChanged event cannot be triggered.
LocationManager.RequestLocationUpdates(LocationManager.GpsProvider, 30000, 100, this);
LocationManager.RequestLocationUpdates(LocationManager.NetworkProvider, 30000, 100, this);
We also try set a timer, if after a minute, the event didn't trigger, we will try get the last known location, but it still returning null.
CurrentLocation = LocationManager.GetLastKnownLocation(LocationManager.GpsProvider);
LocationManager.RequestLocationUpdates(LocationManager.GpsProvider, 0, 0, this);
if (CurrentLocation == null)//network provider
{
CurrentLocation = LocationManager.GetLastKnownLocation(LocationManager.NetworkProvider);
LocationManager.RequestLocationUpdates(LocationManager.NetworkProvider, 0, 0, this);
}
if (CurrentLocation == null)//passive provider
{
CurrentLocation = LocationManager.GetLastKnownLocation(LocationManager.PassiveProvider);
LocationManager.RequestLocationUpdates(LocationManager.PassiveProvider, 0, 0, this);
}
May I know what wrong with my code ?
Edited (Complete Code) :
public class LocationService : Service, ILocationListener
{
public IBinder Binder { get; private set; }
public MainActivity MainAC { get { return m_ac; } set { m_ac = value; } }
public Android.Locations.Location CurrentLocation { get; set; }
public Android.Locations.LocationManager LocationManager { get; set; }
public DateTime LastUpdateTime { get; set; }
public bool IsMockLocation { get; set; }
public string CurrentAddress { get; set; }
public string CurrentCity { get; set; }
private int iUpdateLocationInterval = 30000;// 30sec
private int iUpdateLocationDistance = 100;// 100meter
private int iUpdateLocationInterval_LastKnown = 0;// 0sec
private int iUpdateLocationDistance_LastKnown = 0;// 0meter
private System.Timers.Timer timerBackground = null;
private MainActivity m_ac;
private Lib.GoogleMaps google = new Lib.GoogleMaps();
private bool bUpdateLocationIntervalUnknown = false;
public LocationService()
{
}
#region Override Function
public override void OnCreate()
{
base.OnCreate();
}
[return: GeneratedEnum]
public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
{
StartCommandResult result = base.OnStartCommand(intent, flags, startId);
return result;
}
public override void OnDestroy()
{
Binder = null;
if (LocationManager != null)
{
LocationManager.RemoveUpdates(this);
}
base.OnDestroy();
}
public override IBinder OnBind(Intent intent)
{
// Return the communication channel to the service.
this.Binder = new LocalLocationBinder(this);
return this.Binder;
}
#endregion
private void StartBackgroundTimer()
{
timerBackground = new System.Timers.Timer();
timerBackground.Elapsed -= TimerBackground_Elapsed;
timerBackground.Elapsed += TimerBackground_Elapsed;
timerBackground.Interval = 10000;
timerBackground.AutoReset = false;
timerBackground.Enabled = true;
}
private void TimerBackground_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
timerBackground.Enabled = false;
try
{
if (CurrentLocation == null)// OnLocationChanged didnt trigger, so get from last known location
{
GetLastKnownLocation();
}
}
catch { }
}
public void GetLastKnownLocation()
{
m_ac.RunOnUiThread(() =>
{
bUpdateLocationIntervalUnknown = true;
CurrentLocation = LocationManager.GetLastKnownLocation(LocationManager.GpsProvider);
LocationManager.RequestLocationUpdates(LocationManager.GpsProvider, iUpdateLocationInterval_LastKnown, iUpdateLocationDistance_LastKnown, this);
if (CurrentLocation == null)//network provider
{
CurrentLocation = LocationManager.GetLastKnownLocation(LocationManager.NetworkProvider);
LocationManager.RequestLocationUpdates(LocationManager.NetworkProvider, iUpdateLocationInterval_LastKnown, iUpdateLocationDistance_LastKnown, this);
}
if (CurrentLocation == null)//passive provider
{
CurrentLocation = LocationManager.GetLastKnownLocation(LocationManager.PassiveProvider);
LocationManager.RequestLocationUpdates(LocationManager.PassiveProvider, iUpdateLocationInterval_LastKnown, iUpdateLocationDistance_LastKnown, this);
}
if (CurrentLocation != null)
{
UpdateCurrentLocationInterval();
ResolveGPSCoordinates(CurrentLocation);
}
else
{
m_ac.UpdateLocationName(Function.GetLanguage(m_ac, Resource.String.lblLocationServiceGetFailure));
}
});
}
// Location GPS
public void InitializeLocationManager()
{
try
{
m_ac.RunOnUiThread(() =>
{
try
{
if (LocationManager != null) return;
LocationManager = (LocationManager)GetSystemService(LocationService);
Criteria criteriaForLocationService = new Criteria
{
Accuracy = Accuracy.Fine
};
IList<string> acceptableLocationProviders = LocationManager.GetProviders(criteriaForLocationService, true);
if (!LocationManager.IsProviderEnabled(LocationManager.GpsProvider))
{
m_ac.ShowMessageToast(Function.GetLanguage(this, Resource.String.lblGPSLocationIsNotEnabled));
return;
}
if (acceptableLocationProviders.Any())
{
StartBackgroundTimer();
LocationManager.RequestLocationUpdates(LocationManager.GpsProvider, iUpdateLocationInterval, iUpdateLocationDistance, this);
LocationManager.RequestLocationUpdates(LocationManager.NetworkProvider, iUpdateLocationInterval, iUpdateLocationDistance, this);
}
else
{
m_ac.ShowMessageToast(Function.GetLanguage(this, Resource.String.lblGPSLocationIsNotEnabled));
}
}
catch(Exception ex) { m_ac.ShowMessageToast("ERROR:" + ex.Message); }
});
}
catch (Exception ex) { m_ac.ShowMessageToast("ERROR:" + ex.Message); }
}
private void UpdateCurrentLocationInterval()
{
try
{
if (LocationManager != null)
{
bUpdateLocationIntervalUnknown = false ;
LocationManager.RequestLocationUpdates(LocationManager.GpsProvider, iUpdateLocationInterval, iUpdateLocationDistance, this);
LocationManager.RequestLocationUpdates(LocationManager.NetworkProvider, iUpdateLocationInterval, iUpdateLocationDistance, this);
}
}
catch { }
}
public void OnLocationChanged(Location location)
{
LastUpdateTime = DateTime.Now;
IsMockLocation = true;
CurrentLocation = location;
CurrentAddress = string.Empty;
CurrentCity = string.Empty;
if (bUpdateLocationIntervalUnknown)
{
UpdateCurrentLocationInterval();
}
if (location.IsFromMockProvider)
{
CurrentLocation = null;
m_ac.UpdateLocationName(CurrentCity);
}
else
{
IsMockLocation = false;
ResolveGPSCoordinates(location);
}
}
private void ResolveGPSCoordinates(Location location)
{
ResolveGPSCoordinatesAwait(location);
}
private async void ResolveGPSCoordinatesAwait(Location location)
{
int iResult = await google.ResolveLatLng(location.Latitude, location.Longitude);
if (iResult == 0)
{
CurrentAddress = google.AddressName;
CurrentCity = google.CityName;
if(CurrentCity == string.Empty)
m_ac.UpdateLocationName(Function.GetLanguage(m_ac, Resource.String.lblLocationServiceGetFailure));
else
m_ac.UpdateLocationName(CurrentCity);
}
else if (iResult == -2)
{
m_ac.UpdateLocationName(Function.GetLanguage(m_ac, Resource.String.lblLocationServiceExceedAPIQuota));
}
else
{
if (string.IsNullOrEmpty(google.APIErrorMessage))
{
m_ac.UpdateLocationName("ERROR:" + location.Latitude + "," + location.Longitude );
}
else
{
m_ac.UpdateLocationName(google.APIErrorMessage);
}
}
}
public void OnProviderDisabled(string provider)
{
if (provider.Equals(LocationManager.GpsProvider, StringComparison.InvariantCultureIgnoreCase))
{
LastUpdateTime = DateTime.Now;
IsMockLocation = false;
CurrentLocation = null;
CurrentAddress = string.Empty;
CurrentCity = Function.GetLanguage(m_ac, Resource.String.lblLocationServiceDisable);
m_ac.UpdateLocationName(CurrentCity);
}
}
public void OnProviderEnabled(string provider)
{
UpdateCurrentLocationInterval();
}
public void OnStatusChanged(string provider, [GeneratedEnum] Availability status, Bundle extras)
{
}
}
public class LocationServiceConnection : Java.Lang.Object, IServiceConnection
{
MainActivity m_ac = null;
public LocationServiceConnection(MainActivity activity)
{
m_ac = activity;
IsConnected = false;
Binder = null;
}
public bool IsConnected { get; private set; }
public LocalLocationBinder Binder { get; private set; }
public void OnServiceConnected(ComponentName name, IBinder service)
{
Binder = service as LocalLocationBinder;
IsConnected = this.Binder != null;
Binder.Service.MainAC = m_ac;
Binder?.Service.InitializeLocationManager();
}
public void OnServiceDisconnected(ComponentName name)
{
IsConnected = false;
Binder.Service.MainAC = null;
Binder = null;
}
public void GetLastKnownLocation()
{
Binder?.Service.GetLastKnownLocation();
}
}
#region LocalBinder
public class LocalLocationBinder : Binder
{
public LocalLocationBinder(LocationService service)
{
this.Service = service;
}
public LocationService Service { get; private set; }
}
#endregion
Well I would suggest you check if the location services are provided and by that I mean are they turned on if not doing that would solve the issue also what you can do is if these services are not available or you can say are currently declined you can simply use this to check if it's available or not and in that way apply your own code to it which could determine if you continue forward to the maps page or not.
public class LocationEnabled : Fragment
{
public GoogleApiClient googleApiClient;
// static int REQUEST_LOCATION = 199;
public const int MIN_TIME_BW_UPDATES = 1000 * 3;
public const int REQUEST_CHECK_SETTINGS = 9000;
AppCompatActivity _activity;
public LocationEnabled(AppCompatActivity activity)
{
_activity = activity;
}
private bool hasGPSDevice(Context context)
{
LocationManager mgr = (LocationManager)context.GetSystemService(Context.LocationService);
if (mgr == null)
return false;
IList<string> providers = mgr.AllProviders;
if (providers == null)
return false;
return providers.Contains(LocationManager.GpsProvider);
}
private async void enableLoc()
{
if (googleApiClient == null)
{
googleApiClient = new GoogleApiClient.Builder(_activity)
.AddApi(LocationServices.API)
.AddConnectionCallbacks(new CallBackHelper(googleApiClient))
.AddOnConnectionFailedListener(new ConnectionFailedCallBack(_activity)).Build();
googleApiClient.Connect();
LocationRequest locationRequest = LocationRequest.Create();
locationRequest.SetPriority(LocationRequest.PriorityHighAccuracy);
locationRequest.SetInterval(MIN_TIME_BW_UPDATES);
locationRequest.SetFastestInterval(MIN_TIME_BW_UPDATES/2);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.AddLocationRequest(locationRequest);
builder.SetAlwaysShow(true);
LocationSettingsResult locationSettingsResult =
await LocationServices.SettingsApi.CheckLocationSettingsAsync(googleApiClient, builder.Build());
switch (locationSettingsResult.Status.StatusCode)
{
case LocationSettingsStatusCodes.Success:
Toast.MakeText(_activity, "SUCCESS", ToastLength.Short).Show();
break;
case LocationSettingsStatusCodes.ResolutionRequired:
try
{
locationSettingsResult.Status.StartResolutionForResult(_activity, REQUEST_CHECK_SETTINGS);
}
catch (Exception e)
{
Toast.MakeText(_activity, "CANCEL: " + e.Message, ToastLength.Short).Show();
}
break;
default:
googleApiClient.Disconnect();
break;
}
}
}
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
LocationManager manager = (LocationManager)_activity.GetSystemService(Context.LocationService);
if (manager.IsProviderEnabled(LocationManager.GpsProvider) && hasGPSDevice(_activity))
{
Intent intent = new Intent(_activity, typeof(GoogleMapsActivity));
StartActivity(intent);
}
if (!hasGPSDevice(_activity))
{
Toast.MakeText(_activity, "Gps not Supported", ToastLength.Long).Show();
}
if (!manager.IsProviderEnabled(LocationManager.GpsProvider) && hasGPSDevice(_activity))
{
enableLoc();
}
else
{
}
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return base.OnCreateView(inflater, container, savedInstanceState);
}
}
public class ConnectionFailedCallBack : Java.Lang.Object, GoogleApiClient.IOnConnectionFailedListener
{
Context _context;
public ConnectionFailedCallBack(Context context)
{
_context = context;
}
public void OnConnectionFailed(ConnectionResult result)
{
Toast.MakeText(_context, "Location connection failed.", ToastLength.Short).Show();
}
}
public class CallBackHelper : Java.Lang.Object, GoogleApiClient.IConnectionCallbacks
{
GoogleApiClient googleApiClient;
public CallBackHelper(GoogleApiClient googleApiClient)
{
this.googleApiClient = googleApiClient;
}
public void OnConnected(Bundle connectionHint)
{
}
public void OnConnectionSuspended(int cause)
{
googleApiClient.Connect();
}
}
And get the result on your fragment host activity using this :
protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if (requestCode == LocationEnabled.REQUEST_CHECK_SETTINGS)
{
switch (resultCode)
{
case Result.Canceled:
//negative result
break;
case Result.Ok:
//positive result
break;
case Result.FirstUser:
default:
break;
}
}
}
Goodluck!

how to populate date from webservice to xamarin android

I can't populate date from webservice to xamarin android
namespace Printopack
{
[Activity(Label = "Mainlistview", Icon = "#drawable/icon")]
public class Mainlistview : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Mainlistview);
ListView ListView = FindViewById<ListView>(Resource.Id.listView1);
Selling.WebServiceDB ws = new Selling.WebServiceDB();
ws.OrderStatusListCompleted += Ws_OrderStatusListCompleted;
ws.OrderStatusListAsync(Convert.ToString(1));
}
private void Ws_OrderStatusListCompleted(object sender, Selling.OrderStatusListCompletedEventArgs e)
{
ListView ListView = FindViewById<ListView>(Resource.Id.listView1);
string msg = "";
if (e.Result.ToString().Equals("0"))
{
msg = e.Result.ToString();
}
else
{
// full class
List<TableItem> tableItems = new List<TableItem>();
tableItems.Add(new TableItem("" + e.Result, "" + e.Result, Resource.Drawable.Icon));
ListView.Adapter = new HomeScreenAdapter(this, tableItems);
}
}
// adpater manage
public class HomeScreenAdapter : BaseAdapter<TableItem>
{
List<TableItem> items;
Activity context;
public HomeScreenAdapter(Activity context, List<TableItem> items)
: base()
{
this.context = context;
this.items = items;
}
public override long GetItemId(int position)
{
return position;
}
public override TableItem this[int position]
{
get { return items[position]; }
}
public override int Count
{
get { return items.Count; }
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
var item = items[position];
View view = convertView;
if (view == null) // no view to re-use, create new
view = context.LayoutInflater.Inflate(Resource.Layout.Ticket_News, null);
view.FindViewById<TextView>(Resource.Id.Text1).Text = item.Heading;
view.FindViewById<TextView>(Resource.Id.Text2).Text = item.SubHeading;
view.FindViewById<ImageView>(Resource.Id.Image).SetImageResource(item.ImageResourceId);
return view;
}
}
public class TableItem
{
public string Heading;
public string SubHeading;
public int ImageResourceId;
public TableItem(string Heading, string SubHeading, int ImageResourceId)
{
this.Heading = Heading;
this.SubHeading = SubHeading;
this.ImageResourceId = ImageResourceId;
}
}
}
}
I think the error is in this line:
tableItems.Add(new TableItem("" + e.Result, "" + e.Result, Resource.Drawable.Icon));
You're adding the e.Result as one item and I think the Result holds the complete list. You should loop through the entries in the e.Result and call tableItems.Add for each of them.
Similar to this:
foreach (var item in e.Result)
{
tableItems.Add(new TableItem("" + item.Property, "" + item.Property1, Resource.Drawable.Icon));
}

Android.App.Activity is a type but a variable was expected

string[] arrays = new string[] { "A", "B", "C", "D", "E", "F" };
ListView lstItems;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
// Get our button from the layout resource,
// and attach an event to it
lstItems = FindViewById<ListView>(Resource.Id.listView1);
lstItems.Adapter = new CustomAdapter(Activity, arrays);
}
public class CustomAdapter : BaseAdapter
{
//private const int TYPE_ITEM = 0;
//private const int TYPE_SEPARATOR = 1;
string[] mData;
//private TreeSet sectionHeader;
LayoutInflater mInflater;
public CustomAdapter(Context context, string[] Data)
{
mInflater = LayoutInflater.FromContext(context);
mData = Data;
}
public override int Count
{
get { return mData.Length; }
}
public override Java.Lang.Object GetItem(int position)
{
return mData[position];
}
public override long GetItemId(int position)
{
return position;
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
ViewHolder holder = null;
//var data = mData [position];
if (convertView == null)
{
holder = new ViewHolder();
holder.textViewHeader = (TextView)convertView.FindViewById(Resource.Id.textviewHeaderItems);
holder.textViewSeparator = (TextView)convertView.FindViewById(Resource.Id.textviewItemsSeparator);
convertView.Tag = holder;
}
else
{
holder = (ViewHolder)convertView.Tag as ViewHolder;
}
for (int i = 0; i <= mData.Length - 1; i++)
{
if (i == 0)
{
holder.textViewHeader.Text = "Group A";
}
else if (i == 4)
{
holder.textViewHeader.Text = "Group B";
}
holder.textViewSeparator.Text = mData[i];
}
return convertView;
}
}
public class ViewHolder : Java.Lang.Object
{
public TextView textViewHeader { get; set; }
public TextView textViewSeparator { get; set; }
}
In CustomerAdapter I have a string[] Data parameter. After in OnCreate I got this problem at lstItems.Adapter = new CustomAdapter(Activity, arrays). I don't understand.
I was trying to create a header listview on xamarin android.
I saw several samples but that code has much errors.
You are passing the Activity class name. Instead you should pass an instance of the Activity you are in. You should be instantiating Adapter like below from Activity
lstItems.Adapter = new CustomAdapter (this, arrays);
Activity is a type. What you need is an instance of type Context. In Xamarin Android that's most commonly Android.App.Application.Context.
So your line should look like this:
lstItems.Adapter = new CustomAdapter(Android.App.Application.Context, arrays);

Xamarin passing context from OnClick event

I m a beginner in android dev, I m struggling with passing string Clicked_Message from Click event in Recycle Adapter Class to the other activity. Is it a good way to use Intent? If so how can I pass context to click event? Thanks
public class RecyclerAdapter : RecyclerView.Adapter
{
private RecyclerView mRecyclerView;
private List<NotificationClass> mEmails;
public RecyclerAdapter(List<NotificationClass> emails, RecyclerView recyclerView)
{
mEmails = emails;
mRecyclerView = recyclerView;
}
public class MyView : RecyclerView.ViewHolder
{
public View mMainView { get; set; }
public TextView mName { get; set; }
public TextView mSubject { get; set; }
public TextView mMessage { get; set; }
public MyView(View view) : base(view)
{
mMainView = view;
}
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
View row = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.row, parent, false);
TextView txtName = row.FindViewById<TextView>(Resource.Id.txtName);
TextView txtSubject = row.FindViewById<TextView>(Resource.Id.txtSubject);
TextView txtMessage = row.FindViewById<TextView>(Resource.Id.txtMessage);
MyView view = new MyView(row) { mName = txtName, mSubject = txtSubject, mMessage = txtMessage };
return view;
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
MyView myHolder = holder as MyView;
int indexPosition = (mEmails.Count - 1) - position;
myHolder.mMainView.Click += mMainView_Click;
myHolder.mName.Text = mEmails[position].Name;
myHolder.mSubject.Text = mEmails[position].Subject;
myHolder.mMessage.Text = mEmails[position].Message;
}
public override int ItemCount
{
get { return mEmails.Count; }
}
public void OnClick(int position)
{
if (ItemClick != null)
ItemClick(this, position);
}
public void mMainView_Click(object sender, EventArgs e,Context context)
{
int position = mRecyclerView.GetChildPosition((View)sender);
int indexPosition = (mEmails.Count - 1) - position;
Console.WriteLine(mEmails[indexPosition].Message);
string Clicked_Message = (mEmails[indexPosition].Message);
var activity2 = new Intent(context, typeof(ContactActivity));
activity2.PutExtra("MyData", Clicked_Message);
context.StartActivity(activity2);
}
}
You don't need to pass a context. Just use an intent and put the information you want to pass as extras into the intent.
In case your adapter needs a context, pass it in through the constructor and store it as a field member.
This is my typical implementation of the RecyclerView.Adapter with a view holder...
public class ContactsAdapter : V7.RecyclerView.Adapter
{
private List<Contact> _contacts;
public event EventHandler ItemClick;
public void OnItemClick(ContactViewHolder holder)
{
if (ItemClick != null)
{
ItemClick(holder, EventArgs.Empty);
}
}
public ContactsAdapter(List<Contact> contacts)
: base()
{
_contacts = contacts;
}
public override void OnBindViewHolder(V7.RecyclerView.ViewHolder holder, int position)
{
var contactHolder = (ContactViewHolder)holder;
contactHolder.BindUI(_contacts[position]);
}
public override V7.RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
var view = LayoutInflater.FromContext(parent.Context).Inflate(Resource.Layout.ContactsListItem, parent, false);
return new ContactViewHolder(view)
{
Adapter = this
};
}
public override int ItemCount
{
get
{
return _contacts.Count;
}
}
}
View Holder (typically in the same file as the adapter)
public class ContactViewHolder : V7.RecyclerView.ViewHolder, View.IOnClickListener
{
public TextView ContactNameTextView { get; set; }
public TextView ContactPhoneTextView { get; set; }
public TextView ContactIntialsTextView { get; set; }
public Contact Contact { get; set; }
private WeakReference _adapter;
public ContactsAdapter Adapter
{
get { return (ContactsAdapter)_adapter.Target; }
set { _adapter = new WeakReference(value); }
}
public ContactViewHolder(View view)
: base(view)
{
GetUI(view);
view.SetOnClickListener(this);
}
private void GetUI(View view)
{
ContactNameTextView = view.FindViewById<TextView>(Resource.Id.ContactName);
ContactPhoneTextView = view.FindViewById<TextView>(Resource.Id.ContactPhone);
ContactIntialsTextView = view.FindViewById<TextView>(Resource.Id.ContactInitialsTextView);
}
public void BindUI(Contact contact)
{
Contact = contact;
ContactNameTextView.Text = contact.ContactName;
ContactPhoneTextView.Text = contact.Phone1;
ContactIntialsTextView.Text = contact.Initials;
}
public void OnClick(View v)
{
Adapter.OnItemClick(this);
}
}
This encapsulates the functionality to the view holder. I also give the instance of the adapter to the view holder as a WeakReference. This allows me to call the OnItemClick, passing the instance of the view holder. If you will notice that the view holder also has an instance of the object that it is representing. This means I don't have to worry about the index that was chosen. I already have the object data available to me.
So the implementation in the Activity/Fragment is like this...
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
_contacts = Contact.GetAllContacts();
_adapter = new ContactsAdapter(_contacts);
_adapter.ItemClick += ContactSelected;
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var view = inflater.Inflate(Resource.Layout.ContactsFragment, container, false);
var layoutManager = new V7.LinearLayoutManager(this.Activity) { Orientation = V7.LinearLayoutManager.Vertical };
_contactsView = view.FindViewById<V7.RecyclerView>(Resource.Id.ContactList);
_contactsView.SetAdapter(_adapter);
_contactsView.HasFixedSize = true;
_contactsView.SetLayoutManager(layoutManager);
return view;
}
private void ContactSelected (object sender, EventArgs e)
{
var holder = (ContactViewHolder)sender;
var detailFragment = new ContactDetailsFragment(holder.Contact);
MainActivity.ShowFragment(detailFragment);
}
I give the Contact to a Fragment, but you could do something similar for an activity using an intent.
Now whether this is the most efficient way of handling a click of a row in a RecyclerView, I don't know. But this implementation has been working for me.

Categories