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;
}
}
Related
I've Created and App with Search View comes up with RecyclerView with Check box. When i checked a checkbox then search the checked checkbox becomes uncheck. How can i resolve the issue? Checkbox state when searching state the checkbox is still checked. Thanks fellow programmers
Screenshot 1:
Application View
When checking item in recycler view :
Selecting Item Checkbox
When i searched the item the checkbox state changes it becomes unchecked item: Searching the item becomes unchecked
public class SelectBranch : AppCompatActivity
{
RecyclerView mRecyclerView;
RecyclerView.LayoutManager mLayoutManager;
List<Info_LoadBranch> loadBranch = new List<Info_LoadBranch>();
BranchAdapter holder;
Android.Widget.SearchView searchViewBranch;
List<string> SelectedBranchCode = new List<string>();
Button BtnProceed;
string dbPath;
SQLiteConnection db;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.activity_select);
mRecyclerView = FindViewById<RecyclerView>(Resource.Id.recyclerView1);
mLayoutManager = new LinearLayoutManager(this);
BtnProceed = FindViewById<Button>(Resource.Id.btnProceed);
BtnProceed.Click += BtnProceed_Click;
LoadData();
searchViewBranch = FindViewById<Android.Widget.SearchView>(Resource.Id.searchView1);
searchViewBranch.QueryTextChange += SearchViewBranch_QueryTextChange;
GlobalVariable.SelectedBranchCode = new List<string>();
// Create your application here
}
private void SearchViewBranch_QueryTextChange(object sender, Android.Widget.SearchView.QueryTextChangeEventArgs e)
{
var adapter = new BranchAdapter(this, FindInsideList(e.NewText));
holder.NotifyDataSetChanged();
mRecyclerView.SetAdapter(adapter);
}
private List<Info_LoadBranch> FindInsideList(string text)
{
if (text != null && text.Length > 0)
{
List<Info_LoadBranch> filteredList = new List<Info_LoadBranch>();
foreach (var itm in loadBranch)
{
if (itm != null)
{
text = text.ToLower();
if (itm.BranchName != null ? itm.BranchName.ToLower().Contains(text) : false)
{
filteredList.Add(itm);
}
}
}
return filteredList;
}
return loadBranch;
}
private void BtnProceed_Click(object sender, EventArgs e)
{
if (GlobalVariable.SelectedBranchCode.Count > 0)
{
var intent = new Intent(this, typeof(Inquiry));
StartActivity(intent);
this.Finish();
}
else
{
DialogHelper.ShowAlertMessage(this, "Exception", "Please select Branch");
return;
}
}
private void LoadData()
{
dbPath = Path.Combine(BaseVariable.DEFAULT_APP_SETTINGS_DB_PATH, BaseVariable.DEFAULT_SQLITE_DB_COMPANY);
db = new SQLiteConnection(dbPath);
loadBranch = db.Query<Info_LoadBranch>("Select BranchCode, BranchName from BranchDB");
holder = new BranchAdapter(this, loadBranch);
//ListViewSelectedBranch.Adapter = output;
mRecyclerView.SetLayoutManager(mLayoutManager);
holder.NotifyDataSetChanged();
mRecyclerView.SetAdapter(holder);
}
public class BranchAdapter : RecyclerView.Adapter
{
public event EventHandler<int> ItemClick;
AppCompatActivity activity;
private List<Info_LoadBranch> branchesList;
public BranchAdapter(AppCompatActivity activity, List<Info_LoadBranch> branchesList)
{
//this.items = items;
this.activity = activity;
this.branchesList = branchesList;
//this.branchesList = branchesList.OrderBy(s => s.BranchName).ToList();
}
public override int ItemCount
{
get
{
return branchesList.Count;
}
}
public Filter Filter { get; private set; }
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
View itemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.adapter_selectbranch, parent, false);
//itemView.SetBackgroundResource(Resource.Drawable.listItem1);
PickingViewHolder vh = new PickingViewHolder(itemView);
return vh;
}
private Dictionary<int, bool> map = new Dictionary<int, bool>();
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
var item = branchesList[position];
PickingViewHolder vh = holder as PickingViewHolder;
vh.BranchCodeCheckBox.SetOnCheckedChangeListener(new MyListener(map, position));
vh.LblBranch.Text = item.BranchName;
vh.BranchCodeCheckBox.Tag = item.BranchCode;
if (map != null && map.ContainsKey(position))
{
vh.BranchCodeCheckBox.Checked = true;
// vh.BranchCodeCheckBox.Checked = branchesList[position].IsChecked;
}
else
{
vh.BranchCodeCheckBox.Checked = false;
}
//vh.BranchCodeCheckBox.Checked = branchesList[position].IsChecked;
//vh.BranchCodeCheckBox.SetOnCheckedChangeListener(new CheckedChangeListener(this.activity));
//if (map != null && map.ContainsKey(position))
//{
// vh.BranchCodeCheckBox.Checked = true;
//}
//else
//{
// vh.BranchCodeCheckBox.Checked = false;
//}
//if (position != 0)
//{
// var linearLayoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FillParent,
// ViewGroup.LayoutParams.WrapContent);
// linearLayoutParams.SetMargins(0, 10, 0, 0);
// vh.MainLinearLayout.LayoutParameters = linearLayoutParams;
//}
//vh.Image.SetImageResource (mPhotoAlbum[position].PhotoID);
}
class MyListener : Java.Lang.Object, CompoundButton.IOnCheckedChangeListener
{
public Dictionary<int, bool> map;
public int mPosotion;
string name;
public MyListener(Dictionary<int, bool> map, int position)
{
this.map = map;
mPosotion = position;
}
public void OnCheckedChanged(CompoundButton buttonView, bool isChecked)
{
if (isChecked == true)
{
if (!map.ContainsKey(mPosotion))
{
map.Add(mPosotion, true);
name = (string)buttonView.Tag;
GlobalVariable.SelectedBranchCode.Add(name);
}
}
else
{
map.Remove(mPosotion);
foreach (var a in GlobalVariable.SelectedBranchCode)
{
GlobalVariable.SelectedBranchCode.Remove(name);
break;
}
}
}
}
public class PickingViewHolder : RecyclerView.ViewHolder
{
public LinearLayout MainLinearLayout { get; set; }
public TextView LblBranch { get; set; }
public CheckBox BranchCodeCheckBox { get; set; }
public bool IsChecked { get; set; }
public PickingViewHolder(View itemView):base(itemView)
{
//Image = itemView.FindViewById<ImageView> (Resource.Id.imageView);
MainLinearLayout = itemView.FindViewById<LinearLayout>(Resource.Id.linearLayout1);
LblBranch = itemView.FindViewById<TextView>(Resource.Id.textViewBranch);
BranchCodeCheckBox = itemView.FindViewById<CheckBox>(Resource.Id.checkBoxSelect);
// Detect user clicks on the item view and report which item
// was clicked (by layout position) to the listener:
// itemView.Click += (sender, e) => listener(base.LayoutPosition);
BranchCodeCheckBox.Click += delegate
{
if (BranchCodeCheckBox.Checked)
{
IsChecked = true;
}
else
{
IsChecked = false;
}
};
}
}
void OnClick(int position)
{
if (ItemClick != null)
ItemClick(this, position);
}
}
public class CheckedChangeListener : Java.Lang.Object, CompoundButton.IOnCheckedChangeListener
{
public Activity activity;
string name;
public CheckedChangeListener(Activity activity)
{
this.activity = activity;
}
public void OnCheckedChanged(CompoundButton buttonView, bool isChecked)
{
if (isChecked)
{
name = (string)buttonView.Tag;
GlobalVariable.SelectedBranchCode.Add(name);
}
else if (!isChecked)
{
foreach (var a in GlobalVariable.SelectedBranchCode)
{
GlobalVariable.SelectedBranchCode.Remove(name);
break;
}
}
}
}
}
When use a separate dataset(Dictionary<int, bool> map) to store the position, you need to deal with the Item data and position separately.
private Dictionary<int, bool> map = new Dictionary<int, bool>();
Try another method, just add a field in your Object model : Info_LoadBranch. For example:
public bool isChecked { get; set; }
And initialize the variable to false.
And When you check (or uncheck) the checkBox, you can refer to the following code:
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
PhotoViewHolder vh = holder as PhotoViewHolder;
//***********************
Photo item = mPhotoAlbum[position];
//***********************
//vh.MyCheckBox.Tag = position;
vh.Caption.Text = item.Caption;
vh.MyCheckBox.SetOnCheckedChangeListener(null);
vh.MyCheckBox.SetOnCheckedChangeListener(new MyListener(item));
vh.MyCheckBox.Checked = item.isChecked;
}
And MyListener
class MyListener : Java.Lang.Object, CompoundButton.IOnCheckedChangeListener
{
Photo photo;
public MyListener( Photo item)
{
this.photo = item;
}
public void OnCheckedChanged(CompoundButton buttonView, bool isChecked)
{
photo.isChecked = isChecked;
}
}
If you want to find the checked Items, you can filter like this:
List<Photo> checkedList = new List<Photo>();
for (int i=0;i< loadBranch.Count;i++) {
Photo temp = loadBranch[i];
if (temp.isChecked) {
checkedList.Add(temp);
}
}
Note: the model Photo is my model, you just use yours.
I have try the following code to fire on activity result inside my atapter, when my button pressed without success. The activity TraEdit is starting correctly and updates my data. I can't refresh my list with NotifyDataSetChanged(), OnActivityResult never fires to control the result.
What i am doing wrong? Is there a way to NotifyDataSetChanged() inside my adapter or i have to try a different approach?
Any help appreciated.
using System.Collections.Generic;
using Android.App;
using Android.Content;
using Android.Views;
using Android.Widget;
namespace Cashier
{
[Activity(Label = "TraBaseAdapter")]
public partial class TraBaseAdapter : BaseAdapter<TraTable>
{
List<TraTable> TraListArrayList;
private LayoutInflater mInflater;
private Context activity;
public TraBaseAdapter(Context context, List<TraTable> results)
{
activity = context;
TraListArrayList = results;
mInflater = (LayoutInflater)activity.GetSystemService(Context.LayoutInflaterService);
}
public override int Count { get { return TraListArrayList.Count; } }
public override long GetItemId(int position) { return position; }
public override TraTable this[int position] { get { return TraListArrayList[position]; } }
public override View GetView(int position, View convertView, ViewGroup parent)
{
TraViewHolder holder = null;
if (convertView == null)
{
convertView = mInflater.Inflate(Resource.Layout.TraRecord_view, null);
holder = new TraViewHolder
{
TxtBtnEdit = convertView.FindViewById<Button>(Resource.Id.TraEditButtonHolder),
TxtTraName = convertView.FindViewById<TextView>(Resource.Id.TraNameHolder),
TxtTraCode = convertView.FindViewById<TextView>(Resource.Id.TraCodeHolder)
};
if (!holder.TxtBtnEdit.HasOnClickListeners)
{
holder.TxtBtnEdit.Click += (sender, e) =>
{
TraEditClick(holder);
};
}
convertView.Tag = holder;
}
else { holder = convertView.Tag as TraViewHolder; }
holder.LineId = position;
holder.TraId = TraListArrayList[position].Cs_Traid;
holder.TxtBtnEdit.Tag = holder.LineId + 1;
holder.TxtTraName.Text = TraListArrayList[position].Cs_Name;
holder.TxtTraCode.Text = TraListArrayList[position].Cs_Code;
return convertView;
}
private void TraEditClick(TraViewHolder LineHolder)
{
Intent ActivityAddEditTra = new Intent(this.activity, typeof(TraEdit));
ActivityAddEditTra.PutExtra("TraIdSel", TraListArrayList[LineHolder.LineId].Cs_Traid);
ActivityAddEditTra.PutExtra("NameSel", TraListArrayList[LineHolder.LineId].Cs_Name);
ActivityAddEditTra.PutExtra("TraCodeSel", TraListArrayList[LineHolder.LineId].Cs_Code);
((Activity)activity).StartActivityForResult(ActivityAddEditTra, 99);
}
public void OnActivityResult(int RequestCode, Result ResultCode, Intent Data)
{
if (ResultCode == Result.Ok & RequestCode == 99)
{
int RowUpdate = Data.GetIntExtra("RowUpdate", 0);
NotifyDataSetChanged();
Toast.MakeText(activity, "Data changes :" + RowUpdate.ToString(), ToastLength.Short).Show();
}
}
public class TraViewHolder : Java.Lang.Object
{
public TextView TxtTraCode { get; set; }
public TextView TxtTraName { get; set; }
public Button TxtBtnEdit { get; set; }
public int LineId { get; set; }
public int TraId { get; set; }
}
}
}
In TraEdit:
......
Intent RetunData = new Intent();
SetResult(Result.Ok, RetunData);
RetunData.PutExtra("RowUpdate", RowsUpd);
......
Maybe
RetunData.PutExtra("RowUpdate", RowsUpd);
should come before
SetResult(Result.Ok, RetunData);
Im not good with VS but maybe the OnActivityResult method must be in the Activity not in the adapater
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 tring to create a ListView which is fed data from an SQLite Database (pre-existing db file). The ListView uses a custom row which is one of the aspects which baffle me; How do I extract the data and then assign it to a TextView in the custom row?
I'm new to Xamarin, so would really appreciate any guidance you can give me on this, Thank you!
Current Dialog Box Error When Run:
Java.Lang.ClassNotFoundException: Didn't find class "md5c4f65b5cf99ab8e97737acf0f8ec7efd.DBHelper" on path: DexPathList[[zip file "/data/app/AppName.Droid-1/base.apk"],nativeLibraryDirectories=[/data/app/AppName.Droid-1/lib/arm, /system/fake-libs, /data/app/AppName.Droid-1/base.apk!/lib/armeabi-v7a, /system/lib, /vendor/lib]]
'MainActivity':
public class EateriesActivity : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
Title = "Find An Eatery";
SetContentView(Resource.Layout.Eateries);
DBHelper db = new DBHelper();
db.CreateDatabase();
db.CreateTable();
var items = db.GetData();
var listView = FindViewById<ListView>(Resource.Id.EateryList_ListView);
listView.Adapter = new ArrayAdapter<string>(this, Resource.Layout.Eatery_ListView_Row, items);
}
}
ListViewAdapter (is this necessary?):
class ListViewAdapter : BaseAdapter<Eatery>
{
private List<Eatery> myItems;
private Context myContext;
public ListViewAdapter(Context context, List<Eatery> items)
{
myItems = items;
myContext = context;
}
public override int Count
{
get { return myItems.Count; }
}
public override long GetItemId(int position)
{
return position;
}
public override Eatery this[int position]
{
get
{
return myItems[position];
}
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
View row = convertView;
if (row == null)
{
row = LayoutInflater.From(myContext).Inflate(Resource.Layout.Eatery_ListView_Row, null, false);
}
TextView placeName = row.FindViewById<TextView>(Resource.Id.placeName);
placeName.Text = myItems[position].Name;
TextView placeTown = row.FindViewById<TextView>(Resource.Id.placeTown);
placeTown.Text = myItems[position].Town;
return row;
}
}
Eatery:
public class Eatery
{
[PrimaryKey]
public string ID { get; set; }
public string Image { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Address1 { get; set; }
public string Town { get; set; }
public string PostCode { get; set; }
public string Cuisine { get; set; }
}
DBHelper:
public class DBHelper
{
private static string DB_PATH = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
private static string DB_NAME = "EateryDB.db";
public void CreateDatabase()
{
string dbPath = Path.Combine(DB_PATH, DB_NAME);
var db = new SQLiteConnection(new SQLite.Net.Platform.XamarinAndroid.SQLitePlatformAndroid(), dbPath);
}
public void CreateTable()
{
string dbPath = Path.Combine(DB_PATH, DB_NAME);
var db = new SQLiteConnection(new SQLite.Net.Platform.XamarinAndroid.SQLitePlatformAndroid(), dbPath);
db.CreateTable<Eatery>();
}
public List<string> GetData()
{
string dbPath = Path.Combine(DB_PATH, DB_NAME);
var db = new SQLiteConnection(new SQLite.Net.Platform.XamarinAndroid.SQLitePlatformAndroid(), dbPath);
List<string> data = new List<string>();
foreach (var item in db.Table<Eatery>())
{
var place = item.Name.ToString(); item.Town.ToString();
data.Add(place);
}
return data;
}
Based on your two version of code, I think what you need is adding data from your database to the myItems.
Then you can for example code like this:
List<Eatery> data = new List<Eatery>();
foreach (var item in db.Table<Eatery>())
{
var place = item.Name.ToString();
var location = item.Location.ToString();
var rating = item.Rating;
item.Town.ToString();
data.Add(new Eatery() { PlaceName = place, PlaceLocation = location, PlaceRating = rating });
}
And finally add this data to your adapter as you did when you hard code:
MyListViewAdapter adapter = new MyListViewAdapter(this, data);