I have problem with showing popupmenu. When I clicked on ImageButton , on display shown a few popupmenu(for different elements - in click listener of ClickedPopUpMenu I show toast with position).
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
using Android.App;
using Android.Support.V7.Widget;
using Android.Views;
using Android.Widget;
using DexpensMobile.Core.Models;
using DexpensMobile.Core.Services;
using DexpensMobile.Core.Services.AuthService;
using DexpensMobile.Droid.Screens;
using UniversalImageLoader.Core;
using UniversalImageLoader.Core.Display;
using PopupMenu = Android.Widget.PopupMenu;
namespace DexpensMobile.Droid.Adapters
{
public class PostListAdapter : RecyclerView.Adapter
{
protected Activity context = null;
protected IList<PostModel> tasks = new List<PostModel>();
ImageLoader _imageLoader;
private int popPosition;
private int TYPE_HEADER = 0;
private int TYPE_ITEM = 1;
public event EventHandler<int> ItemClick;
public PostListAdapter(IList<PostModel> tasks, Activity context)
{
this.tasks = tasks;
_imageLoader = ImageLoader.Instance;
this.context = context;
}
public PostListAdapter() { }
public override long GetItemId(int position)
{
return position;
}
public override int GetItemViewType(int position)
{
if (IsPositionHeader(position))
return Resource.Layout.wall_header;
return Resource.Layout.ItemPost;
}
private bool IsPositionHeader(int position)
{
return position == 0;
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
if (holder.GetType() == typeof(PostViewHodler))
{
PostViewHodler vh = holder as PostViewHodler;
var item = tasks[position-1];
var _userData = ServiceLocator.GetService<IAuthService>().GetUserData();
vh.ShowPopUpMenuButton.Click += (sender, e) => button_Click(sender, e, position);
var tempText = item.Text;
if (tempText.EndsWith("<br/>"))
tempText = tempText.Substring(0, tempText.Length - 5);
tempText = tempText.Replace("<br/>", "\n");
tempText = Regex.Replace(tempText, #"^\s+$[\n]*", "", RegexOptions.Multiline);
vh.PostText.Text = tempText;
vh.OwnerFullName.Text = item.CreatorName;
vh.DateText.Text = item.CreatedDate.ToString(CultureInfo.InvariantCulture);
vh.LikeText.Text = item.Like.LikesCount > 0
? item.Like.LikesCount.ToString()
: "";
vh.CommentText.Text = item.Comments.Any() ? item.Comments.Count().ToString() : "";
vh.RepostText.Text = item.SharedCount > 0 ? item.SharedCount.ToString() : "";
var options =
new DisplayImageOptions.Builder()
.CacheInMemory(false)
.CacheOnDisk(false)
.Displayer(new RoundedBitmapDisplayer(500))
.Build();
_imageLoader.DisplayImage(item.AvatarUrl, vh.AvatarProfile, options);
}
else if (holder.GetType() == typeof(PostViewHodlerHeader))
{
PostViewHodlerHeader vh = holder as PostViewHodlerHeader;
vh.OwnerNameHeader.Text = "Hi from header :-)";
}
}
private void button_Click(object sender, EventArgs eventArgs, int position)
{
ImageButton im = sender as ImageButton;
PopupMenu menu = new PopupMenu(im.Context, im);
menu.Inflate(Resource.Menu.popup_menu);
//if (item.ApplicationUserId != _userData.UserId)
//{
menu.Menu.FindItem(Resource.Id.editPopUp).SetVisible(false);
menu.Menu.FindItem(Resource.Id.deletePopUp).SetVisible(false);
//}
menu.Show();
Toast.MakeText(context, position.ToString(), ToastLength.Long).Show();
menu.MenuItemClick += (o, args) => PopUpMenuClickListener(o, args, position);
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
View itemView = null;
if (viewType == Resource.Layout.wall_header)
{
itemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.wall_header, parent, false);
PostViewHodlerHeader vhHeader = new PostViewHodlerHeader(itemView);
return vhHeader;
}
else if(viewType == Resource.Layout.ItemPost)
{
itemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.ItemPost, parent, false);
PostViewHodler vhBody = new PostViewHodler(itemView, OnClick, tasks);
return vhBody;
}
return null;
}
private void OnClick(int position)
{
if (ItemClick != null)
ItemClick(this, position);
}
public override int ItemCount
{
get { return tasks.Count +1; }
}
private void PopUpMenuClickListener(object sender, PopupMenu.MenuItemClickEventArgs e, int position)
{
switch(e.Item.ItemId)
{
case Resource.Id.copyLinkPopUp:
break;
case Resource.Id.editPopUp:
((WallActivity)context).EditPost(popPosition);
break;
case Resource.Id.deletePopUp:
((WallActivity)context).DeleteItem(popPosition);
break;
}
}
}
public class PostViewHodler : RecyclerView.ViewHolder
{
public TextView OwnerFullName { get; private set; }
public ImageView AvatarProfile { get; private set; }
public TextView DateText { get; private set; }
public TextView PostText { get; private set; }
public TextView LikeText { get; private set; }
public TextView CommentText { get; private set; }
public TextView RepostText { get; private set; }
public ImageButton ShowPopUpMenuButton { get; private set; }
public PostViewHodler(View itemView, Action<int> listener, IList<PostModel> posts) : base(itemView)
{
OwnerFullName = itemView.FindViewById<TextView>(Resource.Id.UserName);
AvatarProfile = itemView.FindViewById<ImageView>(Resource.Id.postAva);
DateText = itemView.FindViewById<TextView>(Resource.Id.dateText);
PostText = itemView.FindViewById<TextView>(Resource.Id.postText);
LikeText = itemView.FindViewById<TextView>(Resource.Id.likeText);
CommentText = itemView.FindViewById<TextView>(Resource.Id.commentText);
RepostText = itemView.FindViewById<TextView>(Resource.Id.repostText);
ShowPopUpMenuButton = itemView.FindViewById<ImageButton>(Resource.Id.popupMenuButton);
itemView.Click += (sender, e) => listener(base.Position);
}
}
public class PostViewHodlerHeader : RecyclerView.ViewHolder
{
public TextView OwnerNameHeader{ get; private set; }
public ImageView AvatarProfileHeader { get; private set; }
public PostViewHodlerHeader(View itemView) : base(itemView)
{
OwnerNameHeader = itemView.FindViewById<TextView>(Resource.Id.details);
AvatarProfileHeader = itemView.FindViewById<ImageView>(Resource.Id.avatar_image);
}
}
}
I think problem bind with recycling elements.
Video link with problem.
How to show only one popupmenu only for current item in recyclerview? Why this problem occur?
Related
I would like to display diaglog fragment by clicking a button/imageView (By clicking the sAddButton)from recyclerView. But when I clicked the button nothing shows up.
How do I achieve that here is my code.
My RecyclerView Adapter
I added an pulic eventhandler in myadapter (StockInItemClick)
then created a delegate method to invoke the eventhandler(OnStockInClick)
then pass the delegate method as parameter on my adapterview holder
then Implement the delegate method on my adapterview holder.
internal class StocksAdapter : RecyclerView.Adapter
{
public event EventHandler<StocksAdapterClickEventArgs> ItemClick;
public event EventHandler<StocksAdapterClickEventArgs> ItemLongClick;
public event EventHandler<StocksAdapterClickEventArgs> StockInItemClick;
List<Products> items;
public StocksAdapter(List<Products> data)
{
items = data;
}
// Create new views (invoked by the layout manager)
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
//Setup your layout here
View itemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.stock_rView, parent, false);
//var id = Resource.Layout.__YOUR_ITEM_HERE;
//itemView = LayoutInflater.From(parent.Context).
// Inflate(id, parent, false);
var vh = new StocksAdapterViewHolder(itemView, OnClick, OnLongClick, OnStockInClick);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
public override void OnBindViewHolder(RecyclerView.ViewHolder viewHolder, int position)
{
var holder = viewHolder as StocksAdapterViewHolder;
//holder.TextView.Text = items[position];
holder.sNameText.Text = items[position].PName;
holder.sQtyText.Text = items[position].QtyonHand;
}
public override int ItemCount => items.Count;
void OnClick(StocksAdapterClickEventArgs args) => ItemClick?.Invoke(this, args);
void OnLongClick(StocksAdapterClickEventArgs args) => ItemLongClick?.Invoke(this, args);
void OnStockInClick(StocksAdapterClickEventArgs args) => StockInItemClick?.Invoke(this, args);
}
public class StocksAdapterViewHolder : RecyclerView.ViewHolder
{
//public TextView TextView { get; set; }
public TextView sNameText { get; set; }
public TextView sQtyText { get; set; }
public ImageButton sAddButton { get; set; }
public StocksAdapterViewHolder(View itemView, Action<StocksAdapterClickEventArgs> clickListener,
Action<StocksAdapterClickEventArgs> longClickListener,
Action<StocksAdapterClickEventArgs> stockInClickListener) : base(itemView)
{
//TextView = v;
sNameText = (TextView)itemView.FindViewById(Resource.Id.sNameTView);
sQtyText = (TextView)itemView.FindViewById(Resource.Id.qtyonhandTView);
sAddButton = (ImageButton)itemView.FindViewById(Resource.Id.addButton);
itemView.Click += (sender, e) => clickListener(new StocksAdapterClickEventArgs { View = itemView, Position = AdapterPosition });
itemView.LongClick += (sender, e) => longClickListener(new StocksAdapterClickEventArgs { View = itemView, Position = AdapterPosition });
sAddButton.Click += (sender, e) => longClickListener(new StocksAdapterClickEventArgs { View = itemView, Position = AdapterPosition });
}
}
public class StocksAdapterClickEventArgs : EventArgs
{
public View View { get; set; }
public int Position { get; set; }
}
my code in activity
I implement the eventhandler
then on the event onlcick event(Adapter_StockInItemClick) I called the
dialog fragment.
private void SetupRecyclerView()
{
stockRView.SetLayoutManager(new Android.Support.V7.Widget.LinearLayoutManager(stockRView.Context));
adapter = new StocksAdapter(StockList);
adapter.StockInItemClick += Adapter_StockInItemClick;
stockRView.SetAdapter(adapter);
}
private void Adapter_StockInItemClick(object sender, StocksAdapterClickEventArgs e)
{
Products thisproducts = StockList[e.Position];
addNewStockInProductsFragment = new AddNewStockInProductsFragment(thisproducts);
var trans = SupportFragmentManager.BeginTransaction();
addNewStockInProductsFragment.Show(trans, "StockIn");
}
Found the problem
sAddButton.Click += (sender, e) => longClickListener(new StocksAdapterClickEventArgs { View = itemView, Position = AdapterPosition });
shouldbe (deleteClickListener) not (longClickListener)
sAddButton.Click += (sender, e) => deleteClickListener(new StocksAdapterClickEventArgs { View = itemView, Position = AdapterPosition });
when filtering data and LongItemClick I get wrong data, also when I click ItemClick also
wrong data.
Can we help me?
What I need change to works fine?
I send Model,Activity and Adapter.
There is my Model:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
namespace NovaAndroid.Model
{
public class the_SetSubjModel
{
public string acSubject { get; set; }
public string acAddress { get; set; }
public string acName2 { get; set; }
public string acPost { get; set; }
public string acCountry { get; set; }
public string acCode { get; set; }
public string acPhone { get; set; }
public string acRegNo { get; set; }
public decimal anRebate { get; set; }
public string acBuyer { get; set; }
public static explicit operator the_SetSubjModel(Java.Lang.Object v)
{
throw new NotImplementedException();
}
}
}
There is My Adapter:
using System;
using System.Collections.Generic;
using Android.App;
using Android.Content;
using Android.Views;
using Android.Widget;
using NovaAndroid.Model;
namespace NovaAndroid.Adapters
{
[Activity(Label = "ContactListBaseAdapter")]
public partial class ContactListBaseAdapter : BaseAdapter<the_SetSubjModel>
{
IList<the_SetSubjModel> contactListArrayList;
private LayoutInflater mInflater;
private Context activity;
public ContactListBaseAdapter(Context context, IList<the_SetSubjModel>
results)
{
this.activity = context;
contactListArrayList = results;
mInflater =
(LayoutInflater)activity.GetSystemService(Context.LayoutInflaterService);
}
public override int Count
{
get { return contactListArrayList.Count; }
}
public override long GetItemId(int position)
{
return position;
}
public override the_SetSubjModel this[int position]
{
get { return contactListArrayList[position]; }
}
public override Java.Lang.Object GetItem(int position)
{
return position;
}
I think there is problem in GetView method?
public override View GetView(int position, View convertView, ViewGroup
parent)
{
ContactsViewHolder holder = null;
if (convertView == null)
{
convertView =
mInflater.Inflate(Resource.Layout.list_row_contact_list, null);
holder = new ContactsViewHolder();
// Show item in listView
holder.txtacSubject = convertView.FindViewById<TextView>
(Resource.Id.lr_fullName);
holder.txtacAddress = convertView.FindViewById<TextView>
(Resource.Id.lr_address);
holder.txtEmail = convertView.FindViewById<TextView>
(Resource.Id.lr_email);
holder.txtPib = convertView.FindViewById<TextView>
(Resource.Id.lr_pib);
convertView.Tag = holder;
}
else
{
holder = convertView.Tag as ContactsViewHolder;
}
holder.txtacSubject.Text =
contactListArrayList[position].acSubject.ToString();
holder.txtacAddress.Text = contactListArrayList[position].acAddress;
holder.txtEmail.Text = contactListArrayList[position].acPost;
holder.txtPib.Text = contactListArrayList[position].acCode;
if (position % 2 == 0)
{
convertView.SetBackgroundResource(Resource.Drawable.list_selector);
}
else
{
convertView.SetBackgroundResource(Resource.Drawable.list_selector_alternate);
}
return convertView;
}
public IList<the_SetSubjModel> GetAllData()
{
return contactListArrayList;
}
public class ContactsViewHolder : Java.Lang.Object
{
public TextView txtacSubject { get; set; }
public TextView txtacAddress { get; set; }
public TextView txtEmail { get; set; }
public TextView txtPib { get; set; }
public TextView txtacName2 { get; set; }
public TextView txtacPhone { get; set; }
public TextView txtacRegNo { get; set; }
public TextView txtanRebate { get; set; }
}
class ContactListBaseAdapterViewHolder : Java.Lang.Object
{
//Your adapter views to re-use
//public TextView Title { get; set; }
}
}
}
There is My Activity:
using Android.App;
using Android.Content;
using Android.OS;
using Android.Widget;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using NovaAndroid.Model;
using NovaAndroid.Adapters;
using Android.Views;
namespace NovaAndroid
{
[Activity(Label = "Svi kupci", MainLauncher = false)]
public class ToDoItemActivity : Activity
{
//Button btnAdd;
private SearchView sv;
private ListView lista;
private ArrayAdapter adapter;
IList<the_SetSubjModel> listaToDo = null;
List<the_SetSubjModel> readed = new List<the_SetSubjModel>();
the_SetSubjModel model = new the_SetSubjModel();
EditText contactList_txtSearch;
Button btnHomeScreen;
private const string URL =
"http://192.168.147.10:8888/Service.svc/GetAllSubjectWithoutBuyer";
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.ToDoItemView);
btnHomeScreen = FindViewById<Button>(Resource.Id.buttonHome);
btnHomeScreen.Click += BtnHomeScreen_Click;
GetAllSubjectWithoutBuyer();
var str = readed.Select(x => x.acSubject).ToList();
var listView = FindViewById<ListView>(Resource.Id.listView);
contactList_txtSearch = FindViewById<EditText>
(Resource.Id.contactList_txtSearch);
lista = (ListView)FindViewById(Resource.Id.listView);
lista.Adapter = new ArrayAdapter<String>(this,
Android.Resource.Layout.SimpleListItem1, str);
lista = FindViewById<ListView>(Resource.Id.listView);
sv = FindViewById<SearchView>(Resource.Id.searchView);
adapter = new ArrayAdapter(this,
Android.Resource.Layout.SimpleListItem1, str);
lista.Adapter = adapter;
listaToDo = readed;
contactList_txtSearch.TextChanged +=
ContactList_txtSearch_TextChanged;
lista.ItemClick += Lista_ItemClick;
lista.ItemLongClick += Lista_ItemLongClick;
//
lista.Adapter = new ContactListBaseAdapter(this, listaToDo);
}
private void BtnHomeScreen_Click(object sender, EventArgs e)
{
var activityHome = new Intent(this, typeof(MainActivity));
StartActivity(activityHome);
}
private void GetAllSubjectWithoutBuyer()
{
WebRequest request = WebRequest.Create(URL);
request.Method = "GET";
request.ContentType = "application/json";
//request.ContentLength = DATA.Length;
try
{
using (var webClient = new System.Net.WebClient())
{
var json =
webClient.DownloadString("http://192.168.147.10:8888/
Service.svc/GetAllSubjectWithoutBuyer");
SResult web = JsonConvert.DeserializeObject<SResult>(json);
readed = web.GetAllSubjectWithoutBuyerResult;
}
}
catch (Exception ex)
{
}
}
private void ContactList_txtSearch_TextChanged(object sender,
Android.Text.TextChangedEventArgs e)
{
var searchText = contactList_txtSearch.Text;
//Compare the entered text with List
List<the_SetSubjModel> list = (from items in readed
where
items.acCode.Contains(contactList_txtSearch.Text)
select items).ToList<the_SetSubjModel>();
lista.Adapter = new ContactListBaseAdapter(this,list);
this.lista.DeferNotifyDataSetChanged();
}
private void Lista_ItemLongClick(object sender,
AdapterView.ItemLongClickEventArgs e)
{
the_SetSubjModel o = readed[e.Position];
var activityAddEdit = new Intent(this, typeof(AddEditActivity));
activityAddEdit.PutExtra("acSubject", o.acSubject.ToString());
activityAddEdit.PutExtra("acAddress", o.acAddress.ToString());
activityAddEdit.PutExtra("acPost", o.acPost.ToString());
activityAddEdit.PutExtra("acCode", o.acCode.ToString());
activityAddEdit.PutExtra("acCountry", o.acCountry.ToString());
activityAddEdit.PutExtra("acName2", o.acName2.ToString());
activityAddEdit.PutExtra("acPhone", o.acPhone.ToString());
activityAddEdit.PutExtra("acRegNo", o.acRegNo.ToString());
activityAddEdit.PutExtra("anRebate", o.anRebate.ToString());
StartActivity(activityAddEdit);
}
private void Lista_ItemClick(object sender,
AdapterView.ItemClickEventArgs e)
{
Toast.MakeText(this, adapter.GetItem(e.Position).ToString(),
ToastLength.Short).Show();
}
}
Picture example ItemClick wrong:
I think you have answered your own question, as if you are inheriting from base adapter you need to implement the GetView() method in your adapter if you want to create a layout inflater.
Ok, i fix for item "click" I get the right values.
But tell me how to use LongClick ? and get values for that item in new form?
This is new code for BaseAdapter:
using System;
using System.Collections.Generic;
using Android.App;
using Android.Content;
using Android.Views;
using Android.Widget;
using NovaAndroid.Model;
namespace NovaAndroid.Adapters
{
[Activity(Label = "ContactListBaseAdapter")]
public partial class ContactListBaseAdapter : BaseAdapter<the_SetSubjModel>
{
IList<the_SetSubjModel> contactListArrayList;
private LayoutInflater mInflater;
private Context activity;
the_SetSubjModel model = new the_SetSubjModel();
Dictionary<int, the_SetSubjModel> items;
private Context mContext;
private int mRowLayout;
public ContactListBaseAdapter(Context context, IList<the_SetSubjModel> results,
int rowLayout)
{
this.activity = context;
this.items = items;
context = context;
mContext = context;
mRowLayout = rowLayout;
contactListArrayList = results;
mInflater =
(LayoutInflater)activity.GetSystemService(Context.LayoutInflaterService);
}
public override int Count
{
get { return contactListArrayList.Count; }
}
public override long GetItemId(int position)
{
return position;
}
public override the_SetSubjModel this[int position]
{
get { return items[position]; }
}
public override Java.Lang.Object GetItem(int position)
{
return position;
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
View view = convertView;
if(view==null)
{
// view = LayoutInflater.From(mContext).Inflate(mRowLayout, parent,
false);
//view = Layou // view =
context.tInflater.From(mContext).Inflate(mRowLayout, parent, false);
//view =
LayoutInflater.From(mContext).Inflate(Resource.Layout.list_row_contact_list, null);
}
//ImageView btnDelete;
//ContactsViewHolder holder = null;
view = mInflater.Inflate(Resource.Layout.list_row_contact_list, null);
//holder = new ContactsViewHolder();
//// Show item in listView
//holder.txtacSubject = view.FindViewById<TextView>
(Resource.Id.lr_fullName);
//holder.txtacAddress = view.FindViewById<TextView>
(Resource.Id.lr_address);
//holder.txtEmail = view.FindViewById<TextView>(Resource.Id.lr_email);
//holder.txtPib = view.FindViewById<TextView>(Resource.Id.lr_pib);
//view.Tag = holder;
TextView txtacSubject = view.FindViewById<TextView>(Resource.Id.lr_fullName);
txtacSubject.Text = contactListArrayList[position].acSubject;
TextView txtacAddress = view.FindViewById<TextView>(Resource.Id.lr_address);
txtacAddress.Text = contactListArrayList[position].acAddress;
TextView txtEmail = view.FindViewById<TextView>(Resource.Id.lr_email);
txtEmail.Text = contactListArrayList[position].acPost;
TextView txtPib = view.FindViewById<TextView>(Resource.Id.lr_pib);
txtPib.Text = contactListArrayList[position].acCode;
if (position % 2 == 0)
{
view.SetBackgroundResource(Resource.Drawable.list_selector);
}
else
{
view.SetBackgroundResource(Resource.Drawable.list_selector_alternate);
}
view.Click += delegate
{
Toast.MakeText(mContext, contactListArrayList[position].acSubject,
ToastLength.Short).Show();
};
view.LongClick += delegate
{
};
return view;
}
public IList<the_SetSubjModel> GetAllData()
{
return contactListArrayList;
}
public class ContactsViewHolder : Java.Lang.Object
{
public TextView txtacSubject { get; set; }
public TextView txtacAddress { get; set; }
public TextView txtEmail { get; set; }
public TextView txtPib { get; set; }
public TextView txtacName2 { get; set; }
public TextView txtacPhone { get; set; }
public TextView txtacRegNo { get; set; }
public TextView txtanRebate { get; set; }
}
class ContactListBaseAdapterViewHolder : Java.Lang.Object
{
//Your adapter views to re-use
//public TextView Title { get; set; }
}
}
}
This is My new form where i must show data for I Long"click" item
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Newtonsoft.Json;
using NovaAndroid.Model;
namespace NovaAndroid
{
[Activity(Label = "Prikaz detalja kupci")]
public class AddEditActivity : Activity
{
EditText txtacSubject, txtacAddress, txtEmail,
txtPib,txtCountry,txtName,txtPhone,txtacRegNo,txtanRebate;
Button btnBack;
the_SetSubjModel model = new the_SetSubjModel();
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.AddEditToDoItem);
txtacSubject = FindViewById<EditText>(Resource.Id.addEdit_acSubject);
txtacAddress = FindViewById<EditText>(Resource.Id.addEdit_address);
txtEmail = FindViewById<EditText>(Resource.Id.addEdit_email);
txtPib = FindViewById<EditText>(Resource.Id.addEdit_PIB);
txtCountry= FindViewById<EditText>(Resource.Id.addEdit_acCountry);
txtName = FindViewById<EditText>(Resource.Id.addEdit_acName2);
txtPhone = FindViewById<EditText>(Resource.Id.addEdit_acPhone);
txtacRegNo = FindViewById<EditText>(Resource.Id.addEdit_acRegNo);
txtanRebate = FindViewById<EditText>(Resource.Id.addEdit_anRebate);
btnBack = FindViewById<Button>(Resource.Id.addEdit_btnBack);
btnBack.Click += BtnBack_Click;
string acSubject = Intent.GetStringExtra("acSubject") ??
string.Empty;
string acAddress = Intent.GetStringExtra("acAddress") ??
string.Empty;
string editMail = Intent.GetStringExtra("acPost") ?? string.Empty;
string editPib = Intent.GetStringExtra("acCode") ?? string.Empty;
string editCountry = Intent.GetStringExtra("acCountry") ??
string.Empty;
string editacName2 = Intent.GetStringExtra("acName2") ??
string.Empty;
string editacPhone = Intent.GetStringExtra("acPhone") ??
string.Empty;
string editacRegNo = Intent.GetStringExtra("acRegNo") ??
string.Empty;
string editanRebate = Intent.GetStringExtra("anRebate") ??
string.Empty;
if (acSubject.Trim().Length > 0)
{
txtacSubject.Text = acSubject;
txtacAddress.Text = acAddress;
txtEmail.Text = editMail;
txtPib.Text = editPib;
txtCountry.Text = editCountry;
txtName.Text = editacName2;
txtPhone.Text = editacPhone;
txtacRegNo.Text = editacRegNo;
txtanRebate.Text = editanRebate;
}
}
private void BtnBack_Click(object sender, EventArgs e)
{
var activityBack = new Intent(this, typeof(ToDoItemActivity));
StartActivity(activityBack);
}
}
}
In my project , i want to create a MvxRecyclerView to show all the products which user purchased on particular dates.So i have a main MvxRecyclerView layout and a Adapter class which extends MvxRecyclerAdapter .Inside this MvxRecyclerAdapter , iam creating a layouts which contains MvxRecyclerView which populates all the items based on date.
When i tried to create the adapter, Mvvmcross is not showing the child adapter data since OnCreateViewHolder of the child adapter is throwing error.
Please check My parent Adapter class below:
public class MyRecyler1Adapter: MvxRecyclerAdapter
{
private Activity _activity;
public static int MEETING_TYPE = 0;
public static int DOCUMENTS_TYPE = 1;
public NewResponse _response;
Meeting1Adapter adapter;
Documents1Adapter docadapter;
public List<MeetingDetails> meetingDetailList { get; set; }
public List<DocumentDetails> docDetailsList { get; set; }
public bool btnDocStatus = false;
public NewViewModel viewModel;
public MyRecyler1Adapter(IMvxAndroidBindingContext bindingContext, Activity context, NewResponse response,NewViewModel model)
: base(bindingContext)
{
this._activity = context;
this._response = response;
this.viewModel = model;
}
public override int ItemCount
{
get { return 2; }
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
if (position == 0 && _response.Meetings != null)
{
var meeting = holder as MeetingsTypeViewHolder;
meeting.txtMeg.Text = "Meeting";_response.Meetings.Meetings[position].MeetingTitle+position);
adapter = new Meeting1Adapter(BindingContext, _activity, _response.Meetings);
meeting.recycle.SetAdapter(adapter);
meetingDetailList = _response.Meetings.Meetings;
}
else if (position == 1 && _response.Documents != null)
{
var documents = holder as DocumentsTypeViewHolder;
documents.txtMsg.Text = "Documents";
docadapter = new Documents1Adapter((IMvxAndroidBindingContext)BindingContext,_activity, _response.Documents);
documents.recycle.SetAdapter(docadapter);
docDetailsList = _response.Documents.Documents;
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
View itemView;
switch (viewType)
{
case 0:
if (_response.Meetings != null)
{
var itemBindingContext = new MvxAndroidBindingContext(parent.Context, this.BindingContext.LayoutInflaterHolder);
var id = Resource.Layout.layout1;
itemView = LayoutInflater.From(parent.Context).Inflate(id, parent, false);
return new MeetingsTypeViewHolder(itemView, itemBindingContext);
}
case 1:
if (_response.Documents != null)
{
var itemBindingContext = new MvxAndroidBindingContext(parent.Context, this.BindingContext.LayoutInflaterHolder);
var id1 = Resource.Layout.layout2;
itemView = LayoutInflater.From(parent.Context).Inflate(id1, parent, false);
return new DocumentsTypeViewHolder(itemView, itemBindingContext);
}
}
return null;
}
public class MeetingsTypeViewHolder : MvxRecyclerViewHolder
{
public TextView txtMeg { get; private set; }
public MvxRecyclerView recycle { get; set; }
public Button btnShowMore { get; set; }
public MeetingsTypeViewHolder(View itemView, IMvxAndroidBindingContext context) : base(itemView, context)
{
txtMeg = itemView.FindViewById<TextView>(Resource.Id.textView1);
recycle = itemView.FindViewById<MvxRecyclerView>(Resource.Id.rec1);
btnShowMore = itemView.FindViewById<Button>(Resource.Id.btnShowMore);
}
}
public class DocumentsTypeViewHolder : MvxRecyclerViewHolder
{
public TextView txtMsg { get; private set; }
public RecyclerView recycle { get; set; }
public Button btnShowMore { get; set; }
public DocumentsTypeViewHolder(View itemView, IMvxAndroidBindingContext context) : base(itemView, context)
{
txtMsg = itemView.FindViewById<TextView>(Resource.Id.textView1);
recycle = itemView.FindViewById<RecyclerView>(Resource.Id.rec1);
btnShowMore = itemView.FindViewById<Button>(Resource.Id.btnShowMore);
}
}
public override int GetItemViewType(int position)
{
switch (position)
{
case 0:
return MEETING_TYPE;
case 1:
return DOCUMENTS_TYPE;
default:
return -1;
}
}
}
Child adapter sample:
public class Meeting1Adapter: MvxRecyclerAdapter
{
private Activity activity;
public MeetingsMain meetingMain { get; set; }
public Meeting1Adapter(IMvxAndroidBindingContext bindingContext, Activity activity, MeetingsMain meetingsMain)
: base(bindingContext)
{
this.activity = activity;
this.meetingMain = meetingsMain;
}
public void RefreshItems(Object response)
{
if (response is List<ContactDetails>)
meetingMain.Meetings = (List<MeetingDetails>)response;
NotifyDataSetChanged();
}
public override int ItemCount
{
get { return meetingMain.Meetings.Count; }
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
var meeting = holder as MeetingsAdapterValueTypeViewHolder;
meeting.txtMeg.Text = meetingMain.Meetings[position].MeetingTitle;
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
try
{
var itemBindingContext = new MvxAndroidBindingContext(parent.Context, this.BindingContext.LayoutInflaterHolder);
var id = Resource.Layout.item_layout;
View itemView = LayoutInflater.From(parent.Context).Inflate(id, parent, false);
return new MeetingsAdapterValueTypeViewHolder(itemView, itemBindingContext);
}catch(Exception e)
{
Console.WriteLine("Exception in response ## " + e.Message);
}
return null;
}
public class MeetingsAdapterValueTypeViewHolder : MvxRecyclerViewHolder
{
// public ImageView Image { get; private set; }
public TextView txtMeg { get; private set; }
public MeetingsAdapterValueTypeViewHolder(View itemView, IMvxAndroidBindingContext ctxt) : base(itemView,ctxt)
{
txtMeg = itemView.FindViewById<TextView>(Resource.Id.textView);
}
}
}
}
Problem : In the child adapter ,OnCreateViewHolder () method is not calling.
Thanks in advance.
After 2 days in searching the solution ,finally i got the result.
The main thing we should check while loading MvxRecyclerview is
1: MvxRecyclerView.LayoutManager.
2:In Child Adapter,Since we are using MvxRecyclerView,we should use IMvxAndroidBindingContext
and the associated adapter changes like
a:Adapter should extend MvxRecyclerAdapter
b: use MvxRecyclerViewHolder
------------------------------------------Edit Your Adapter in the below mentioned way----
Code change made in MyRecyler1Adapter:
MvxRecyclerView.LayoutManager layoutManager;//Dont use RecyclerView.LayoutManager
Inside the OnBindViewHolder()
layoutManager = new LinearLayoutManager(_activity, LinearLayoutManager.Vertical, false);
meeting.recycle.SetLayoutManager(layoutManager);
Inside Child Adapter:
public class Meeting1Adapter: MvxRecyclerAdapter
{
private Activity activity;
public IMvxAndroidBindingContext bindingCtxt;
protected IMvxAndroidBindingContext BindingContext => bindingCtxt;
public MeetingsMain meetingMain { get; set; }
public Meeting1Adapter(IMvxAndroidBindingContext bindingContext, Activity activity, MeetingsMain meetingsMain)
{
this.bindingCtxt = bindingContext;
this.activity = activity;
this.meetingMain = meetingsMain;
}
----
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
try
{
var itemBindingContext = new MvxAndroidBindingContext(parent.Context, this.BindingContext.LayoutInflaterHolder);
var id = Resource.Layout.item_layout;
View itemView = LayoutInflater.From(parent.Context).Inflate(id, parent, false);
return new MeetingsAdapterValueTypeViewHolder(itemView, itemBindingContext);
// return new MeetingsAdapterValueTypeViewHolder(itemView);
}
catch (Exception e)
{
Console.WriteLine("Exception in response ## " + e.Message);
}
return null;
}
----
}
I have a recycler view with linearlayout and textviews inside cardview. I would like to implement onclick method for my item where in I would like to change the background color of the linear layout and invert the textcolor of the textviews. I have got it working but the main issue I am facing is that if I select 1st item then 1st as well as 7th items color is changed.
Trying to get this to work since two days. Any help would be appreciated.
Here is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Models.ViewModels;
using Android.App;
using Android.Content;
using Android.Graphics;
using Android.OS;
using Android.Runtime;
using Android.Support.V7.Widget;
using Android.Views;
using Android.Widget;
namespace A.Droid.Adapters
{
public class DeliveryAdapter : RecyclerView.Adapter//, View.IOnClickListener
{
List<RequestViewModel> list;
public Context v;
public event EventHandler<int> phoneClick;
List<RequestViewModel> selectedList = new List<RequestViewModel>();
public DeliveryAdapter(List<RequestViewModel> records, Context v1)
{
list = records;
v = v1;
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
// Inflate the CardView for the photo:
View itemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.activity_cardview_slinkyRecordList, parent, false);
DeliveryListViewHolder vh = new DeliveryListViewHolder(itemView, OnPhoneClick);
return vh;
}
// Fill in the contents of the photo card (invoked by the layout manager):
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
DeliveryListViewHolder viewHolder = holder as DeliveryListViewHolder;
viewHolder.PICNumber.Text = string.IsNullOrEmpty(list[position].PICNumber) ? "-" : list[position].PICNumber;
viewHolder.PropertyName.Text = string.IsNullOrEmpty(list[position].PropertyName) ? "-" : list[position].PropertyName;
viewHolder.ContactAddress.Text = string.IsNullOrEmpty(list[position].ContactAddress) ? "-" : list[position].ContactAddress;
viewHolder.ContactPerson.Text = string.IsNullOrEmpty(list[position].ContactPerson) ? "-" : list[position].ContactPerson;
viewHolder.ContactNumber.Text = string.IsNullOrEmpty(list[position].ContactNumber) ? "-" : list[position].ContactNumber;
viewHolder.NumberOfAliveSpecies.Text = list[position].NumberOfAliveStock + " Alive " + list[position].NameOfSpecies;
viewHolder.NumberOfDeadSpecies.Text = list[position].NumberOfDeadStock + " Dead " + list[position].NameOfSpecies;
viewHolder.DistanceOfTransporterToPIC.Text = list[position].DistanceOfTransporterFromPIC.ToString() + " KM"; //DeliveryList[position].DistanceOfTransporterFromPIC.ToString();
//viewHolder.MainLinearLayout.SetOnClickListener((new OnClickListener(viewHolder.MainLinearLayout,position)); // cardViewList.Add(viewHolder.cardView); //add all the cards to this list
//viewHolder.MainLinearLayout.SetOnClickListener(this); // cardViewList.Add(viewHolder.cardView); //add all the cards to this list
viewHolder.cardView.Click += delegate (object sender, EventArgs e)
{
if (selectedList.All(i => i.slinkyStockRequestId != list[position].slinkyStockRequestId))
{
selectedList.Add(list[position]);
viewHolder.MainLinearLayout.SetBackgroundColor(v.Resources.GetColor(Resource.Color.white));
viewHolder.PICNumber.SetTextColor(v.Resources.GetColor(Resource.Color.dark_blue));
viewHolder.PropertyName.SetTextColor(v.Resources.GetColor(Resource.Color.dark_blue));
viewHolder.ContactAddress.SetTextColor(v.Resources.GetColor(Resource.Color.dark_blue));
viewHolder.ContactPerson.SetTextColor(v.Resources.GetColor(Resource.Color.dark_blue));
viewHolder.ContactNumber.SetTextColor(v.Resources.GetColor(Resource.Color.dark_blue));
viewHolder.NumberOfAliveSpecies.SetTextColor(v.Resources.GetColor(Resource.Color.dark_blue));
viewHolder.NumberOfDeadSpecies.SetTextColor(v.Resources.GetColor(Resource.Color.dark_blue));
viewHolder.DistanceOfTransporterToPIC.SetTextColor(v.Resources.GetColor(Resource.Color.dark_blue));
viewHolder.mapIcon.SetColorFilter(v.Resources.GetColor(Resource.Color.dark_blue), PorterDuff.Mode.SrcAtop);
viewHolder.contactIcon.SetColorFilter(v.Resources.GetColor(Resource.Color.dark_blue), PorterDuff.Mode.SrcAtop);
viewHolder.phoneIcon.SetColorFilter(v.Resources.GetColor(Resource.Color.dark_blue), PorterDuff.Mode.SrcAtop);
}
else
{
selectedList.Remove(list[position]);
viewHolder.MainLinearLayout.SetBackgroundColor(v.Resources.GetColor(Resource.Color.dark_blue));
viewHolder.PICNumber.SetTextColor(v.Resources.GetColor(Resource.Color.white));
viewHolder.PropertyName.SetTextColor(v.Resources.GetColor(Resource.Color.white));
viewHolder.ContactAddress.SetTextColor(v.Resources.GetColor(Resource.Color.white));
viewHolder.ContactPerson.SetTextColor(v.Resources.GetColor(Resource.Color.white));
viewHolder.ContactNumber.SetTextColor(v.Resources.GetColor(Resource.Color.white));
viewHolder.NumberOfAliveSpecies.SetTextColor(v.Resources.GetColor(Resource.Color.white));
viewHolder.NumberOfDeadSpecies.SetTextColor(v.Resources.GetColor(Resource.Color.white));
viewHolder.DistanceOfTransporterToPIC.SetTextColor(v.Resources.GetColor(Resource.Color.white));
viewHolder.mapIcon.SetColorFilter(v.Resources.GetColor(Resource.Color.white), PorterDuff.Mode.SrcAtop);
viewHolder.contactIcon.SetColorFilter(v.Resources.GetColor(Resource.Color.white), PorterDuff.Mode.SrcAtop);
viewHolder.phoneIcon.SetColorFilter(v.Resources.GetColor(Resource.Color.white), PorterDuff.Mode.SrcAtop);
}
};
animate(holder);
}
public List<RequestViewModel> GetSelectedItems()
{
return selectedList;
}
// Return the number of photos available in the photo album:
public override int ItemCount
{
get { return list.Count; }
}
// Raise an event when the phone-click takes place:
void OnPhoneClick(int position)
{
if (phoneClick != null)
{
phoneClick(this, position);
}
}
public class DeliveryListViewHolder : RecyclerView.ViewHolder
{
public ImageView MapTag { get; private set; }
public TextView PICNumber { get; private set; }
public TextView PropertyName { get; private set; }
public TextView ContactAddress { get; private set; }
public TextView ContactPerson { get; private set; }
public TextView ContactNumber { get; private set; }
public TextView NameOfSpecies { get; private set; }
public TextView NumberOfAliveSpecies { get; private set; }
public TextView NumberOfDeadSpecies { get; private set; }
public TextView DistanceOfTransporterToPIC { get; private set; }
public CardView cardView { get; private set; }
public LinearLayout MainLinearLayout { get; private set; }
public ImageView mapIcon { get; private set; }
public ImageView contactIcon { get; private set; }
public ImageView phoneIcon { get; private set; }
// Get references to the views defined in the CardView layout.
public DeliveryListViewHolder(View itemView, Action<int> phoneClickListener) : base(itemView)
{
MapTag = itemView.FindViewById<ImageView>(Resource.Id.mapIcon);
PICNumber = itemView.FindViewById<TextView>(Resource.Id.PICNumber);
PropertyName = itemView.FindViewById<TextView>(Resource.Id.nameOfProperty);
ContactPerson = itemView.FindViewById<TextView>(Resource.Id.contactPerson);
NumberOfAliveSpecies = itemView.FindViewById<TextView>(Resource.Id.noOfAliveSpecies);
NumberOfDeadSpecies = itemView.FindViewById<TextView>(Resource.Id.noOfDeadSpecies);
DistanceOfTransporterToPIC = itemView.FindViewById<TextView>(Resource.Id.areaInKM);
ContactAddress = itemView.FindViewById<TextView>(Resource.Id.address);
ContactNumber = itemView.FindViewById<TextView>(Resource.Id.mobileNo);
mapIcon = itemView.FindViewById<ImageView>(Resource.Id.mapIcon);
contactIcon = itemView.FindViewById<ImageView>(Resource.Id.contactIcon);
phoneIcon = itemView.FindViewById<ImageView>(Resource.Id.phoneIcon);
cardView = itemView.FindViewById<CardView>(Resource.Id.mainCardviewLayout);
MainLinearLayout = itemView.FindViewById<LinearLayout>(Resource.Id.MainLinearLayout);
ContactNumber.Click += (sender, e) => phoneClickListener(base.Position);
}
}
}
}
Edit
From Deep Patel input, here is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Models.ViewModels;
using Android.App;
using Android.Content;
using Android.Graphics;
using Android.OS;
using Android.Runtime;
using Android.Support.V7.Widget;
using Android.Views;
using Android.Widget;
namespace A.Droid.Adapters
{
public class DeliveryAdapter : RecyclerView.Adapter//, View.IOnClickListener
{
List<RequestViewModel> list;
public Context v;
public event EventHandler<int> phoneClick;
List<RequestViewModel> selectedList = new List<RequestViewModel>();
public DeliveryAdapter(List<RequestViewModel> records, Context v1)
{
list = records;
v = v1;
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
// Inflate the CardView for the photo:
View itemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.activity_cardview_slinkyRecordList, parent, false);
DeliveryListViewHolder vh = new DeliveryListViewHolder(itemView, OnPhoneClick);
return vh;
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
DeliveryListViewHolder viewHolder = holder as DeliveryListViewHolder;
viewHolder.PICNumber.Text = string.IsNullOrEmpty(list[position].PICNumber) ? "-" : list[position].PICNumber;
viewHolder.PropertyName.Text = string.IsNullOrEmpty(list[position].PropertyName) ? "-" : list[position].PropertyName;
viewHolder.ContactAddress.Text = string.IsNullOrEmpty(list[position].ContactAddress) ? "-" : list[position].ContactAddress;
viewHolder.ContactPerson.Text = string.IsNullOrEmpty(list[position].ContactPerson) ? "-" : list[position].ContactPerson;
viewHolder.ContactNumber.Text = string.IsNullOrEmpty(list[position].ContactNumber) ? "-" : list[position].ContactNumber;
viewHolder.NumberOfAliveSpecies.Text = list[position].NumberOfAliveStock + " Alive " + list[position].NameOfSpecies;
viewHolder.NumberOfDeadSpecies.Text = list[position].NumberOfDeadStock + " Dead " + list[position].NameOfSpecies;
viewHolder.DistanceOfTransporterToPIC.Text = list[position].DistanceOfTransporterFromPIC.ToString() + " KM"; //DeliveryList[position].DistanceOfTransporterFromPIC.ToString();
//viewHolder.MainLinearLayout.SetOnClickListener((new OnClickListener(viewHolder.MainLinearLayout,position)); // cardViewList.Add(viewHolder.cardView); //add all the cards to this list
//viewHolder.MainLinearLayout.SetOnClickListener(this); // cardViewList.Add(viewHolder.cardView); //add all the cards to this list
viewHolder.cardView.Click += delegate (object sender, EventArgs e)
{
setSelectedPosition(position);
};
viewHolder.MainLinearLayout.SetBackgroundColor(list[position].isSelected() ? v.Resources.GetColor(Resource.Color.white) : v.Resources.GetColor(Resource.Color.dark_blue));
animate(holder);
}
private void setSelectedPosition(int position)
{
for (int i = 0; i < list.Count(); i++)
{
list[position].setSelected(i == position);
}
NotifyDataSetChanged();
}
public List<RequestViewModel> GetSelectedItems()
{
return selectedList;
}
// Return the number of photos available in the photo album:
public override int ItemCount
{
get { return list.Count; }
}
// Raise an event when the phone-click takes place:
void OnPhoneClick(int position)
{
if (phoneClick != null)
{
phoneClick(this, position);
}
}
public class DeliveryListViewHolder : RecyclerView.ViewHolder
{
public ImageView MapTag { get; private set; }
public TextView PICNumber { get; private set; }
public TextView PropertyName { get; private set; }
public TextView ContactAddress { get; private set; }
public TextView ContactPerson { get; private set; }
public TextView ContactNumber { get; private set; }
public TextView NameOfSpecies { get; private set; }
public TextView NumberOfAliveSpecies { get; private set; }
public TextView NumberOfDeadSpecies { get; private set; }
public TextView DistanceOfTransporterToPIC { get; private set; }
public CardView cardView { get; private set; }
public LinearLayout MainLinearLayout { get; private set; }
public ImageView mapIcon { get; private set; }
public ImageView contactIcon { get; private set; }
public ImageView phoneIcon { get; private set; }
// Get references to the views defined in the CardView layout.
public DeliveryListViewHolder(View itemView, Action<int> phoneClickListener) : base(itemView)
{
MapTag = itemView.FindViewById<ImageView>(Resource.Id.mapIcon);
PICNumber = itemView.FindViewById<TextView>(Resource.Id.PICNumber);
PropertyName = itemView.FindViewById<TextView>(Resource.Id.nameOfProperty);
ContactPerson = itemView.FindViewById<TextView>(Resource.Id.contactPerson);
NumberOfAliveSpecies = itemView.FindViewById<TextView>(Resource.Id.noOfAliveSpecies);
NumberOfDeadSpecies = itemView.FindViewById<TextView>(Resource.Id.noOfDeadSpecies);
DistanceOfTransporterToPIC = itemView.FindViewById<TextView>(Resource.Id.areaInKM);
ContactAddress = itemView.FindViewById<TextView>(Resource.Id.address);
ContactNumber = itemView.FindViewById<TextView>(Resource.Id.mobileNo);
mapIcon = itemView.FindViewById<ImageView>(Resource.Id.mapIcon);
contactIcon = itemView.FindViewById<ImageView>(Resource.Id.contactIcon);
phoneIcon = itemView.FindViewById<ImageView>(Resource.Id.phoneIcon);
cardView = itemView.FindViewById<CardView>(Resource.Id.mainCardviewLayout);
MainLinearLayout = itemView.FindViewById<LinearLayout>(Resource.Id.MainLinearLayout);
ContactNumber.Click += (sender, e) => phoneClickListener(base.Position);
}
}
}
}
in your model,
take a boolean variable, and create getter setter methods
private boolean isSelected = false
public boolean isSelected() {
return isSelected;
}
public void setSelected(boolean selected) {
isSelected = selected;
}
in your OnBindViewHolder
viewHolder.MainLinearLayout.SetBackgroundColor(list[position].isSelected()?v.Resources.GetColor(Resource.Color.white):v.Resources.GetColor(Resource.Color.black));
in your onClick event, // Code below is edited
Note: For Best practice setTag(position) with your position to your view that is getting clicked and use that tag value as a position.
int pos = (int) view.getTag();
list[pos].setSelected(!list[pos].isSelected());
notifyItemChanged(position);
You need to reset the background color of your view at OnBindViewHolder() because views are reused here
Add these lines on your OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
if (selectedList.All(i => i.slinkyStockRequestId != list[position].slinkyStockRequestId))
viewHolder.MainLinearLayout.SetBackgroundColor(v.Resources.GetColor(Resource.C olor.white));
else
viewHolder.MainLinearLayout.SetBackgroundColor(v.Resources.GetColor(Resource.Color.dark_blue));
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.