Started with Xamarin Android yesterday and can't seem to figure out why the Back Button script(s) won't be called.
Searched and seen that a lot of people recommend something like this:
public override void OnBackPressed()
{
Toast.MakeText(this, "Back Button Pressed", ToastLength.Short).Show();
}
However this doesn't stop my phone or the android emulator from closing the app instantly.
Most of the things I have found about this thread I haven't managed to make work for some reason or they won't be called.
Thanks
Update:
Checked another project. It works 100% there with the same code as above. Not sure what makes it not work in my project
Update
Here is some of the code. I know it's terrible but I'm just messing around trying to learn as I'm a total newbie with Xamarin & Android - Feel free to give links on something I should read however!
namespace Workout_App {
[Activity(Label = "Workout App", MainLauncher = true)]
public class MainActivity : Activity
{
private List<Exercise> mItems, mItemsDay1;
private ListView mListView;
MyListViewAdapter adapter, adapter2;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Main);
mListView = FindViewById<ListView>(Resource.Id.myListView); // myListView er navnet på objekte i AXML fila f.eks
mItems = new List<Exercise>();
mItemsDay1 = new List<Exercise>();
mItems.Add(new Exercise() { Name = "Day 1"});
mItems.Add(new Exercise() { Name = "Day 2"});
mItems.Add(new Exercise() { Name = "Day 3"});
mItemsDay1.Add(new Exercise() { Name = "Benkpress", Reps = "8x4", kg = 140});
mItemsDay1.Add(new Exercise() { Name = "Lårpress", Reps = "8x4", kg = 58});
mItemsDay1.Add(new Exercise() { Name = "BankPro", Reps = "8x4", kg = 22});
adapter = new MyListViewAdapter(this, mItems);
adapter2 = new MyListViewAdapter(this, mItemsDay1);
mListView.Adapter = adapter;
mListView.ItemClick += mListView_ItemClick; // subscribes it, - to unsub
mListView.ItemLongClick += mListView_ItemLongClick;
// mListView.ItemClick += mListView_ItemClick2;
}
public override void OnBackPressed()
{
Toast.MakeText(this, "Back Button Pressed Detected", ToastLength.Short).Show();
}
void mListView_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
{
mListView.Adapter = adapter2;
}
And this is the view
namespace Workout_App {
class MyListViewAdapter : BaseAdapter<Exercise>
{
public List<Exercise> mItems;
private Context mContext;
public MyListViewAdapter(Context context, List<Exercise> items)
{
mItems = items;
mContext = context;
}
public override int Count
{
get { return mItems.Count; }
}
public override long GetItemId(int position)
{
return position;
}
public override Exercise this[int position]
{
get { return mItems[position]; }
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
View row = convertView;
if(row == null)
{
row = LayoutInflater.From(mContext).Inflate(Resource.Layout.listview_row, null, false );
}
TextView txtName = row.FindViewById<TextView>(Resource.Id.txtName);
txtName.Text = mItems[position].Name;
TextView txtReps = row.FindViewById <TextView>(Resource.Id.txtReps);
txtReps.Text = mItems[position].Reps;
TextView txtKg = row.FindViewById<TextView>(Resource.Id.txtKg);
if(mItems[position].kg > 0) {
txtKg.Text = mItems[position].kg + " kg";
} else
{
txtKg.Text = "";
}
return row;
}
}
}
Related
I have a custom listview in my C# Android app, each row contains a textview, ImageView and a switch. When a Listview item is clicked, I want to turn the row's item switch on.
MainActivity:
List<TableList> list = = new List<TableList>();
list.Add(new TableList("Germany"));
list.Add(new TableList("France"));
list.Add(new TableList("Finland"));
listView.ItemClick += delegate (object sender, AdapterView.ItemClickEventArgs e)
{
string selected = t.Name;
if (selected == "France")
{
// Turn the proper switch for France row ON
}
};
ListAdapter and ListClass for the Listview:
public class ListAdapter : BaseAdapter<TableList>
{
List<TableList> items;
Activity context;
public ListAdapter(Activity context, List<TableList> items)
: base()
{
this.context = context;
this.items = items;
}
public override long GetItemId(int position)
{
return position;
}
public override TableList this[int position]
{
get { return items[position]; }
}
public override int Count
{
get { return items.Count; }
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
var item = items[position];
View view = convertView;
if (view == null) // no view to re-use, create new
view = context.LayoutInflater.Inflate(Resource.Layout.CoinList, null);
view.FindViewById<TextView>(Resource.Id.CoinName).Text = item.Name;
view.FindViewById<ImageView>(Resource.Id.imageView1).SetImageResource(Resource.Drawable.n);
If item is clicked set it on
{
view.FindViewById<Switch>(Resource.Id.switch).SetOn
}
else
{
view.FindViewById<Switch>(Resource.Id.switch).SetOf
}
return view;
}
}
public class TableList
{
public string Name;
public TableList(string Name)
{
this.Name = Name;
}
}
I don't know where I should set the Switch ON (in the listView.ItemClick event or in the ListAdapter) and I don't know how to set it to ON. Please help me to do so.
Here is my demo.
You can choose one to achieve your goal. I will show you how to do this by ItemClick event:
When a Listview item is clicked, I want to turn the row's item switch on.
Because, Switch will grab the focus from ViewGroup. So, I remove the focus from Switch in the MyAdapter:
holder.ms.Focusable = false;//ms is Switch
Now, this is my ItemClick event( turn switch on while click the item):
private void MListView_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
{
var ll = e.View as LinearLayout;
var sw = ll.GetChildAt(1) as Switch;
if (sw.Checked)
{
sw.Checked = false;
adapter.changeState((int)sw.Tag,false);
}
else
{
sw.Checked = true;
adapter.changeState((int)sw.Tag, true);
}
}
As we all know, ListView has reuse problem, so, I add a bool property to control the Switch's state:
public class MyData:Java.Lang.Object {
public MyData(string p,bool b) {
this.position = p;
this.isCheck = b;
}
public string position { get; set; }
public bool isCheck { get; set; }
}
Below is changeState method:
internal void changeState(int position, bool v)
{
mitems[position].isCheck = v;
this.NotifyDataSetChanged();
}
And this is CheckedChange event:
private void Ms_CheckedChange(object sender, CompoundButton.CheckedChangeEventArgs e)
{
var sm = sender as Switch;
Log.Error("Ms_CheckedChange", (int)sm.Tag+"");
if (e.IsChecked&&!mitems[(int)sm.Tag].isCheck)
{
mitems[(int)sm.Tag].isCheck = true;
this.NotifyDataSetChanged();
}
else if(!e.IsChecked&& mitems[(int)sm.Tag].isCheck)
{
mitems[(int)sm.Tag].isCheck = false;
this.NotifyDataSetChanged();
}
}
I'm trying to figure out in my customer's Mobile what causes black screens of death. The apk in different places and random moments causes a black screen of death and application stucks. I have place exceptions almost everywhere but i dont get any exception message.I will send you an examample from my code:
What can cause this black screens???
Here is my class:
class MyListViewAdapterInventory : BaseAdapter<InventoryPreviewClass>
{
public List<InventoryPreviewClass> mitems;
private Context mContext;
private int mRowLayout;
private int[] mAlternatingColors;
public MyListViewAdapterInventory(Context context, int rowLayout, List<InventoryPreviewClass> items)
{
mitems = items;
mContext = context;
mRowLayout = rowLayout;
mAlternatingColors = new int[] { 0xF2F2F2, 0xbfddff };
}
public override int Count
{
get
{
return mitems.Count;
}
}
public override long GetItemId(int position)
{
return position;
}
public override InventoryPreviewClass this[int position]
{
get
{
return mitems[position];
}
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
View row = convertView;
if (row == null)
{
row = LayoutInflater.From(mContext).Inflate(Resource.Layout.InventoryPreview, null, false);
}
row = LayoutInflater.From(mContext).Inflate(Resource.Layout.InventoryPreview, null, false);
row.SetBackgroundColor(GetColorFromInteger(mAlternatingColors[position % mAlternatingColors.Length]));
TextView txtInventoryID = row.FindViewById<TextView>(Resource.Id.txtInventoryID);
txtInventoryID.Text = mitems[position].InventoryItemID;
TextView txtInventoryName = row.FindViewById<TextView>(Resource.Id.txtInventoryName);
txtInventoryName.Text = mitems[position].InventoryItemName;
TextView txtInventoryPrice = row.FindViewById<TextView>(Resource.Id.txtInventoryPrice);
txtInventoryPrice.Text = mitems[position].InventoryItemPrice.Replace(",", ".");
Button ExtraBtn = row.FindViewById<Button>(Resource.Id.ExtrasBtn);
ExtraBtn.Click += (sender, e) =>
{
try
{
Connection.InventoryItemID = mitems[position].InventoryItemID;
Connection.InventoryItemName = mitems[position].InventoryItemName;
Connection.RetailPrice = mitems[position].InventoryItemPrice;
Toast toast = Toast.MakeText(mContext, txtInventoryName.Text, ToastLength.Short);
toast.Show();
mContext.StartActivity(typeof(ExtrasPreviewMain));
}
catch (Exception ex)
{
Toast toast = Toast.MakeText(mContext, Convert.ToString(ex), ToastLength.Long);
toast.Show();
}
};
return row;
}
private Color GetColorFromInteger(int color)
{
return Color.Rgb(Color.GetRedComponent(color), Color.GetGreenComponent(color), Color.GetBlueComponent(color));
}
}
And here is my activity Main when running:
private List<InventoryPreviewClass> mItems;
private ListView mlistview;
private EditText mSearch;
private EditText etSearchAlwaysOn;
private LinearLayout mContainer;
private bool mAnimatedDown;
private bool mIsAnimating;
private MyListViewAdapterInventory mAdapter;
string dpPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "student.db3");
SQLiteConnection db;
private TextView mTxtHeaderFirstName;
private TextView mTxtHeaderLastName;
private bool mFirstNameAscending;
private bool mLastNameAscending;
protected override void OnCreate(Bundle savedInstanceState)
{
try
{
ActionBar.SetHomeButtonEnabled(true);
ActionBar.SetDisplayHomeAsUpEnabled(true);
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.InventoryPreviewMain);
OverridePendingTransition(Resource.Layout.trans_left_in, Resource.Layout.trans_left_out);
mSearch = FindViewById<EditText>(Resource.Id.etSearch);
etSearchAlwaysOn = FindViewById<EditText>(Resource.Id.etSearchAlwaysOn);
mContainer = FindViewById<LinearLayout>(Resource.Id.llContainer);
mTxtHeaderFirstName = FindViewById<TextView>(Resource.Id.txtHeaderFirstName);
mTxtHeaderLastName = FindViewById<TextView>(Resource.Id.txtHeaderLastName);
mTxtHeaderFirstName.Click += mTxtHeaderFirstName_Click;
mTxtHeaderLastName.Click += mTxtHeaderLastName_Click;
mSearch.Alpha = 0;
mContainer.BringToFront();
mSearch.TextChanged += mSearch_TextChanged;
etSearchAlwaysOn.TextChanged += EtSearchAlwaysOn_TextChanged;
mlistview = FindViewById<ListView>(Resource.Id.InventoryList);
}
catch (Exception ex)
{
Toast.MakeText(this, Convert.ToString(ex), ToastLength.Short).Show();
}
try
{
db = new SQLiteConnection(dpPath);
var table = db.Query<InventoryPreviewClass>("select * from InventoryPreviewClass where CategoryID =" + Connection.CategoryID+ "");
mItems = new List<InventoryPreviewClass>();
foreach (var item in table)
{
mItems.Add(new InventoryPreviewClass() { InventoryItemID = item.InventoryItemID, InventoryItemName = item.InventoryItemName, InventoryItemPrice = item.InventoryItemPrice });
}
MyListViewAdapterInventory adapter = new MyListViewAdapterInventory(this, Resource.Layout.InventoryPreview, mItems);
mlistview.Adapter = adapter;
mlistview.ItemClick += Mlistview_ItemClick;
}
catch
{
}
try
{
if (SearchAlwaysOn == true)
{
var param = (LinearLayout.LayoutParams)etSearchAlwaysOn.LayoutParameters;
var WidthParam = ViewGroup.LayoutParams.MatchParent;
var HeigthParam = ViewGroup.LayoutParams.WrapContent;
param.Width = WidthParam;
param.Height = HeigthParam;
mIsAnimating = true;
}
}
catch (Exception ex)
{
Toast.MakeText(this, Convert.ToString(ex), ToastLength.Short).Show();
}
}
I have tried to look out for an answer to the behavior of my views but I seem not find any question or solution related to it. My recycler views seemed to be set up well. I just realized that my app is not responding in the right way to the OnClickListeners.
I have set up toasts in my adapter for the recycler view click events. When i have 10 views. When i click on a view, it gives a text of another view. It seems it randomly gives me the text of another view amongst the 9 remaining views. What could be the cause of this?
Activity
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
FrameLayout content = (FrameLayout)FindViewById(Resource.Id.content_frame);
LayoutInflater.Inflate(Resource.Layout.Main, content);
setUpRecyclerView();
}
public void setUpRecyclerView(){
rv = FindViewById<RecyclerView>(Resource.Id.recyclerView);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.Orientation = LinearLayoutManager.Vertical;
layoutManager.ReverseLayout = true;
layoutManager.StackFromEnd = true;
rv.HasFixedSize = true;
rv.SetLayoutManager(layoutManager);
}
Adapter
public class FeedViewHolder : RecyclerView.ViewHolder, View.IOnClickListener, View.IOnLongClickListener
{
public FeedViewHolder(View itemView):base(itemView)
{
//binding of variables here
itemView.SetOnClickListener(this);
itemView.SetOnLongClickListener(this);
}
public void OnClick(View v)
{
itemClickListener.OnClick(v, AdapterPosition, false);
}
public bool OnLongClick(View v)
{
itemClickListener.OnClick(v, AdapterPosition, true);
return true;
}
public class FeedAdapter : RecyclerView.Adapter, ItemClickListener
{
public FeedAdapter(RssObject rssObject, Context mContext)
{
this.mContext = mContext;
this.inflater = LayoutInflater.From(mContext);
activity = (MainActivity)mContext;
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
hold = holder as FeedViewHolder;
//binding
hold.itemClickListener = this;
}
public void OnClick(View view, int position, bool isLongClick)
{
Toast.MakeText(activity, "Main text : " + hold.txtContent.Text, ToastLength.Long).Show();
}
public override int ItemCount
{
get { return rssObject.items.Count; }
}
}
}
}
Hi I want to add pull to refresh on my apps using this component PullToResharp, The project is great but im having problem adding custom listview in fragment, does anyone here done this before help me resolve it, thanks.
here is the code
fragment
namespace ListViewPullToRefresh.Fragments
{
public class SampleListFragment : SupportListFragment
{
private IPullToRefresharpView _ptrView;
private List<TableItem> _itemHeading = new List<TableItem>();
public SampleListFragment() : base()
{
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.Inflate(Resource.Layout.nav, null, false);
}
public override void OnViewStateRestored(Bundle savedInstanceState)
{
base.OnViewStateRestored(savedInstanceState);
_itemHeading.Add(new TableItem(){Heading = "Ivan", Subheading = "Guinto"});
_itemHeading.Add(new TableItem(){Heading = "Jonathan", Subheading = "Guinto"});
_itemHeading.Add(new TableItem(){Heading = "Keneth", Subheading = "Guinto"});
if (_ptrView == null && ListView is IPullToRefresharpView)
{
_ptrView = (IPullToRefresharpView)ListView;
_ptrView.RefreshActivated += ptr_view_RefreshActivated;
}
ListView.Adapter = new HomeScreenAdapter(this, _itemHeading);
}
private void ptr_view_RefreshActivated(object sender, EventArgs e)
{
View.PostDelayed(() =>
{
if (_ptrView != null)
{
_ptrView.OnRefreshCompleted();
}
}, 2000);
}
public override void OnDestroyView()
{
if (_ptrView != null)
{
_ptrView.RefreshActivated -= ptr_view_RefreshActivated;
_ptrView = null;
}
base.OnDestroyView();
}
public override void OnResume()
{
base.OnResume();
ListView.ItemClick += ListView_ItemClick;
}
public override void OnPause()
{
base.OnPause();
ListView.ItemClick -= ListView_ItemClick;
}
void ListView_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
{
Toast.MakeText(Activity,e.Position+ " Clicked",ToastLength.Short).Show();
}
}
HomeScreenAdapter.cs
public class HomeScreenAdapter :BaseAdapter<TableItem>
{
public HomeScreenAdapter(Activity content, List<TableItem> items)
{
_content = content;
_items = items;
}
public override long GetItemId(int position)
{
return position;
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
var item = _items[position];
var view = convertView;
if (view == null)
view = _content.LayoutInflater.Inflate(Resource.Layout.CustomView, null);
view.FindViewById<TextView>(Resource.Id.Text1).Text = item.Heading;
view.FindViewById<TextView>(Resource.Id.Text2).Text = item.Subheading;
return view;
}
public override int Count
{
get { return _items.Count; }
}
public override TableItem this[int position]
{
get { return _items[position]; }
}
}
}
im getting this error
Error 1 The best overloaded method match for 'ListViewPullToRefresh.HomeScreenAdapter.HomeScreenAdapter(Android.App.Activity, System.Collections.Generic.List)' has some invalid arguments C:\Users******\Documents\Visual Studio 2013\Projects\ListViewPullToRefresh\ListViewPullToRefresh\Fragments\SampleListFragment.cs 43 32 ListViewPullToRefresh
Error 2 Argument 1: cannot convert from 'ListViewPullToRefresh.Fragments.SampleListFragment' to 'Android.App.Activity' C:\Users****\Documents\Visual Studio 2013\Projects\ListViewPullToRefresh\ListViewPullToRefresh\Fragments\SampleListFragment.cs 43 54 ListViewPullToRefresh
when i putting my custom adapter to the fragment, i get the error here ListView.Adapter = new HomeScreenAdapter(this, _itemHeading); and here public HomeScreenAdapter(Activity content, List<TableItem> items)
{
_content = content;
_items = items;
}
I get a problem when I am trying to show an AlertDialog in my adapter. It's showed many time when I want to delete an article (The first article for each category) or when I try to delete a category (Exactly when I remove a second category )
This is my code
ArticlesConfigurations.cs
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.Util;
using Android.Views;
using Android.Widget;
using SymaMobile.Core.Models;
using Vici.CoolStorage;
using SymaMobile.Droid.Adapters;
using Android.Database;
namespace SymaMobile.Droid
{
public class ArticlesConfiguration : Fragment
{
private ListView listViewCatgArticles;
private ListCategorieArticlesConfigAdapter adapterCatConfig;
private ListArticleConfigAdapter adapterArticles;
private List<CategoriesArticlesConfig> listCatgArticles;
private List<ArticlesConfig> listArticles;
private Button ajouterArticle;
private GridView gridArticles;
private ArticlesConfig art;
private TextView codeBarre;
private TextView libelle;
private CategoriesArticlesConfig categorieActuelle;
private Articles articleActuelle;
private CSList<CategoriesArticles, int> catglist;
private Spinner categorie;
private Spinner articles;
public override View OnCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View v = inflater.Inflate(Resource.Layout.fragment_configuration_articles, container, false);
listViewCatgArticles = v.FindViewById<ListView>(Resource.Id.lv_articles_fragment_configuration_articles);
ajouterArticle = v.FindViewById<Button>(Resource.Id.bt_ajouter_fragment_configuration_articles);
gridArticles = v.FindViewById<GridView>(Resource.Id.gv_articles_fragment_articles_configuration);
listCatgArticles = CategoriesArticlesConfig.List().ToList<CategoriesArticlesConfig>();
adapterCatConfig = new ListCategorieArticlesConfigAdapter(Activity, listCatgArticles);
listViewCatgArticles.Adapter = adapterCatConfig;
ajouterArticle.Click += ajouterArticle_Click;
listViewCatgArticles.ItemClick += listViewCatgArticles_ItemClick;
gridArticles.ItemClick += gridArticles_ItemClick;
return v;
}
void gridArticles_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
{
if (e.Position == gridArticles.Count-1)
{
Android.Util.Log.Error("Position grid", ""+e.Position);
Android.Util.Log.Error("grid Count", "" + gridArticles.Count);
AlertDialog.Builder builder = new AlertDialog.Builder(Activity);
builder.SetTitle(Resource.String.ajouter_categorie);
LayoutInflater inflater = Activity.LayoutInflater;
View v = inflater.Inflate(Resource.Layout.alertdialog_ajouter_article_configuration, null);
codeBarre = v.FindViewById<TextView>(Resource.Id.ed_code_barre_alert_dialog_ajouter_article_configuration);
libelle = v.FindViewById<TextView>(Resource.Id.tv_nom_article_alert_dialog_ajouter_article_configuration);
categorie = v.FindViewById<Spinner>(Resource.Id.sp_categories_alert_dialog_ajouter_article_configuration);
articles = v.FindViewById<Spinner>(Resource.Id.sp_articles_alert_dialog_ajouter_article_configuration);
var adapter = new ArrayAdapter<string>(Activity, Android.Resource.Layout.SimpleSpinnerDropDownItem);
catglist = CategoriesArticles.List();
for (int i = 0; i < catglist.Count; i++)
{
adapter.Add(catglist[i].Nom);
}
categorie.ItemSelected += categorie_ItemSelected;
categorie.Adapter = adapter;
codeBarre.TextChanged+=codeBarre_TextChanged;
builder.SetPositiveButton(Resource.String.ajouter, delegate
{
if (articleActuelle != null && categorieActuelle != null)
{
ArticlesConfig a = ArticlesConfig.New();
a.Article = articleActuelle;
a.CategorieArticles = categorieActuelle;
a.Save();
listArticles.Add(a);
adapterArticles.NotifyDataSetChanged();
}
});
builder.SetNegativeButton(Resource.String.annuler, (Android.Content.IDialogInterfaceOnClickListener)null);
builder.SetView(v);
builder.Show();
}
}
void categorie_ItemSelected(object sender, AdapterView.ItemSelectedEventArgs e)
{
List<Articles> a = catglist[e.Position].Articles.ToList<Articles>();
var adapter = new ArrayAdapter<string>(Activity, Android.Resource.Layout.SimpleSpinnerDropDownItem);
for (int i = 0; i < a.Count; i++)
{
adapter.Add(a[i].Libelle);
}
articles.Adapter = adapter;
}
private void codeBarre_TextChanged(object sender, Android.Text.TextChangedEventArgs e)
{
if (codeBarre.Text.Length > 2)
{
articleActuelle = Articles.ReadFirst("CodeBarre ='" + codeBarre.Text + "'");
if (articleActuelle != null)
{
libelle.Text = articleActuelle.Libelle;
}
else
{
libelle.Text = "";
}
}
}
void listViewCatgArticles_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
{
categorieActuelle = CategoriesArticlesConfig.Read((int)adapterCatConfig.GetItemId(e.Position));
listArticles = categorieActuelle.ArticlesConfig.ToList();
adapterArticles = new ListArticleConfigAdapter(Activity, listArticles);
gridArticles.Adapter = adapterArticles;
}
void ajouterArticle_Click(object sender, EventArgs e)
{
AlertDialog.Builder builder = new AlertDialog.Builder(Activity);
builder.SetTitle(Resource.String.ajouter_categorie);
LayoutInflater inflater = Activity.LayoutInflater;
View v = inflater.Inflate(Resource.Layout.alertdialog_ajouter_categorie_article_configuration, null);
TextView nom = v.FindViewById<TextView>(Resource.Id.ed_nom_ajouter_categorie_fragment_article_configuration);
builder.SetPositiveButton(Resource.String.ajouter, delegate
{
if (nom.Text.Length > 0)
{
CategoriesArticlesConfig c = CategoriesArticlesConfig.New();
c.Nom = nom.Text;
c.Save();
c = CategoriesArticlesConfig.ReadFirst("CategorieArticlesConfigID=" + c.CategorieArticlesConfigID);
listCatgArticles.Add(c);
adapterCatConfig.NotifyDataSetChanged();
}
});
builder.SetNegativeButton(Resource.String.annuler, (Android.Content.IDialogInterfaceOnClickListener)null);
builder.SetView(v);
builder.Show();
}
}
}
ListCategorieArticlesConfigAdapter.cs
namespace SymaMobile.Droid.Adapters
{
class ListCategorieArticlesConfigAdapter : BaseAdapter
{
private List<CategoriesArticlesConfig> list;
private int indice;
private Activity Activity;
public ListCategorieArticlesConfigAdapter(Android.App.Activity Activity, List<CategoriesArticlesConfig> list)
: base()
{
this.Activity = Activity;
this.list = list;
}
public override int Count
{
get { return list.Count; }
}
public override Java.Lang.Object GetItem(int position)
{
return null;
}
public override long GetItemId(int position)
{
return list[position].CategorieArticlesConfigID;
}
public override Android.Views.View GetView(int position, Android.Views.View convertView, Android.Views.ViewGroup parent)
{
var view = (convertView ??
Activity.LayoutInflater.Inflate(
Resource.Layout.list_item_categories_articles_configuration,
parent,
false)) as LinearLayout;
var nom = view.FindViewById(Resource.Id.tv_nom_list_item_categories_articles_configuration) as TextView;
var modify = view.FindViewById(Resource.Id.bt_modify_list_categories_articles_configuration) as Button;
var delete = view.FindViewById(Resource.Id.bt_delete_list_categories_articles_configuration) as Button;
modify.Click += modify_Click;
indice = position;
delete.Click +=delete_Click;
nom.Text = list[position].Nom;
return view;
}
void delete_Click(object sender, EventArgs e)
{
Android.App.AlertDialog.Builder builder = new Android.App.AlertDialog.Builder(Activity);
builder.SetMessage(Resource.String.msg_supprimer);
builder.SetPositiveButton(Resource.String.oui, delegate
{
CSDatabase.ExecuteNonQuery("DELETE FROM CategoriesArticlesConfig WHERE CategorieArticlesConfigID=" + list[indice].CategorieArticlesConfigID);
list.RemoveAt(indice);
NotifyDataSetChanged();
});
builder.SetNegativeButton(Resource.String.non, (Android.Content.IDialogInterfaceOnClickListener)null);
builder.Show();
}
void modify_Click(object sender, EventArgs e)
{
AlertDialog.Builder builder = new AlertDialog.Builder(Activity);
builder.SetTitle(Resource.String.modifier_categorie);
LayoutInflater inflater = Activity.LayoutInflater;
View v = inflater.Inflate(Resource.Layout.alertdialog_ajouter_categorie_article_configuration, null);
TextView _nom = v.FindViewById<TextView>(Resource.Id.ed_nom_ajouter_categorie_fragment_article_configuration);
_nom.Text = list[indice].Nom;
builder.SetNegativeButton(Resource.String.annuler, (Android.Content.IDialogInterfaceOnClickListener)null);
builder.SetPositiveButton(Resource.String.modifier, delegate {
CategoriesArticlesConfig c = CategoriesArticlesConfig.ReadFirst("CategorieArticlesConfigID=" + list[indice].CategorieArticlesConfigID);
if (c != null)
{
c.Nom = _nom.Text;
c.Save();
}
list[indice].Nom = _nom.Text;
NotifyDataSetChanged();
});
builder.SetView(v);
builder.Show();
}
}
}
ListArticleConfigAdapter
namespace SymaMobile.Droid.Adapters
{
class ListArticleConfigAdapter : BaseAdapter
{
Activity context;
private List<ArticlesConfig> liste;
private int indice;
public ListArticleConfigAdapter(Activity context, List<ArticlesConfig> liste)
: base()
{
this.context = context;
this.liste = liste;
}
public override int Count
{
get { return liste.Count+1; }
}
public override long GetItemId(int position)
{
return position;
}
public override Android.Views.View GetView(int position, View convertView, ViewGroup parent)
{
var view = (convertView ??
context.LayoutInflater.Inflate(
Resource.Layout.list_item_article_configuration,
parent,
false)) as LinearLayout;
var image = view.FindViewById(Resource.Id.iv_list_item_article_configuration) as ImageView;
var nom = view.FindViewById(Resource.Id.tv_nom_article_list_item_article_configuration) as TextView;
var supprimer = view.FindViewById(Resource.Id.bt_delete_list_item_article_configuration) as Button;
Android.Util.Log.Error("Position : ", ""+position+" List Count : "+liste.Count);
if (position < liste.Count)
{
nom.Text = liste[position].Article.Libelle;
image.SetImageBitmap(Tools.ImageTools.StringToBitMap(liste[position].Article.Image));
}
else
{
nom.Text = context.Resources.GetString(Resource.String.ajouter);
image.SetImageResource(Resource.Drawable.add128x128);
supprimer.Visibility = ViewStates.Invisible;
}
indice = position;
supprimer.Click += supprimer_Click;
return view;
}
void supprimer_Click(object sender, EventArgs e)
{
Android.App.AlertDialog.Builder builder = new Android.App.AlertDialog.Builder(context);
builder.SetMessage(Resource.String.msg_supprimer);
builder.SetPositiveButton(Resource.String.oui, delegate
{
CSDatabase.ExecuteNonQuery("DELETE FROM ArticlesConfig WHERE ArticlesConfigID=" + liste[indice].ArticlesConfigID);
liste.RemoveAt(indice);
NotifyDataSetChanged();
});
builder.SetNegativeButton(Resource.String.non, (Android.Content.IDialogInterfaceOnClickListener)null);
builder.Show();
}
public override Java.Lang.Object GetItem(int position)
{
return position;
}
}
}
thank you in advance
u have need to do this code on next activity onbackpress or
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
progressDialog.dismiss();
}
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
System.exit(0);
}
In ListCategorieArticlesConfigAdapter.GetView (), you're adding new event handlers for modify and delete, even when the view has been recycled, which means it will already have those handlers. Convert your convertView ?? check into an if/else check and do not reinitialise the handlers when convertView != null.
Modified your adapter to use view holder pattern. This should solve your issues.
class ListCategorieArticlesConfigAdapter : BaseAdapter
{
private List<CategoriesArticlesConfig> list;
private Activity Activity;
public ListCategorieArticlesConfigAdapter(Android.App.Activity Activity, List<CategoriesArticlesConfig> list)
: base()
{
this.Activity = Activity;
this.list = list;
}
public override int Count
{
get { return list.Count; }
}
public override Java.Lang.Object GetItem(int position)
{
return null;
}
public override long GetItemId(int position)
{
return list[position].CategorieArticlesConfigID;
}
public override Android.Views.View GetView(int position, Android.Views.View convertView,
Android.Views.ViewGroup parent)
{
ViewHolder vh;
var view = convertView;
if (view == null)
{
view = Activity.LayoutInflater.Inflate(Resource.Layout.list_item_categories_articles_configuration,
false);
vh = new ViewHolder(list);
vh.Initialize(view);
view.Tag = vh;
}
vh = view.Tag as ViewHolder;
vh.Bind(position);
return view;
}
private class ViewHolder : Java.Lang.Object
{
private TextView _nom;
private Button _modify;
private Button _delete;
private List<CategoriesArticlesConfig> _list;
public ViewHolder(List<CategoriesArticlesConfig> list)
{
_list = list;
}
public void Initialize(View view)
{
_nom = view.FindViewById<TextView>(Resource.Id.tv_nom_list_item_categories_articles_configuration);
_modify = view.FindViewById<Button>(Resource.Id.bt_modify_list_categories_articles_configuration);
_delete = view.FindViewById<Button>(Resource.Id.bt_delete_list_categories_articles_configuration);
}
public void Bind(int position)
{
_modify.Tag = position;
_modify.Click += modify_Click;
_delete.Click += delete_Click;
_nom.Text = _list[position].Nom;
}
void delete_Click(object sender, EventArgs e)
{
var indice = (int)(((View)sender).Tag);
Android.App.AlertDialog.Builder builder = new Android.App.AlertDialog.Builder(Activity);
builder.SetMessage(Resource.String.msg_supprimer);
builder.SetPositiveButton(Resource.String.oui, delegate
{
CSDatabase.ExecuteNonQuery("DELETE FROM CategoriesArticlesConfig WHERE CategorieArticlesConfigID=" + list[indice].CategorieArticlesConfigID);
list.RemoveAt(indice);
NotifyDataSetChanged();
});
builder.SetNegativeButton(Resource.String.non, (Android.Content.IDialogInterfaceOnClickListener)null);
builder.Show();
}
void modify_Click(object sender, EventArgs e)
{
var indice = (int)(((View)sender).Tag);
AlertDialog.Builder builder = new AlertDialog.Builder(Activity);
builder.SetTitle(Resource.String.modifier_categorie);
LayoutInflater inflater = Activity.LayoutInflater;
View v = inflater.Inflate(Resource.Layout.alertdialog_ajouter_categorie_article_configuration, null);
TextView _nom = v.FindViewById<TextView>(Resource.Id.ed_nom_ajouter_categorie_fragment_article_configuration);
_nom.Text = _list[indice].Nom;
builder.SetNegativeButton(Resource.String.annuler, (Android.Content.IDialogInterfaceOnClickListener)null);
builder.SetPositiveButton(Resource.String.modifier, delegate
{
CategoriesArticlesConfig c = CategoriesArticlesConfig.ReadFirst("CategorieArticlesConfigID=" + list[indice].CategorieArticlesConfigID);
if (c != null)
{
c.Nom = _nom.Text;
c.Save();
}
_list[indice].Nom = _nom.Text;
NotifyDataSetChanged();
});
builder.SetView(v);
builder.Show();
}
}
}
I find a solution. Is not the best but it work fine.
Firstly, I declare a boolean variable :
bool entree;
and in GetView method :
if ((position == 0 && !entree) || (position != 0 && entree))
{
...
entree = true;
}
that's all.