In the code below I have a ListView with a Items list containing Name, Id and Quantity. When I click on a row this value should be updated according to informed parameter in UpdateItemSelectedInListView () method. But only line 9 is having the changed value, independent of the line that I select.
Activity:
public class MainActivity : Activity
{
ListView _ListView;
AdapterItem _Adapter;
List<Item> _ListaItem = new List<Item>();
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
CriaListView();
}
private void CriaListView()
{
_ListView = FindViewById<ListView>(Resource.Id.listaItems);
_ListView.ItemClick += _ListView_ItemClick;
_ListView.Adapter = CriaAdapter();
}
private AdapterItem CriaAdapter()
{
for (int i = 0; i < 15; i++)
{
_ListaItem.Add(new Item("Test Name",i));
}
_Adapter = new AdapterItem(this, _ListaItem);
return _Adapter;
}
void _ListView_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
{
_Adapter.UpdateItemSelectedInListView(e.Position, 5);
}
}
Adapter:
public class AdapterItem : BaseAdapter
{
List<Item> _ListaItem = new List<Item>();
Activity _Activity;
LayoutInflater _Inflate;
ViewHolderItem _HolderItem;
Boolean _HasUpdate;
int _IdToUpDate;
int _NewQntd;
int _Position;
public AdapterItem(Activity activity, List<Item> listaItem)
{
_Activity = activity;
_ListaItem = listaItem;
try
{
_Inflate = (LayoutInflater)_Activity.GetSystemService(Context.LayoutInflaterService);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
View _View;
public override View GetView(int position, Android.Views.View convertView, Android.Views.ViewGroup parent)
{
_View = convertView;
try
{
if (_View != null)
_HolderItem = _View.Tag as ViewHolderItem;
else
{
_View = _Activity.LayoutInflater.Inflate(Resource.Layout.LayoutItem, null);
_HolderItem = CriaViewHolder();
}
PopulaViewHolder(position);
_View.Tag = _HolderItem;
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
return _View;
}
private ViewHolderItem CriaViewHolder()
{
ViewHolderItem holderItem = new ViewHolderItem();
holderItem.txtNameItem = _View.FindViewById<TextView>(Resource.Id.nameItem);
holderItem.txtIdItem = _View.FindViewById<TextView>(Resource.Id.idItem);
holderItem.txtqntItem = _View.FindViewById<TextView>(Resource.Id.totalInStock);
return holderItem;
}
private void PopulaViewHolder(int position)
{
_HolderItem.txtNameItem.Text = _ListaItem[position].nome;
_HolderItem.txtIdItem.Text = _ListaItem[position].id.ToString();
if (_HasUpdate && (position == _Position))
UpdateAdapter();
}
public void UpdateAdapter()
{
_HolderItem.txtqntItem.Text = _NewQntd.ToString();
_HasUpdate = false;
}
public void UpdateItemSelectedInListView(int position, int newValue)
{
_NewQntd = newValue;
_HasUpdate = true;
_Position = position;
this.NotifyDataSetChanged();
}
public override Java.Lang.Object GetItem(int position)
{
return 0;
}
public override int Count
{
get {return _ListaItem.Count; }
}
public override long GetItemId(int position)
{
return _ListaItem[position].id;
}
public override int GetItemViewType(int position)
{
return base.GetItemViewType(position);
}
public override int ViewTypeCount
{
get
{
return base.ViewTypeCount;
}
}
private class ViewHolderItem : Java.Lang.Object
{
public TextView txtNameItem { get; set; }
public TextView txtIdItem { get; set; }
public TextView txtqntItem { get; set; }
}
}
You need to move _View.Tag = _HolderItem; inside of the else on the GetView method:
public override View GetView(int position, Android.Views.View convertView, Android.Views.ViewGroup parent)
{
_View = convertView;
try
{
if (_View != null)
_HolderItem = _View.Tag as ViewHolderItem;
else
{
_View = _Activity.LayoutInflater.Inflate(Resource.Layout.LayoutItem, null);
_HolderItem = CriaViewHolder();
//Set the tag only when you create a new one
//otherwise you'll have the problem you are having
_View.Tag = _HolderItem;
}
PopulaViewHolder(position);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
return _View;
}
It seems that your _Adapter.UpdateItemSelectedInListView not fetching correct position as it looses the state. Instead you can make use of binding "event action" to each view row from viewholder class.
On trigger of this action event [ in GetView()] another event action to activity class to process Click event.
//Viewholder class
internal Action ActionImgViewSelectedToGetView{ get; set;}
internal void Initialize(View view)
{
imgItem=view.FindViewById<ImageView> (Resource.Id.imgItem);
imgItem.Click += delegate(object sender , EventArgs e )
{
ActionImgViewSelectedToGetView(); //action event to getview()
};
}
//in getview()
viewHolder.ActionImgViewSelectedToGetView = () =>
{
if(ActionImgSelectedToActivity!=null)
ActionImgSelectedToActivity(_lstItem[position].ItemName); //action event,targeting to activity class method
};
//activity
if ( objItemAdapter != null )
{
objItemAdapter.ActionImgSelectedToActivity -= SelectedItem;
objItemAdapter = null;
}
objItemAdapter = new ItemAdapterClass (this, lstItem);
objItemAdapter.ActionImgSelectedToActivity += SelectedItem;
listViewItem.Adapter = objItemAdapter;
void SelectedItem( string strItemName)
{
//seleced item
}
for more detail : http://appliedcodelog.blogspot.in/2015/07/working-on-issues-with-listview-in.html#WrongPosition
Related
I am currently working on an app, that finds all MP3s on a users phone and then puts them into a list. This works very fine and is very quick, even with many songs. Now I populate a new list with an object for each item of the list to then display it inside my recyclerview. The problem is, that I have 700+ songs on my phone and this blocks the UI thread quite some time.
Now, I want to use the recyclerview to not load all items from the list into the objects all at once but rather only when they are about to be displayed - but I have NO clue over how to do this. Right now, all objects are build and then displayed in a very long scrollview from the recyclerview after the UI thread has been blocked for a good 30 seconds. Can please anyone help me? Here is my code:
namespace Media_Player
{
[Activity(Label = "Media_Player", MainLauncher = true)]
public class MainActivity : Activity
{
static public MediaPlayer mediaPlayer;
List<MP3object> mp3;
MediaMetadataRetriever reader;
public static Button btn_StartOrPause, btn_Stop;
public static TextView txt_CurrentSong;
public static bool stopIsActive = false, firstStart = true;
public static Android.Net.Uri CurrentActiveSongUri;
RecyclerView mRecyclerView;
RecyclerView.LayoutManager mLayoutManager;
PhotoAlbumAdapter mAdapter;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.test);
reader = new MediaMetadataRetriever();
PopulateMP3List(ReturnPlayableMp3(true));
mediaPlayer = new MediaPlayer();
InitRecView();
}
private void InitRecView()
{
// Instantiate the adapter and pass in its data source:
mAdapter = new PhotoAlbumAdapter(mp3);
// Get our RecyclerView layout:
mRecyclerView = FindViewById<RecyclerView>(Resource.Id.recyclerView);
// Plug the adapter into the RecyclerView:
mRecyclerView.SetAdapter(mAdapter);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.SetLayoutManager(mLayoutManager);
}
private void PopulateMP3List(List<string> content)
{
mp3 = new List<MP3object>();
foreach (string obj in content)
{
WriteMetaDataToFileList(obj);
}
}
void WriteMetaDataToFileList(string obj)
{
reader.SetDataSource(obj);
//Write Mp3 as object to global list
MP3object ob = new MP3object();
{
if(reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyTitle) != "" && reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyTitle) != null)
{
ob.SongName = reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyTitle);
}
else
{
ob.SongName = Resources.GetString(Resource.String.Unknown);
}
if (reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyArtist) != "" && reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyArtist) != null)
{
ob.ArtistName = reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyArtist);
}
else
{
ob.ArtistName = Resources.GetString(Resource.String.Unknown);
}
if (reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyAlbum) != "" && reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyAlbum) != null)
{
ob.AlbumName = reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyAlbum);
}
else
{
ob.AlbumName = Resources.GetString(Resource.String.Unknown);
}
if (reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyYear) != "" && reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyYear) != null)
{
ob.Year = reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyYear);
}
else
{
ob.Year = Resources.GetString(Resource.String.Unknown);
}
if (reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyYear) != "" && reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyYear) != null)
{
ob.Year = reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyYear);
}
else
{
ob.Year = Resources.GetString(Resource.String.Unknown);
}
ob.Mp3Uri = obj; // can never be unknown!
ob.DurationInSec = int.Parse(reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyDuration)) / 1000; // can never be unknown, div by 1000 to get sec not millis
}
mp3.Add(ob);
}
public List<string> ReturnPlayableMp3(bool sdCard)
{
List<string> res = new List<string>();
string phyle;
string path1 = null;
if(sdCard) // get mp3 from SD card
{
string baseFolderPath = "";
try
{
bool getSDPath = true;
Context context = Application.Context;
Java.IO.File[] dirs = context.GetExternalFilesDirs(null);
foreach (Java.IO.File folder in dirs)
{
bool IsRemovable = Android.OS.Environment.InvokeIsExternalStorageRemovable(folder);
bool IsEmulated = Android.OS.Environment.InvokeIsExternalStorageEmulated(folder);
if (getSDPath ? IsRemovable && !IsEmulated : !IsRemovable && IsEmulated)
baseFolderPath = folder.Path;
}
}
catch (Exception ex)
{
Console.WriteLine("GetBaseFolderPath caused the following exception: {0}", ex);
}
string xy = baseFolderPath.Remove(18); // This is result after this, but this hard coded solution could be a problem on different phones.: "/storage/05B6-2226/Android/data/Media_Player.Media_Player/files"
path1 = xy;
// path to SD card and MUSIC "/storage/05B6-2226/"
}
else // get Mp3 from internal storage
{
path1 = Android.OS.Environment.ExternalStorageDirectory.ToString();
}
var mp3Files = Directory.EnumerateFiles(path1, "*.mp3", SearchOption.AllDirectories);
foreach (string currentFile in mp3Files)
{
phyle = currentFile;
res.Add(phyle);
}
return res;
}
}
public class PhotoViewHolder : RecyclerView.ViewHolder
{
public ImageView Image { get; private set; }
public TextView Caption { get; private set; }
public PhotoViewHolder(View itemView) : base(itemView)
{
// Locate and cache view references:
Image = itemView.FindViewById<ImageView>(Resource.Id.imageView);
Caption = itemView.FindViewById<TextView>(Resource.Id.textView);
}
}
public class PhotoAlbumAdapter : RecyclerView.Adapter
{
public List<MP3object> mp3;
public PhotoAlbumAdapter(List<MP3object> mp3)
{
this.mp3 = mp3;
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
View itemView = LayoutInflater.From(parent.Context).
Inflate(Resource.Layout.lay, parent, false);
PhotoViewHolder vh = new PhotoViewHolder(itemView);
return vh;
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
PhotoViewHolder vh = holder as PhotoViewHolder;
vh.Caption.Text = mp3[position].SongName;
}
public override int ItemCount
{
get { return mp3.Count(); }
}
}
}
So getting the list of strings with the locations of the Mp3 works very quickly, but then "WriteMetaDataToFileList(obj)" kicks in, comming from "PopulateMP3List(List content)" and this is what takes so long. What I think I need is for the recyclerview to only build the first 20 objects, and when the user starts scrolling, builds the next 20 objects and attaches them to list for them to also be scrolled. Please help me out here :)
Here is an abstract class:
public abstract class PaginationScrollListener extends RecyclerView.OnScrollListener {
private LinearLayoutManager linearLayoutManager;
protected PaginationScrollListener(LinearLayoutManager linearLayoutManager) {
this.linearLayoutManager = linearLayoutManager;
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int visibleItemCount = linearLayoutManager.getChildCount();
int totalItemCount = linearLayoutManager.getItemCount();
int firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition();
if (!isLoading() && !isLastPage()) {
if ((visibleItemCount + firstVisibleItemPosition) >= totalItemCount && firstVisibleItemPosition >= 0) {
loadMoreItems();
}
}
}
protected abstract void loadMoreItems();
public abstract boolean isLastPage();
public abstract boolean isLoading();
}
and In your adapter you must follow this pattern:
public class ConsultancyAdapter extends RecyclerView.Adapter<ConsultancyAdapter.ConsultancyVH> {
private static final int ITEM = 0;
private static final int LOADING = 1;
private boolean isLoadingAdded = false;
public ConsultancyAdapter(List<Consultancy> consultancies, ConsultancyAdapterListener listener) {
}
#NonNull
#Override
public ConsultancyVH onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
RecyclerView.ViewHolder viewHolder = null;
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
switch (viewType) {
case ITEM:
viewHolder = getViewHolder(parent, layoutInflater);
break;
case LOADING:
View v2 = layoutInflater.inflate(R.layout.item_progress, parent, false);
viewHolder = new ConsultancyVH(v2);
break;
}
return (ConsultancyVH) viewHolder;
}
#NonNull
private RecyclerView.ViewHolder getViewHolder(ViewGroup parent, LayoutInflater inflater) {
RecyclerView.ViewHolder viewHolder;
View v1 = inflater.inflate(R.layout.item_consultancy, parent, false);
viewHolder = new ConsultancyVH(v1);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull ConsultancyVH holder, int position) {
Consultancy consultancy = consultancies.get(position);
switch (getItemViewType(position)) {
case ITEM:
ConsultancyVH mySingeCounseller = holder;
holder.title.setText(consultancy.getTitle()); // set cardTitle
holder.fieldArea.setText(consultancy.getField_filedoctorskills());
break;
case LOADING:
break;
}
}
#Override
public int getItemCount() {
return consultancies.size();
}
#Override
public int getItemViewType(int position) {
return (position == consultancies.size() - 1 && isLoadingAdded) ? LOADING : ITEM;
}
public void add(Consultancy mc) {
consultancies.add(mc);
notifyItemInserted(consultancies.size() - 1);
}
public void addAll(List<Consultancy> mcList) {
for (Consultancy mc : mcList) {
add(mc);
}
}
public void remove(Consultancy city) {
int position = consultancies.indexOf(city);
if (position > -1) {
consultancies.remove(position);
notifyItemRemoved(position);
}
}
public Consultancy getItem(int position) {
return consultancies.get(position);
}
public void clear() {
isLoadingAdded = false;
while (getItemCount() > 0) {
remove(getItem(0));
}
}
public boolean isEmpty() {
return getItemCount() == 0;
}
public void addLoadingFooter() {
isLoadingAdded = true;
add(new Consultancy());
}
public void removeLoadingFooter() {
isLoadingAdded = false;
int position = consultancies.size() - 1;
Consultancy item = getItem(position);
if (item != null) {
consultancies.remove(position);
notifyItemRemoved(position);
}
}
public interface ConsultancyAdapterListener {
void onCaseClicked(int position, String nid, String fieldArea, String title);
}
protected class ConsultancyVH extends RecyclerView.ViewHolder {
private TextView title, fieldArea;
private CircleImageView iconProfile;
private MaterialRippleLayout caseButtonRipple;
public ConsultancyVH(View itemView) {
super(itemView);
caseButtonRipple = itemView.findViewById(R.id.case_button_ripple);
this.title = itemView.findViewById(R.id.docName);
this.fieldArea = itemView.findViewById(R.id.fieldArea);
this.iconProfile = itemView.findViewById(R.id.icon_profile);
}
}
}
and in your activity:
private void setScrollListener() {
recyclerView.addOnScrollListener(new PaginationScrollListener(linearLayoutManager) {
#Override
protected void loadMoreItems() {
isLoading = true;
currentPage += 1;
loadNextPage();
}
#Override
public boolean isLastPage() {
return isLastPage;
}
#Override
public boolean isLoading() {
return isLoading;
}
});
loadFirstPage();
}
and in my loadFirstPage i talk to a API and you need some your code:
private void loadFirstPage() {
CallData().enqueue(new DefaultRetrofitCallback<List<Consultancy>>() {
#Override
protected void onFailure(Throwable t) {
super.onFailure(t);
}
#Override
protected void onSuccess(List<Consultancy> response) {
swipeRefreshLayout.setRefreshing(false);
dataList = response;
adapter.addAll(dataList);
recyclerView.setAdapter(adapter);
if (!checkLast(response)) adapter.addLoadingFooter();
else isLastPage = true;
}
#Override
protected void onOtherStatus(Response<List<Consultancy>> response) {
super.onOtherStatus(response);
}
#Override
protected void always() {
super.always();
}
});
}
and loadNextPage:
private void loadNextPage() {
CallData().enqueue(new DefaultRetrofitCallback<List<Consultancy>>() {
#Override
protected void onFailure(Throwable t) {
super.onFailure(t);
}
#Override
protected void onSuccess(List<Consultancy> response) {
swipeRefreshLayout.setRefreshing(false);
adapter.removeLoadingFooter();
isLoading = false;
swipeRefreshLayout.setRefreshing(false);
adapter.addAll(response);
if (!checkLast(response)) adapter.addLoadingFooter();
else isLastPage = true;
}
#Override
protected void onOtherStatus(Response<List<Consultancy>> response) {
super.onOtherStatus(response);
}
#Override
protected void always() {
super.always();
}
});
}
For the given RecyclerView, I can access the LinearLayout element by:
recyclerView.findViewHolderForAdapterPosition(1)
Where 1 is the 2nd element/position within RecyclerView and the ViewHolder is returned.
How can I then access the child elements of the ViewHolder LinearLayout? Or is there a way to get to the AppCompatTextView element so that I can pull the text from that element?
I have created RecyclerViewMatcher class then following code
onView(withRecyclerView(R.id.rv_fragment_recipes).atPosition(0))
.check(matches(isDisplayed()));
onView(withRecyclerView(R.id.rv_fragment_recipes).atPositionOnView(0, R.id.tv_recipe_name))
.check(matches(isDisplayed()))
.check(matches(withText("Nutella Pie")));
onView(withRecyclerView(R.id.rv_fragment_recipes).atPositionOnView(0, R.id.tv_servings))
.check(matches(isDisplayed()))
.check(matches(withText("Servings : 8")));
onView(withRecyclerView(R.id.rv_fragment_recipes).atPosition(0))
.perform(click());
public class RecyclerViewMatcher {
private final int recyclerViewId;
public RecyclerViewMatcher(int recyclerViewId) {
this.recyclerViewId = recyclerViewId;
}
public Matcher<View> atPosition(final int position) {
return atPositionOnView(position, -1);
}
public Matcher<View> atPositionOnView(final int position, final int targetViewId) {
return new TypeSafeMatcher<View>() {
Resources resources = null;
View childView;
public void describeTo(Description description) {
String idDescription = Integer.toString(recyclerViewId);
if (this.resources != null) {
try {
idDescription = this.resources.getResourceName(recyclerViewId);
} catch (Resources.NotFoundException var4) {
idDescription = String.format("%s (resource name not found)",
new Object[] { Integer.valueOf
(recyclerViewId) });
}
}
description.appendText("with id: " + idDescription);
}
public boolean matchesSafely(View view) {
this.resources = view.getResources();
if (childView == null) {
RecyclerView recyclerView =
(RecyclerView) view.getRootView().findViewById(recyclerViewId);
if (recyclerView != null && recyclerView.getId() == recyclerViewId) {
childView = recyclerView.findViewHolderForAdapterPosition(position).itemView;
}
else {
return false;
}
}
if (targetViewId == -1) {
return view == childView;
} else {
View targetView = childView.findViewById(targetViewId);
return view == targetView;
}
}
};
}
}
for refernce you can follow this project
Use IdelingResource if recyclerView data is not static
https://github.com/bignerdranch/expandable-recycler-view
With the help of the above library, I was able to implement a expandable RecyclerView, the expand and collapse all works fine. Now I need the different click listeners for child and parent. I was able to able implement a click listener, but I'm having trouble finding the child and parent positions.
the position integer variable available inside the Adapter returns only the overall position in the case of a normal RecyclerView. When clicking parent and child items, it returns different values depending on whether the parent is expanded or collapsed.
What I really want is When I click a parent I want the parent position. And when I click a child I want the parent and child position.
This is my Adapter class
public class LeftNavAdapter : ExpandableRecyclerAdapter<LeftNavParentViewHolder, LeftNavChildViewHolder>
{
LayoutInflater _inflater;
public event EventHandler<int> ItemClick;
public LeftNavAdapter(Context context, List<IParentObject> itemList) : base(context, itemList)
{
_inflater = LayoutInflater.From(context);
}
#region implemented abstract members of ExpandableRecyclerAdapter
public override LeftNavParentViewHolder OnCreateParentViewHolder(ViewGroup parentViewGroup)
{
var view = _inflater.Inflate(Resource.Layout.left_nav_item_parent, parentViewGroup, false);
return new LeftNavParentViewHolder(view);
}
public override LeftNavChildViewHolder OnCreateChildViewHolder(ViewGroup childViewGroup)
{
var view = _inflater.Inflate(Resource.Layout.left_nav_item_child, childViewGroup, false);
return new LeftNavChildViewHolder(view, OnChildClick);
}
public override void OnBindParentViewHolder(LeftNavParentViewHolder parentViewHolder, int position, object parentObject)
{
var parent = (LeftNavParent)parentObject;
parentViewHolder.nameTextView.Text = parent.title;
parentViewHolder.imageImageView.SetImageResource(parent.image);
if (parent.ChildObjectList.Count == 0)
parentViewHolder.exapandCollapseButton.Visibility = ViewStates.Gone;
}
public override void OnBindChildViewHolder(LeftNavChildViewHolder childViewHolder, int position, object childObject)
{
var child = (LeftNavChild) childObject;
childViewHolder.cNameTextView.Text = child.childTitle;
//childViewHolder._crimeSolvedCheckBox.CheckedChange += (object sender, CompoundButton.CheckedChangeEventArgs e) =>
//{
// Console.WriteLine("Child CheckedChanged Position: {0}", position);
//};
}
#endregion
private void OnChildClick(int position)
{
Console.WriteLine("checkpoint 2");
if (ItemClick != null)
{
Console.WriteLine("checkpoint 3");
ItemClick(this, position);
Console.WriteLine("checkpoint 4");
}
}
public override void OnParentItemClickListener(int position)
{
Toast.MakeText(_context, position + "touched", ToastLength.Short).Show();
if (_itemList[position] is IParentObject)
{
var parentObject = (IParentObject)_itemList[position];
if (parentObject.ChildObjectList.Count != 0)
{
ExpandParent(parentObject, position);
}
}
}
}
Expandable RecylerView class
public abstract class ExpandableRecyclerAdapter<PVH, CVH> : RecyclerView.Adapter, IParentItemClickListener
where PVH : ParentViewHolder
where CVH : ChildViewHolder
{
const int TypeParent = 0;
const int TypeChild = 1;
const string StableIdMap = "ExpandableRecyclerAdapter.StableIdMap";
const string StableIdList = "ExpandableRecyclerAdapter.StableIdList";
public const int CustomAnimationViewNotSet = -1;
public const long DefaultRotateDurationMs = 200;
public const long CustomAnimationDurationNotSet = -1;
Dictionary<long, bool> _stableIdMap;
ExpandableRecyclerAdapterHelper _adapterHelper;
IExpandCollapseListener _expandCollapseListener;
bool _parentAndIconClickable = false;
int _customParentAnimationViewId = CustomAnimationViewNotSet;
long _animationDuration = CustomAnimationDurationNotSet;
protected Context _context;
protected List<Object> _itemList;
protected List<IParentObject> _parentItemList;
#region Constructors
public ExpandableRecyclerAdapter(Context context, List<IParentObject> parentItemList)
: this(context, parentItemList, CustomAnimationViewNotSet, DefaultRotateDurationMs)
{
}
public ExpandableRecyclerAdapter(Context context, List<IParentObject> parentItemList,
int customParentAnimationViewId)
: this(context, parentItemList, customParentAnimationViewId, DefaultRotateDurationMs)
{
}
public ExpandableRecyclerAdapter(Context context, List<IParentObject> parentItemList,
int customParentAnimationViewId, long animationDuration)
{
_context = context;
_parentItemList = parentItemList;
_itemList = GenerateObjectList(parentItemList);
_adapterHelper = new ExpandableRecyclerAdapterHelper(_itemList);
_stableIdMap = GenerateStableIdMapFromList(_adapterHelper.HelperItemList);
_customParentAnimationViewId = customParentAnimationViewId;
_animationDuration = animationDuration;
}
#endregion
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup viewGroup, int viewType)
{
if (viewType == TypeParent)
{
var pvh = OnCreateParentViewHolder(viewGroup);
pvh.ParentItemClickListener = this;
return pvh;
}
else if (viewType == TypeChild)
{
return OnCreateChildViewHolder(viewGroup);
}
else
{
throw new ArgumentException("Invalid ViewType found");
}
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
if (_adapterHelper.GetHelperItemAtPosition(position) is ParentWrapper)
{
var parentViewHolder = (PVH)holder;
if (_parentAndIconClickable)
{
if (_customParentAnimationViewId != CustomAnimationViewNotSet &&
_animationDuration != CustomAnimationDurationNotSet)
{
parentViewHolder.SetCustomClickableViewAndItem(_customParentAnimationViewId);
parentViewHolder.AnimationDuration = _animationDuration;
}
else if (_customParentAnimationViewId != CustomAnimationViewNotSet)
{
parentViewHolder.SetCustomClickableViewAndItem(_customParentAnimationViewId);
parentViewHolder.CancelAnimation();
}
else
{
parentViewHolder.SetMainItemClickToExpand();
}
}
else
{
if (_customParentAnimationViewId != CustomAnimationViewNotSet &&
_animationDuration != CustomAnimationDurationNotSet)
{
parentViewHolder.SetCustomClickableViewOnly(_customParentAnimationViewId);
parentViewHolder.AnimationDuration = _animationDuration;
}
else if (_customParentAnimationViewId != CustomAnimationViewNotSet)
{
parentViewHolder.SetCustomClickableViewOnly(_customParentAnimationViewId);
parentViewHolder.CancelAnimation();
}
else
{
parentViewHolder.SetMainItemClickToExpand();
}
}
parentViewHolder.Expanded = ((ParentWrapper)_adapterHelper.GetHelperItemAtPosition(position)).Expanded;
OnBindParentViewHolder(parentViewHolder, position, _itemList[position]);
}
else if (_itemList[position] == null)
{
throw new NullReferenceException("Incorrect ViewHolder found");
}
else
{
OnBindChildViewHolder((CVH)holder, position, _itemList[position]);
}
}
private Dictionary<long, bool> GenerateStableIdMapFromList(List<Object> itemList)
{
var parentObjectHashMap = new Dictionary<long, bool>();
for (int i = 0; i < itemList.Count; i++)
{
if (itemList[i] != null)
{
var parentWrapper = (ParentWrapper)_adapterHelper.GetHelperItemAtPosition(i);
parentObjectHashMap.Add(parentWrapper.StableId, parentWrapper.Expanded);
}
}
return parentObjectHashMap;
}
private List<Object> GenerateObjectList(List<IParentObject> parentObjectList)
{
var objectList = new List<Object>();
foreach (var parentObject in parentObjectList)
{
objectList.Add(parentObject);
}
return objectList;
}
public override int ItemCount
{
get
{
return _itemList.Count;
}
}
public override int GetItemViewType(int position)
{
if (_itemList[position] is IParentObject)
{
return TypeParent;
}
else if (_itemList[position] == null)
{
throw new NullReferenceException("Null object added");
}
else
{
return TypeChild;
}
}
public void SetParentClickableViewAnimationDefaultDuration()
{
_animationDuration = DefaultRotateDurationMs;
}
public long AnimationDuration
{
get { return _animationDuration; }
set { _animationDuration = value; }
}
public int CustomParentAnimationViewId
{
get { return _customParentAnimationViewId; }
set { _customParentAnimationViewId = value; }
}
public bool ParentAndIconExpandOnClick
{
get { return _parentAndIconClickable; }
set { _parentAndIconClickable = value; }
}
public void RemoveAnimation()
{
_customParentAnimationViewId = CustomAnimationViewNotSet;
_animationDuration = CustomAnimationDurationNotSet;
}
public void AddExpandCollapseListener(IExpandCollapseListener expandCollapseListener)
{
_expandCollapseListener = expandCollapseListener;
}
public void ExpandParent(IParentObject parentObject, int position)
{
var parentWrapper = (ParentWrapper)_adapterHelper.GetHelperItemAtPosition(position);
if (parentWrapper == null)
{
return;
}
if (parentWrapper.Expanded)
{
parentWrapper.Expanded = false;
if (_expandCollapseListener != null)
{
var expandedCountBeforePosition = GetExpandedItemCount(position);
_expandCollapseListener.OnRecyclerViewItemCollapsed(position - expandedCountBeforePosition);
}
// Was Java HashMap put, need to replace the value
_stableIdMap[parentWrapper.StableId] = false;
//_stableIdMap.Add(parentWrapper.StableId, false);
var childObjectList = ((IParentObject)parentWrapper.ParentObject).ChildObjectList;
if (childObjectList != null)
{
for (int i = childObjectList.Count - 1; i >= 0; i--)
{
var pos = position + i + 1;
_itemList.RemoveAt(pos);
_adapterHelper.HelperItemList.RemoveAt(pos);
NotifyItemRemoved(pos);
}
}
}
else
{
parentWrapper.Expanded = true;
if (_expandCollapseListener != null)
{
var expandedCountBeforePosition = GetExpandedItemCount(position);
_expandCollapseListener.OnRecyclerViewItemExpanded(position - expandedCountBeforePosition);
}
// Was Java HashMap put, need to replace the value
_stableIdMap[parentWrapper.StableId] = true;
//_stableIdMap.Add(parentWrapper.StableId, true);
var childObjectList = ((IParentObject)parentWrapper.ParentObject).ChildObjectList;
if (childObjectList != null)
{
for (int i = 0; i < childObjectList.Count; i++)
{
var pos = position + i + 1;
_itemList.Insert(pos, childObjectList[i]);
_adapterHelper.HelperItemList.Insert(pos, childObjectList[i]);
NotifyItemInserted(pos);
}
}
}
}
private int GetExpandedItemCount(int position)
{
if (position == 0)
return 0;
var expandedCount = 0;
for (int i = 0; i < position; i++)
{
var obj = _itemList[i];
if (!(obj is IParentObject))
expandedCount++;
}
return expandedCount;
}
public Bundle OnSaveInstanceState(Bundle savedInstanceStateBundle)
{
savedInstanceStateBundle.PutString(StableIdMap, JsonConvert.SerializeObject(_stableIdMap));
return savedInstanceStateBundle;
}
public void OnRestoreInstanceState(Bundle savedInstanceStateBundle)
{
if (savedInstanceStateBundle == null)
return;
if (!savedInstanceStateBundle.ContainsKey(StableIdMap))
return;
_stableIdMap = JsonConvert.DeserializeObject<Dictionary<long, bool>>(savedInstanceStateBundle.GetString(StableIdMap));
var i = 0;
while (i < _adapterHelper.HelperItemList.Count)
{
if (_adapterHelper.GetHelperItemAtPosition(i) is ParentWrapper)
{
var parentWrapper = (ParentWrapper)_adapterHelper.GetHelperItemAtPosition(i);
if (_stableIdMap.ContainsKey(parentWrapper.StableId))
{
parentWrapper.Expanded = _stableIdMap[parentWrapper.StableId];
if (parentWrapper.Expanded)
{
var childObjectList = ((IParentObject)parentWrapper.ParentObject).ChildObjectList;
if (childObjectList != null)
{
for (int j = 0; j < childObjectList.Count; j++)
{
i++;
_itemList.Insert(i, childObjectList[j]);
_adapterHelper.HelperItemList.Insert(i, childObjectList[j]);
}
}
}
}
else
{
parentWrapper.Expanded = false;
}
}
i++;
}
NotifyDataSetChanged();
}
public abstract PVH OnCreateParentViewHolder(ViewGroup parentViewGroup);
public abstract CVH OnCreateChildViewHolder(ViewGroup childViewGroup);
public abstract void OnBindParentViewHolder(PVH parentViewHolder, int position, Object parentObject);
public abstract void OnBindChildViewHolder(CVH childViewHolder, int position, Object childObject);
#region IParentItemClickListener implementation
public abstract void OnParentItemClickListener(int position);
// {
//// if (_itemList[position] is IParentObject)
//// {
//// var parentObject = (IParentObject)_itemList[position];
////if (parentObject.ChildObjectList.Count != 0)
////{
//// ExpandParent(parentObject, position);
////}
//// }
// }
#endregion
}
This is how I accomplished it.
Created ChildViewHolder like this, passed an item click listener via constructor.
public class LeftNavChildViewHolder : ChildViewHolder
{
public TextView cNameTextView;
public LeftNavChildViewHolder(View itemView, Action<int> listener) : base(itemView)
{
cNameTextView = itemView.FindViewById<TextView>(Resource.Id.leftNavTitleChild);
itemView.Click += (sender, e) => listener(Position);
}
}
then in adapter:
public class LeftNavAdapter : ExpandableRecyclerAdapter<LeftNavParentViewHolder, LeftNavChildViewHolder>
{
public override LeftNavChildViewHolder OnCreateChildViewHolder(ViewGroup childViewGroup)
{
var view = _inflater.Inflate(Resource.Layout.left_nav_item_child, childViewGroup, false);
return new LeftNavChildViewHolder(view, OnChildClick);
}
void OnChildClick(int position)
{
// Do whatever you want
}
}
Everything work fine before i implement the json things. When i click the detail button(imageView), dialogFragment should be pop up. It is okay with the pop up, the problem is, it's generate two or more dialogFragment. Is implement json affect the viewholder? Or its related to settag gettag?
Here my code(I used api link from the tutorial) :
RecyclerAdapter :
public class MyVoteMAPOAdapter : RecyclerView.Adapter
{
public List<string> mImageList;
public List<MyVote_Data> mVoteData;
Activity context;
public event EventHandler<int> ItemClick;
public MyVoteMAPOAdapter (Activity context, List<MyVote_Data> data)
{
this.context = context;
mVoteData = data;
}
public override RecyclerView.ViewHolder OnCreateViewHolder (ViewGroup parent, int viewType)
{
View itemView = LayoutInflater.From (parent.Context).Inflate (Resource.Layout.ItemList, parent, false);
ViewHolder vh = new ViewHolder (itemView, OnClick);
itemView.Tag = vh;
return vh;
}
public override void OnBindViewHolder (RecyclerView.ViewHolder holder, int position)
{
//int item = mData[position];
IWindowManager windowManager = context.GetSystemService(Context.WindowService).JavaCast<IWindowManager>();
ViewHolder vh = holder as ViewHolder;
setImage (holder, position);
//var imageBitmap = GetImageBitmapFromUrl(mVoteData[position].mPosterImage);
vh.IVDetail.SetTag (Resource.Id.ivDetails, position);
//vh.IVPoster.SetImageBitmap (imageBitmap);
vh.IVDetail.SetImageResource (Resource.Drawable.ic_information);
vh.IVVote.SetImageResource (Resource.Drawable.undi_color);
vh.IVPoster.Click += delegate {
Android.App.FragmentTransaction trans = context.FragmentManager.BeginTransaction();
FullImageView fImage = FullImageView.newInstance(position);
vh.IVPoster.SetTag(Resource.Id.ivPoster, position);
trans.AddToBackStack(null);
trans.Replace(Resource.Id.place_holder, fImage);
trans.Commit();
};
vh.IVVote.Click += delegate {
if(vh.IVVote.Drawable.GetConstantState().Equals(Resource.Drawable.undi_color)){
vh.IVVote.SetImageResource(Resource.Drawable.undi_grey);
}
else {
vh.IVVote.SetImageResource(Resource.Drawable.undi_color);
}
};
//set a tag for the button to the current clicked position
vh.IVDetail.Click += IVDetail_Click;
vh.TVLike.Text = position.ToString();
}
public void IVDetail_Click (object sender, EventArgs e)
{
//retrieve the tag
int position = (int) (((ImageView) sender).GetTag(Resource.Id.ivDetails));
dialogShow (position);
Console.WriteLine ("KELUARRRRRR!~");
}
public void dialogShow(int position)
{
Android.App.FragmentTransaction transaction = context.FragmentManager.BeginTransaction();
//instantiate a fragment
DetailDialogFragment dialogFragment = DetailDialogFragment.newInstance (mVoteData[position].mName, mVoteData[position].mDescription);
dialogFragment.Show (transaction, "dialog_Fragment");
}
//
public async void setImage(RecyclerView.ViewHolder holder, int position)
{
ViewHolder vh = holder as ViewHolder;
string tempImageString = mVoteData[position].mPosterImage;
var imageBMP = GetImageBitmapFromUrl (tempImageString);
//vh.IVPoster.SetImageBitmap (imageBMP);
vh.IVPoster.SetTag (Resource.Id.ivPoster, position);
if (imageBMP.IsCompleted) {
vh.IVPoster.SetImageBitmap (imageBMP.Result);
} else {
vh.IVPoster.SetImageBitmap (await imageBMP);
}
}
//decode string into bitmap
public async static Task<Bitmap> GetImageBitmapFromUrl(string url)
{
Bitmap imageBitmap = null;
try{
if (url != null)
using (var webClient = new WebClient ()) {
var imageBytes = await webClient.DownloadDataTaskAsync (url);
if (imageBytes != null && imageBytes.Length > 0) {
imageBitmap = BitmapFactory.DecodeByteArray (imageBytes, 0, imageBytes.Length);
}
}
}
catch (Exception e){
Console.WriteLine ("Image Exception : {0}", e);
}
return imageBitmap;
}
public override int ItemCount{
get { return mVoteData.Count; }
}
void OnClick (int position)
{
if (ItemClick != null)
ItemClick (this, position);
}
}
public class ViewHolder : RecyclerView.ViewHolder
{
public ImageView IVPoster { get; private set; }
public TextView TVLike { get; private set; }
public ImageView IVDetail { get; private set; }
public ImageView IVVote { get; private set; }
public ViewHolder (View itemView, Action<int> listener) : base(itemView)
{
IVPoster = itemView.FindViewById <ImageView>(Resource.Id.ivPoster);
TVLike = itemView.FindViewById <TextView>(Resource.Id.tvLike);
IVDetail = itemView.FindViewById <ImageView> (Resource.Id.ivDetails);
IVVote = itemView.FindViewById <ImageView> (Resource.Id.ivVote);
itemView.Click += (sender, e) => listener (base.Position);
}
}
}
Child_Data.cs :
public class MyVote_Data
{
public string mPosterImage { get; set; }
public string mName { get; set; }
public string mDescription { get; set; }
public MyVote_Data ()
{
}
public MyVote_Data(string image, string name, string description)
{
mPosterImage = image;
mName = name;
mDescription = description;
}
public List<MyVote_Data> GetVoteData( string jsonString)
{
string tempImage, temptName, tempDescription;
var myVoteData = new List<MyVote_Data> ();
var data = JsonConvert.DeserializeObject <RootObject2> (jsonString);
foreach (var tempData in data.actors)
{
tempImage = tempData.image;
temptName = tempData.name;
tempDescription = tempData.description;
myVoteData.Add (new MyVote_Data(tempImage, temptName, tempDescription));
}
return myVoteData;
}
}
public class Actor
{
public string name { get; set; }
public string description { get; set; }
public string dob { get; set; }
public string country { get; set; }
public string height { get; set; }
public string spouse { get; set; }
public string children { get; set; }
public string image { get; set; }
}
public class RootObject2
{
public List<Actor> actors { get; set; }
}
There is one issue that I see that sticks out:
vh.IVPoster.Click += delegate {
Android.App.FragmentTransaction trans = context.FragmentManager.BeginTransaction();
FullImageView fImage = FullImageView.newInstance(position);
vh.IVPoster.SetTag(Resource.Id.ivPoster, position);
trans.AddToBackStack(null);
trans.Replace(Resource.Id.place_holder, fImage);
trans.Commit();
};
Every time your re-use your view holder, it still contains the contents of the previous view holder. What you're doing there is your adding an addtional click event handler for every view holder. That is why you're seeing multiple dialog fragments.
What you have to do is unregister the vh.IVPoster.Click event handler before you assigned the new one. So what I would do is refactor your delegate code into an actual method. You can then use "-=" to unregister any previous event handlers and "+=" to register the current event handler.
Update:
I'm doing this by hand, so you'll have to put in a little effort and fix any compile errors and use some basic troubleshooting to get it to work.
So first, create a new method called OnIVPosterClicked:
private void OnIVPosterClicked(object sender, EventArgs e)
{
Android.App.FragmentTransaction trans = context.FragmentManager.BeginTransaction();
FullImageView fImage = FullImageView.newInstance(position);
vh.IVPoster.SetTag(Resource.Id.ivPoster, position);
trans.AddToBackStack(null);
trans.Replace(Resource.Id.place_holder, fImage);
trans.Commit();
}
Then Register your event handler instead of using a delegate:
vh.IVPoster.Click += OnIVPosterClicked;
To Unregister the event handler when ViewHolders get recycled, you'll have to override the:
public override void OnViewRecycled(Java.Lang.Object holder)
{
//Unregister any View specific event handlers
var viewHolder = holder as ViewHolder;
viewHolder.IVPoster.Click -= OnIVPosterClicked;
base.OnViewRecycled(holder);
}
That's the basic gist of it. It probably won't compile if you blindly copy and paste it into your program, so you'll have to fix those. I'm not sure why you're setting tags. With this pattern, that should eliminate the use for keeping track of tags.
I have a listview with a list of items. There is an event that sends the new value for a given row of the listview. For example: I have a listview with the names ("Jhon", "Alice", "Paul", "Mary", "Stive") then the event me "warns" that the name of Jhon was changed to "Josh". How can I access the online listview containing the name "Jhon", I am using adapter and viewholder to populate the listview.
using System;
using Android.App;
using Android.Views;
using Android.Widget;
using MyApp
using Android.Content;
using System.Collections.Generic;
using Android.Graphics;
public class AdapterContatos : BaseAdapter
{
private Activity _Activity = null;
private static Usuario[] _ListaContatos;
private static Grupo[] _Listagrupos;
private static List<Object> _ListaCompleta = new List<object>();
private static LayoutInflater _Inflate = null;
private static View _View;
private static Dictionary<int, Bitmap> _DicAvatarContato = new Dictionary<int, Bitmap>();
private static Dictionary<int, Bitmap> _DicAvatarGrupo = new Dictionary<int, Bitmap>();
public AdapterContatos(Activity activity, Usuario[] listaContatos, Grupo[] listaGrupo)
{
_Activity = activity;
_ListaContatos = listaContatos;
_Listagrupos = listaGrupo;
_ListaCompleta.AddRange(_Listagrupos);
_ListaCompleta.AddRange(_ListaContatos);
try
{
_Inflate = (LayoutInflater)_Activity.GetSystemService(Context.LayoutInflaterService);
foreach (var item in _ListaContatos)
ObtemImagemArredondadaContato(item.Codigo);
foreach (var item in _Listagrupos)
ObtemImagemArredondadaGrupo(item.CodigoDoGrupo);
}
catch (Exception ex)
{
UtilExcessao.TrateExcessao(ex);
}
}
ViewHolderContato _HolderContato;
public override View GetView(int position, View convertView, ViewGroup parent)
{
_View = convertView;
try
{
if (_View != null)
_HolderContato = _View.Tag as ViewHolderContato;
else
{
_View = _Activity.LayoutInflater.Inflate(Resource.Layout.LayoutContato, null);
_HolderContato = CriaViewHolder(position);
}
PopulaViewHolder(_HolderContato, position);
_View.Tag = _HolderContato;
}
catch (Exception ex)
{
UtilExcessao.TrateExcessao(ex);
}
return _View;
}
private ViewHolderContato CriaViewHolder(int position)
{
ViewHolderContato holder = new ViewHolderContato();
holder.txtNome = _View.FindViewById<TextView>(Resource.Id.nomeContato);
holder.txtCargo = _View.FindViewById<TextView>(Resource.Id.funcaoContato);
holder.imgAvatar = _View.FindViewById<ImageView>(Resource.Id.imgAvatar);
holder.txtPrimeiraLetraNomeOuGrupo = _View.FindViewById<TextView>(Resource.Id.txtPrimeiraLetraNomeOuGrupo);
holder.txtQntdMsgNaoLidas = _View.FindViewById<TextView>(Resource.Id.imgAlertaChat);
return holder;
}
private void PopulaViewHolder(ViewHolderContato holder, int position)
{
if(EhGrupo(_ListaCompleta[position]))
PopulaViewHolderGrupo(holder,
(Grupo)_ListaCompleta[position]);
else
PopulaViewHolderUsuario(holder,
(Usuario)_ListaCompleta[position]);
}
void PopulaViewHolderGrupo(ViewHolderContato holder, Grupo grupo)
{
holder.txtNome.Text = grupo.NomeDoGrupo;
holder.txtCargo.Text = UtilFormatacao.ObtenhaNomeIntegrantesGrupoFormatado(grupo.ListaDeUsuarios);
holder.txtPrimeiraLetraNomeOuGrupo.Text = UtilFormatacao.ObtenhaPrimeiraLetraDoNome(grupo.NomeDoGrupo);
MostraAvatargrupo(holder, grupo.CodigoDoGrupo, grupo.NomeDoGrupo);
}
void PopulaViewHolderUsuario(ViewHolderContato holder, Usuario usuario)
{
holder.txtNome.Text = usuario.Nome;
holder.txtCargo.Text = usuario.Cargo;
MostraAvatarContatoPrivado(holder, usuario.Codigo, usuario.Nome);
}
void MostraAvatarContatoPrivado(ViewHolderContato holder, int codigo, string nome)
{
if (_DicAvatarContato[codigo] != null)
{
holder.imgAvatar.SetImageBitmap(_DicAvatarContato[codigo]);
holder.txtPrimeiraLetraNomeOuGrupo.Text = "";
}
else
{
holder.imgAvatar.SetImageResource(Resource.Drawable.icon_avatar_default_52);
holder.txtPrimeiraLetraNomeOuGrupo.Text = UtilFormatacao.ObtenhaPrimeiraLetraDoNome(nome);
}
}
void MostraAvatargrupo(ViewHolderContato holder, int codigoGrupo, string nomeGrupo)
{
if (_DicAvatarGrupo[codigoGrupo] != null)
{
holder.imgAvatar.SetImageBitmap(_DicAvatarGrupo[codigoGrupo]);
holder.txtPrimeiraLetraNomeOuGrupo.Text = "";
}
else
{
holder.imgAvatar.SetImageResource(Resource.Drawable.icon_avatar_default_52);
holder.txtPrimeiraLetraNomeOuGrupo.Text = UtilFormatacao.ObtenhaPrimeiraLetraDoNome(nomeGrupo);
}
}
private void ObtemImagemArredondadaContato(int codigo)
{
using (var bmp = UtilImagem.ObtemImagemArredondado(UtilImagem.ObtemImagemLocalContato(codigo), 60, 80, 80))
{
_DicAvatarContato.Add(codigo, bmp);
}
}
private void ObtemImagemArredondadaGrupo(int codigoGrupo)
{
using (var bmp = UtilImagem.ObtemImagemArredondado(UtilImagem.ObtemImagemLocalGrupo(codigoGrupo), 60, 80, 80))
{
_DicAvatarGrupo.Add(codigoGrupo, bmp);
}
}
public bool EhGrupo(Object objeto)
{
return object.Equals(objeto.GetType(),
typeof(Grupo));
}
private int ObtenhaCodigoGrupoOuUsuario(int position)
{
if (EhGrupo(_ListaCompleta[position]))
{
Grupo G = (Grupo)_ListaCompleta[position];
return G.CodigoDoGrupo;
}
else
{
Usuario U = (Usuario)_ListaCompleta[position];
return U.Codigo;
}
}
public void AdicionaNovoContato(Usuario usario)
{
}
public void RemoveContato(Usuario usuario)
{
}
public void AdicionaNovoGrupo(Grupo grupo)
{
}
public void RemoveGrupo(Grupo grupo)
{
}
public override int GetItemViewType(int position)
{
return base.GetItemViewType(position);
}
public int GetCount()
{
return _ListaCompleta.Count;
}
public override Java.Lang.Object GetItem(int position)
{
return ObtenhaCodigoGrupoOuUsuario(position);
}
public Object ObtenhaTipoObjeto(int position)
{
return _ListaCompleta[position];
}
public Grupo ObtenhaGrupoDaLista(int codigo)
{
foreach (var item in _Listagrupos)
{
if (item.CodigoDoGrupo == codigo)
return item;
}
return null;
}
public override long GetItemId(int position)
{
return ObtenhaCodigoGrupoOuUsuario(position);
}
public override int Count
{
get { return _ListaCompleta.Count; }
}
private class ViewHolderContato : Java.Lang.Object
{
public TextView txtNome { get; set; }
public TextView txtCargo { get; set; }
public TextView txtPrimeiraLetraNomeOuGrupo { get; set; }
public ImageView imgAvatar { get; set; }
}
}
Simply call notifyDataSetChanged on your Adapter. This will inform it that the data inside the ListView has changed.
More info here: http://developer.android.com/reference/android/widget/BaseAdapter.html#notifyDataSetChanged()