I'm new to app development and I'm trying to create a Recycled View on a Fragment, however there are some problems, it throws the following errors:
Code:
namespace Homecheck.Fragments {
public class SmokeSensor : Fragment {
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private RecyclerView.LayoutManager layoutManager;
private List<ItemData> itemData;
public override void OnCreate(Bundle savedInstanceState) {
base.OnCreate(savedInstanceState);
recyclerView.HasFixedSize = true;
layoutManager = new LinearLayoutManager(Activity);
recyclerView.SetLayoutManager(layoutManager);
itemData = new List<ItemData>();
itemData.Add(new ItemData() {title = "Testing", image = Resource.Drawable.ic_circle_red});
adapter = new MyAdapter(itemData);
recyclerView.SetAdapter(adapter);
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.Inflate(Resource.Layout.SmokeSensor, container, false);
recyclerView = view.FindViewById<RecyclerView>(Resource.Id.smoke_recycler_view);
return view;
}
}
public class MyAdapter : RecyclerView.Adapter {
private List<ItemData> itemData;
private TextView titleText;
private ImageView imageId;
public MyAdapter(List<ItemData> itemData) {
this.itemData = itemData;
}
public class ViewHolder : RecyclerView.ViewHolder {
public View mainView { get; set; }
public TextView title { get; set; }
public ImageView image { get; set; }
public ViewHolder (View view) : base (view) {
mainView = view;
}
}
public override MyAdapter.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType) {
View itemLayoutView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.SmokeItemView, null);
titleText = itemLayoutView.FindViewById<TextView>(Resource.Id.item_title);
imageId = itemLayoutView.FindViewById<ImageView>(Resource.Id.item_icon);
ViewHolder viewHolder = new ViewHolder(itemLayoutView) { title = titleText, image = imageId };
return viewHolder;
}
public override void OnBindViewHolder(ViewHolder viewHolder, int position) {
viewHolder.title.SetText(itemData[position]);
}
public override int getItemCount() {
return itemData.Count();
}
}
public class ItemData {
public string title { get; set; }
public int image { get; set; }
}
}
I know it's most likely a stupid mistake, but I can't seem to find it and fix it.
The return type of OnCreateViewHolder is wrong, it should be Android.Support.V7.Widget.RecyclerView.ViewHolder
You need to override ItemCount:
public override int ItemCount {get{...}}
Wrong parameter type, fix it like this:
public override void OnBindViewHolder(Android.Support.V7.Widget.RecyclerView.ViewHolder viewHolder, int position)
Related
How to put the json object result into a list view using adapter?
Object class
public class ScVsrList
{
public int vnd { get; set; }
public string drref { get; set; }
public int dpt { get; set; }
public string dname { get; set; }
public int sdp { get; set; }
public int cls { get; set; }
public string cname { get; set; }
public int ctn { get; set; }
public List<ScDrList> drList2 { get; set; }
}
public class ScDrList
{
public int vnd2 { get; set; }
public string drref { get; set; }
}
public class StoreConsignorVsrObject
{
public string status { get; set; }
public string env { get; set; }
public string vsr { get; set; }
public string type { get; set; }
public List<ScVsrList> drList { get; set; }
}
*MY CODE USING REST CLIENT FROM XAMARIN ANDROID *
var client = new RestClient("http://10.121.4.72:10010/web/services/getVSRdt");
var request = new RestRequest(Method.POST);
request.AddHeader("Content-type", "application/json");
var requestObject = new VsrRequestObject
{
env = "DSP",
vsr = GlobalVariable.VsrNumber,
token = "967F058F023DA12798F2D41CDC2F2A5C6D4A6F5D40069A80V3S98R9RFPDT"
};
request.AddJsonBody(requestObject);
var response = client.Execute(request);
var content = response.Content;
StoreConsignorVsrObject item = JsonConvert.DeserializeObject<StoreConsignorVsrObject>(content);
if (item != null)
{
LayoutInflater inflate = LayoutInflater.From(this);
View view = inflate.Inflate(Resource.Layout.activity_storeconsignorvsrmonitoring, null);
alertBuilder = new Android.Support.V7.App.AlertDialog.Builder(this);
alertBuilder.SetView(view);
contentDialog = alertBuilder.Create();
BtnReturnDialog = FindViewById<Button>(Resource.Id.btnReturn);
listViewStoreConsignor = FindViewById<ListView>(Resource.Id.listViewStoreConsignor);
listViewStoreConsignor.Adapter = new StoreConsignorDetailAdapter(this, item);
}
else
{
DialogHelper.ShowAlertMessage(this, "Error Data Findings", "No Detail Found");
return;
}
StoreConsignorDetailAdapter
public class StoreConsignorDetailAdapter : BaseAdapter<StoreConsignorVsrObject>
{
private StoreConsignorVsrObject items;
AppCompatActivity activity;
public StoreConsignorDetailAdapter(AppCompatActivity activity, StoreConsignorVsrObject items)
{
this.items = items;
this.activity = activity;
}
public override StoreConsignorVsrObject this[int position]
{
get
{
return items[position];
}
}
public override int Count
{
get
{
return items.Count;
}
}
public override long GetItemId(int position)
{
return position;
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
var item = items[position];
View view = convertView;
if (view == null)
{
view = activity.LayoutInflater.Inflate(Resource.Layout.adapter_storeconsignorvsrmonitoring, null);
}
var detail = item.drList.FirstOrDefault();
view.FindViewById<TextView>(Resource.Id.txtViewVendorNum).Text = detail.vnd.ToString();
view.FindViewById<TextView>(Resource.Id.txtViewVdrNumber).Text = detail.drref.ToString();
view.FindViewById<TextView>(Resource.Id.txtViewTotal).Text = detail.ctn.ToString();
view.FindViewById<TextView>(Resource.Id.txtViewMvdr).Text = detail.drList2.Count.ToString();
view.FindViewById<TextView>(Resource.Id.txtViewDepartment).Text = detail.dname;
view.FindViewById<TextView>(Resource.Id.txtViewStatus).Text = "SHIPPED";
return view;
}
}
Im getting an error from my Adapter
Err 1: cannot apply indexing with to an expression of type 'object' from items[position]
public override StoreConsignorVsrObject this[int position]
{
get
{
return items[position];
}
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
var item = items[position];
View view = convertView;
if (view == null)
{
view = activity.LayoutInflater.Inflate(Resource.Layout.adapter_storeconsignorvsrmonitoring, null);
}
var detail = item.drList.FirstOrDefault();
view.FindViewById<TextView>(Resource.Id.txtViewVendorNum).Text = detail.vnd.ToString();
view.FindViewById<TextView>(Resource.Id.txtViewVdrNumber).Text = detail.drref.ToString();
view.FindViewById<TextView>(Resource.Id.txtViewTotal).Text = detail.ctn.ToString();
view.FindViewById<TextView>(Resource.Id.txtViewMvdr).Text = detail.drList2.Count.ToString();
view.FindViewById<TextView>(Resource.Id.txtViewDepartment).Text = detail.dname;
view.FindViewById<TextView>(Resource.Id.txtViewStatus).Text = "SHIPPED";
return view;
}
ERR 2 Cannot Convert group method Count to a non delegate type 'int':
public override int Count
{
get
{
return items.Count;
}
}
I expect a clean output of my list view through my json outputs. My json is consists also of Json Array, so it's a nested Json.
One problem is the items in your StoreConsignorDetailAdapter should be list not a single Object.So you can define a list variable:
private List<ScVsrList> drList;
You can do like this:
public class StoreConsignorDetailAdapter: BaseAdapter<ScVsrList>
{
private StoreConsignorVsrObject item;
AppCompatActivity activity;
private List<ScVsrList> drList; // defile variable drList
public StoreConsignorDetailAdapter(AppCompatActivity activity, StoreConsignorVsrObject item)
{
this.item = item;
this.activity = activity;
this.drList = item.drList; // assign value to drList
}
public override ScVsrList this[int position]
{
get
{
return drList[position];
}
}
public override int Count
{
get
{
return drList.Count;
}
}
public override long GetItemId(int position)
{
return position;
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
var item = drList[position];
View view = convertView;
if (view == null)
{
view = activity.LayoutInflater.Inflate(Resource.Layout.adapter_storeconsignorvsrmonitoring, null);
}
//var detail = drList.FirstOrDefault();
view.FindViewById<TextView>(Resource.Id.txtViewVendorNum).Text = item.vnd.ToString();
view.FindViewById<TextView>(Resource.Id.txtViewVdrNumber).Text = item.drref.ToString();
view.FindViewById<TextView>(Resource.Id.txtViewTotal).Text = item.ctn.ToString();
view.FindViewById<TextView>(Resource.Id.txtViewMvdr).Text = item.drList2.Count.ToString();
view.FindViewById<TextView>(Resource.Id.txtViewDepartment).Text = item.dname;
view.FindViewById<TextView>(Resource.Id.txtViewStatus).Text = "SHIPPED";
return view;
}
}
I have been looking everywhere but i cannot find out how to do a fragment transaction when an item in a recycler view is clicked. So i was wandering if anyone knows how to do it in c#
Thanks
Recycler Adapter
class FavouritesPageAdapter : RecyclerView.Adapter
{
FavouritesFragment favFragment = new FavouritesFragment();
private List<Favourites> mFavourites;
private RecyclerView mRecyclerView;
public FavouritesPageAdapter(List<Favourites> favourites, RecyclerView recyclerView)
{
mFavourites = favourites;
mRecyclerView = recyclerView;
}
public override int ItemCount
{
get { return mFavourites.Count; }
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
FavouritesViewHolder viewHolder = holder as FavouritesViewHolder;
viewHolder.mCalcLabel.Text = mFavourites[position].CalcName;
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
View favouritesCard = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.favourites_cards, parent, false);
TextView calcName = favouritesCard.FindViewById<TextView>(Resource.Id.calculatorLabel);
FavouritesViewHolder view = new FavouritesViewHolder(favouritesCard) { mCalcLabel = calcName };
return view;
}
public class FavouritesViewHolder : RecyclerView.ViewHolder
{
public View mMainView { get; set; }
public TextView mCalcLabel { get; set; }
public FavouritesViewHolder (View view) : base(view)
{
mMainView = view;
}
}
}
If you need to open new fragment when user clicking on recyclerView item, try doing this in your OnBindViewHolder overridden method
public class FavouritesPageAdapter : RecyclerView.Adapter
{
FavouritesFragment favFragment = new FavouritesFragment();
private List<Favourites> mFavourites;
private RecyclerView mRecyclerView;
Activity _activity;
public FavouritesPageAdapter(Activity activity, List<Favourites> favourites, RecyclerView recyclerView)
{
_activity=activity;
mFavourites = favourites;
mRecyclerView = recyclerView;
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
FavouritesViewHolder viewHolder = holder as FavouritesViewHolder;
viewHolder.mCalcLabel.Text = mFavourites[position].CalcName;
var clickedItem = mFavourites[position];
viewHolder.mMainView.click+=delegate
{
var objFrg = new MyFragment();
var fragmentTx =_activity.SupportFragmentManager.BeginTransaction();
fragmentTx.Replace(Resource.Id.crealtabcontent, objFrg, "MyFrgTag").AddToBackStack("myFrgBackStack");
fragmentTx.Commit();
};
}
}
Your fragment should look like this
public class MyFragment :Android.Support.V4.App.Fragment
{
}
For getting clicked item use position of OnBindViewHolder method. _activity is Activity you have to pass while calling your adapter like this
var fvrtAdapter = new FavouritesPageAdapter(this.Activity,favourites,recyclerView);
i'm new on Xamarin, i created a view where i'm showing a list of items, i created activity, axml files and style. It work well.
Now i would like start a "intent" on item selected but i have problem to get position or title of item.
My "Console.WriteLine(selectedFromList)" show just 0 value, i would like get more information from my item selected, like the right position or title, so i can validate and "intent" my specific activities for each item selected.
namespace app_sofis.Droid
{
[Activity(Label = "ServiziActivity" , Theme = "#style/ThemeActionBar")]
public class ServiziActivity : Activity
{
public static int TYPE_ITEM = 0;
public static int TYPE_SEPORATOR = 1;
List<IMenuItemsType> item = new List<IMenuItemsType>();
private ListView lst;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Servizi);
// my items
item.Add(new MenuHeaderItem("Servizi per il paziente"));
item.Add(new MenuContentItem("COLLO", "Inforntuni, patologie, interventi e riabilitazione", Resource.Mipmap.ic_schiena));
item.Add(new MenuContentItem("SPALLA", "Inforntuni, patologie, interventi e riabilitazione", Resource.Mipmap.ic_schiena));
item.Add(new MenuContentItem("SCHIENA", "Inforntuni, patologie, interventi e riabilitazione", Resource.Mipmap.ic_schiena));
lst = FindViewById<ListView>(Resource.Id.lstview);
lst.Adapter = new ListViewAdapter(this, item);
lst.ItemClick += (object sender, Android.Widget.AdapterView.ItemClickEventArgs e) =>
{
// HERE I WOULD LIKE VALIDATE ITEM AND START "intent" with my specific activities :)
string selectedFromList = lst.GetItemAtPosition(e.Position).ToString();
// trying to show item position but it return always 0
Console.WriteLine(selectedFromList);
};
}
// code for my listview
public interface IMenuItemsType
{
int GetMenuItemsType();
}
public class MenuHeaderItem : IMenuItemsType
{
public string HeaderText { get; set; }
public int GetMenuItemsType()
{
return TYPE_ITEM;
}
public MenuHeaderItem(string _headerText)
{
HeaderText = _headerText;
}
}
public class MenuContentItem : IMenuItemsType
{
public string Title { get; set; }
public string SubTitle { get; set; }
public int IconImage { get; set; }
public int GetMenuItemsType()
{
return TYPE_SEPORATOR;
}
public MenuContentItem(string _title, string _subtitle, int _iconImage)
{
Title = _title;
SubTitle = _subtitle;
IconImage = _iconImage;
}
}
public class ListViewAdapter : ArrayAdapter<IMenuItemsType>
{
private Context context;
private List<IMenuItemsType> items;
private LayoutInflater inflater;
public ListViewAdapter(Context context, List<IMenuItemsType> items) : base(context, 0, items)
{
this.context = context;
this.items = items;
this.inflater = (LayoutInflater)this.context.GetSystemService(Context.LayoutInflaterService);
}
public override int Count
{
get
{
//throw new System.NotImplementedException();
return items.Count;
}
}
public override long GetItemId(int position)
{
//throw new System.NotImplementedException();
return position;
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
//throw new System.NotImplementedException();
View view = convertView;
try
{
IMenuItemsType item = items[position];
if (item.GetMenuItemsType() == TYPE_ITEM)
{
MenuHeaderItem _headerItem = (MenuHeaderItem)item;
view = inflater.Inflate(Resource.Layout.ListViewHeaderItem, null);
// user dont click header item
view.Clickable = false;
var headerName = view.FindViewById<TextView>(Resource.Id.txtHeader);
headerName.Text = _headerItem.HeaderText;
}
else if (item.GetMenuItemsType() == TYPE_SEPORATOR)
{
MenuContentItem _contentItem = (MenuContentItem)item;
view = inflater.Inflate(Resource.Layout.ListViewContentItem, null);
var _title = view.FindViewById<TextView>(Resource.Id.txtTitle);
var _imgIcon = view.FindViewById<ImageView>(Resource.Id.imgIcon);
var _subTitle = view.FindViewById<TextView>(Resource.Id.txtSubTitle);
_title.Text = _contentItem.Title;
_imgIcon.SetBackgroundResource(_contentItem.IconImage);
_subTitle.Text = _contentItem.SubTitle;
}
}
catch (Exception ex)
{
Toast.MakeText(context, ex.Message, ToastLength.Long);
}
return view;
}
}
}
}
MY CONSOLE RETURN
[ViewRootImpl#1fcd26a[ServiziActivity]] ViewPostImeInputStage processPointer 0
[ViewRootImpl#1fcd26a[ServiziActivity]] ViewPostImeInputStage processPointer 1
app_sofis.Droid.ServiziActivity+MenuContentItem
You can use position to get item from the list:
lst.ItemClick += (object sender, Android.Widget.AdapterView.ItemClickEventArgs e) =>
{
MenuItemsType selectedItem = (MenuItemsType)item[e.Position];
Console.WriteLine(selectedItem.Title);
Console.WriteLine(selectedItem.SubTitle);
};
Hope this helps
I would suggest the following addition to your adapter class:
public override IMenuItemsType this [int index]
{
get { return items[index]; }
}
That way it is easier to access an item at the given position.
lst.ItemClick += (object sender, Android.Widget.AdapterView.ItemClickEventArgs e) =>
{
var selectedFromList = (lst.Adapter as ListViewAdapter)[e.Position];
if(selectedFromList is MenuHeaderItem)
{
var intent = new Intent(this, typeof(YOUR_ACTIVITY1));
StartActivity(intent);
}
if(selectedFromList is MenuContentItem)
{
var intent = new Intent(this, typeof(YOUR_ACTIVITY2));
StartActivity(intent);
}
};
I'm using Realm to save my seekbar updates.
I have a RecyclerView, adding X Items manual to the RecyclerView,
Inside the Items there are settings for the User and i want the settings seperate for each Item.
public static BottomSheet_Faecher newInstance(String mString)
{
BottomSheet_Faecher f = new BottomSheet_Faecher();
Bundle args = new Bundle();
args.PutString("string", mString);
f.Arguments = args;
return f;
}
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
mString = Arguments.GetString("string");
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View v = inflater.Inflate(Resource.Layout.Settings_Faecher_Wertung, container, false);
Fach1 = v.FindViewById<SeekBar>(Resource.Id.seek1);
Fach2 = v.FindViewById<SeekBar>(Resource.Id.seek2);
var prefs = PreferenceManager.GetDefaultSharedPreferences(this.Activity);
bool previouslyStarted = prefs.GetBoolean("first", false);
string name = name = Arguments.GetString("Name");
Ad = realm.All<SAd>().Where(m => m.mName == name).First();
if (!previouslyStarted)
{
wertungen = new HNWertung { HWertung = Fach1.Progress, NhWertung = Fach2.Progress };
realm.Write(() =>
{
Ad.mWertunglist.Add(wertungen);
});
var edit = prefs.Edit();
edit.PutBoolean("first", true);
edit.Commit();
}
var test = realm.All<HNWertung>().First();
Fach1.Progress = test.HauptfachWertung;
Fach2.Progress = test.NebenfachWertung;
//Fach1.Progress = L;
//Fach2.Progress = ListWertung.NebenfachWertung;
Fach1.ProgressChanged += Fach1_ProgressChanged;
Fach2.ProgressChanged += Fach2_ProgressChanged;
return v;
}
private void Fach2_ProgressChanged(object sender, SeekBar.ProgressChangedEventArgs e)
{
Fach1.Progress = 100 - e.Progress;
}
private void Fach1_ProgressChanged(object sender, SeekBar.ProgressChangedEventArgs e)
{
Fach2.Progress = 100 - e.Progress;
}
public override void OnDestroy()
{
base.OnDestroy();
}
And how can i update/ save the Progress, after the Fragment is destroyed
and how can i reach the updated Progress
//Edit
public class StufeAdapter : RecyclerView.Adapter
{
public event EventHandler<int> ItemClick;
private RecyclerView mRecyclerView;
private List<StufeAd> mStufenListe;
Realm realm = Realm.GetInstance();
public StufeAdapter(List<StufeAd> stufenListe, RecyclerView recyclerView)
{
mStufenListe = stufenListe;
mRecyclerView = recyclerView;
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
var viewholder = holder as StufeViewHolder;
viewholder.StufenPhoto.SetImageResource(mStufenListe[position].mPhoto);
viewholder.Stufe.Text = mStufenListe[position].mName;
viewholder.Durchschnitt.Text = mStufenListe[position].mDurchschnitt.ToString();
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
View view = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.CardView_Stufe_Row, parent, false);
StufeViewHolder vh = new StufeViewHolder(view, OnClick);
return vh;
}
public override int ItemCount
{
get
{
return mStufenListe.Count;
}
}
//Realm Object
public class StufeAd : RealmObject
{
[PrimaryKey]
public string mName { get; set; }
public int mPhoto { get; set; }
public int mDurchschnitt { get; set; }
public IList<HNWertung> mWertunglist { get; }
}
public class HNWertung : RealmObject
{
public int HauptfachWertung { get; set; }
public int NebenfachWertung { get; set; }
}
So assuming you have a RecyclerView that looks like:
We can create a matching RealmObject that persists your data.
RealmObject:
public class ARealmObject : RealmObject
{
[PrimaryKey] // Use Gap-less Primary keys for super fast RecyclerView, otherwise you have to create a "positional" RealmObject mapping
public int Key { get; set; } // zero-based for RecyclerView Adapter
public string Caption { get; set; }
public int SeekBar1 { get; set; }
public int SeekBar2 { get; set; }
}
We can create a RecyclerView.Adapter that pulls the data from your Realm instance and persists user changes changes to each SeekBar.
RecyclerView.Adapter:
public class RealmAdapter : RecyclerView.Adapter
{
Realm realm;
IQueryable<ARealmObject> realmobjects;
public RealmAdapter(RealmConfiguration config)
{
realm = Realm.GetInstance(config);
realmobjects = realm.All<ARealmObject>();
}
public class RealmObjectViewHolder : RecyclerView.ViewHolder
{
readonly Timer timer;
readonly Realm realm;
ARealmObject aRealmObject;
string lastCaption;
public RealmObjectViewHolder(View view, Realm realm) : base(view)
{
this.realm = realm;
Caption = view.FindViewById<TextView>(Resource.Id.realmTextView);
SeekBar1 = view.FindViewById<SeekBar>(Resource.Id.seekBar1);
SeekBar2 = view.FindViewById<SeekBar>(Resource.Id.seekBar2);
SeekBar1.StopTrackingTouch += SeekBar_HandleEventHandler;
SeekBar2.StopTrackingTouch += SeekBar_HandleEventHandler;
}
public TextView Caption { get; private set; }
public SeekBar SeekBar1 { get; private set; }
public SeekBar SeekBar2 { get; private set; }
public int Key
{
get { return aRealmObject.Key; }
set
{
aRealmObject = realm.Find<ARealmObject>(value);
aRealmObject = aRealmObject ?? new ARealmObject { Key = value, Caption = $"missing key : {value}", SeekBar1 = 50, SeekBar2 = 50 };
Caption.Text = aRealmObject.Caption;
lastCaption = Caption.Text;
SeekBar1.Progress = aRealmObject.SeekBar1;
SeekBar2.Progress = aRealmObject.SeekBar2;
}
}
void SeekBar_HandleEventHandler(object sender, SeekBar.StopTrackingTouchEventArgs e)
{
UpdateRealmObject();
}
void UpdateRealmObject()
{
if (aRealmObject.Caption != Caption.Text || aRealmObject.SeekBar1 != SeekBar1.Progress || aRealmObject.SeekBar2 != SeekBar2.Progress)
{
lastCaption = Caption.Text;
realm.Write(() =>
{
aRealmObject.SeekBar1 = SeekBar1.Progress;
aRealmObject.SeekBar2 = SeekBar2.Progress;
realm.Add(aRealmObject, true); // Using the optional update: parameter set to true
});
}
}
}
public override int ItemCount
{
get { return realmobjects.Count(); }
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
var vh = holder as RealmObjectViewHolder;
vh.Key = position;
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
var itemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.ARealmObjectCardView, parent, false);
var vh = new RealmObjectViewHolder(itemView, realm);
return vh;
}
}
Example Usage w/ 10,000 test items:
[Activity(Label = "RecyclerViewWithRealm", MainLauncher = true, Icon = "#mipmap/icon")]
public class MainActivity : Activity
{
RecyclerView recyclerView;
RecyclerView.Adapter adapter;
RecyclerView.LayoutManager layoutManager;
Realm masterRealmInstance;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
masterRealmInstance = Realm.GetInstance("RecyclerViewExample.realm");
if (masterRealmInstance.All<ARealmObject>().Count() == 0)
{
masterRealmInstance.Write(() => // Create some test data
{
for (int i = 0; i < 10000; i++)
{
masterRealmInstance.Add(new ARealmObject { Key = i, Caption = $"StackOverFlow # + {i.ToString()}", SeekBar1 = 50, SeekBar2 = 50 });
}
});
}
SetContentView(Resource.Layout.ARecyclerLayOut);
recyclerView = (RecyclerView)FindViewById(Resource.Id.recyclerView);
recyclerView.HasFixedSize = true;
layoutManager = new LinearLayoutManager(this);
recyclerView.SetLayoutManager(layoutManager);
adapter = new RealmAdapter((RealmConfiguration)masterRealmInstance.Config);
recyclerView.SetAdapter(adapter);
}
}
Change the values of any of the individual SeekBars exit and restart the application and your changes will be reloaded:
I'm new coding Xamarin, so i made a custom adapter, my idea was to save everything, when the user closes the app. After some research I thought this code was gonna work:
List<GardenClass> MyList = new List<GardenClass> ();
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
listview.Adapter = new GardenAdapter(this, MyList);
}
protected override void OnPause()
{
base.OnPause();
write();
}
public void write()
{
string path = System.Environment.GetFolderPath(SpecialFolder.Personal);
string filename = Path.Combine(path, "Files.txt");
try
{
File.WriteAllText(filename,JsonConvert.SerializeObject(MyList));
}
catch (Exception e)
{
Console.WriteLine("Failed to serialize. Reason: " + e.Message);
throw;
}
}
public class GardenAdapter : BaseAdapter<GardenClass>
{
private Context MyCon;
List<GardenClass> items;
Activity context;
public GardenAdapter(Activity context, List<GardenClass> items)
: base()
{
MyCon = context;
this.context = context;
this.items = items;
}
public override long GetItemId(int position)
{
return position;
}
public override GardenClass this[int position]
{
get { return items[position]; }
}
public override int Count
{
get { return items.Count; }
}
public override Android.Views.View GetView(int position, Android.Views.View convertView, ViewGroup parent)
{
var item = items[position];
Android.Views.View view;
if (convertView == null) {
view = context.LayoutInflater.Inflate(Resource.Layout.ListItem, null);
} else { view = convertView; }
view.FindViewById<TextView>(Resource.Id.textView1).Text = item.ToDo;
view.FindViewById<TextView>(Resource.Id.textView2).Text = "Week " + item.Week.ToString();
view.FindViewById<CheckBox>(Resource.Id.checkBox1).Checked = item.Done;
CheckBox MyCheckBox;
checkding = view.FindViewById<CheckBox>(Resource.Id.checkBox1);
// The folowing code prevents the checkbox of stealing the focus, which make a singular listview item unclickable
MyCheckBox.Focusable = false;
MyCheckBox.FocusableInTouchMode = false;
MyCheckBox.Clickable = true;
return view;
}
}
[Serializable]
public class ZaaiSpul
{
public int Week { get; set; }
public string ToDo { get; set; }
public bool Done { get; set; }
}
But when the OnPause() function gets called, then MyList gives me incorrect information(saw it myself in the debugger).
I'm sorry if I did some wrong things, but I'm new to Xamarin.
I hope you can help me.
You're only reading the check box state, you're never saving it when it changes. Add this in your GetView:
MyCheckBox.CheckedChange += (sender, e) =>
{
items[position].Done = e.IsChecked;
};