0

I have a custom Listview, each row contains one textviewand one checkbox. I am saving the value (or the text) of the selected row's textview in a public list named usercoin. Each time the user opens the app, the list usercoin will contain the text of the his textview selected items, and I am doing that using SQLite. The problem is I want to re-check the items which the usaer have previously selected which are available in the usercoin list. I am not able to do so.

MyActivity.cs

    ListView mListView;
    MyAdapter adapter;
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);

        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.activity_main);
        mListView = FindViewById<ListView>(Resource.Id.listview);
        List<TableList> list = new List<TableList>();

        list.Add(new TableList("Germany",false));
        list.Add(new TableList("France", false));
        list.Add(new TableList("Finland", false));
        list.Add(new TableList("Germany", false));
        list.Add(new TableList("France", false));
        list.Add(new TableList("Germany", false));
        list.Add(new TableList("France", false));
        list.Add(new TableList("Finland", false));

        adapter = new MyAdapter(this, list);
        mListView.Adapter = adapter;
        mListView.ItemClick += MListView_ItemClick;
    }

    private void MListView_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
    {
        var t = list[e.Position];
        string selected = t.name;
        var ll = e.View as LinearLayout;
        var cb = ll.GetChildAt(2) as CheckBox;
        if (cb.Checked)
        {
            cb.Checked = false;
            adapter.changeState((int)cb.Tag, false);
        }
        else
        {
            cb.Checked = true;
            adapter.changeState((int)cb.Tag, true);
        }
    }



    class MyAdapter : BaseAdapter
    {
        Context mContext;
        List<TableList> mitems;
        public MyAdapter(Context context, List<TableList> list)
        {
            this.mContext = context;
            this.mitems = list;

        }
        public override int Count
        {
            get
            {
                return mitems.Count;
            }
        }

        public override Java.Lang.Object GetItem(int position)
        {
            return mitems[position];
        }

        public override long GetItemId(int position)
        {
            return position;
        }

        public override View GetView(int position, View convertView, ViewGroup parent)
        {
            DataViewHolder holder = null;
            if (convertView == null)
            {
                convertView = LayoutInflater.From(mContext).Inflate(Resource.Layout.CoinList, null, false);
                holder = new DataViewHolder();
                holder.tv = convertView.FindViewById<TextView>(Resource.Id.CoinName);
                holder.iv = convertView.FindViewById<ImageView>(Resource.Id.imageView1);
                holder.cb = convertView.FindViewById<CheckBox>(Resource.Id.checkBox1);
                convertView.Tag = holder;
            }
            else
            {
                holder = convertView.Tag as DataViewHolder;

            }
            holder.cb.Tag = position;

            holder.tv.Text = mitems[position].Name;
            holder.cb.Focusable = false;
            holder.cb.Checked = mitems[position].bl;
            holder.iv.SetImageResource(Resource.Drawable.dapao);
            holder.cb.CheckedChange += Cb_CheckedChange;
            return convertView;

        }

        private void Cb_CheckedChange(object sender, CompoundButton.CheckedChangeEventArgs e)
        {
            var cb = sender as CheckBox;
            if (e.IsChecked && !mitems[(int)cb.Tag].bl)
            {
                mitems[(int)cb.Tag].bl = true;
                this.NotifyDataSetChanged();
            }
            else if (!e.IsChecked && mitems[(int)cb.Tag].bl)
            {
                mitems[(int)cb.Tag].bl = false;
                this.NotifyDataSetChanged();
            }
        }

        internal void changeState(int tag, bool v)
        {
            mitems[tag].bl = v;
            this.NotifyDataSetChanged();
        }
    }

    public class DataViewHolder : Java.Lang.Object
    {
        public ImageView iv { get; set; }
        public TextView tv { get; set; }
        public CheckBox cb { get; set; }

    }
    public class TableList : Java.Lang.Object
    {
        private string v;



        public TableList(string name, bool b)
        {
            this.Name = name;
            this.bl = b;
        }
        public string Name { get; set; }
        public bool bl { get; set; }
    }
}
}

For example, when the user run the app and select France and Germany from the listview, next time he opens the app, the usercoin list will contain France and Germany. Now the question is how can I check the checkboxes corresponding to those values in the listview. I have tried to do so by including this code in MyAdapter : BaseAdapter class:

if (Class1.usercoin.Contains(item.CoinAbr))
            {
                Class1.adapter[(int)holder.cb.Tag].bl = true;
                this.NotifyDataSetChanged();
            }

But when this code get executed, the previously checked items are checked plus some other items which the user haven't checked previously are also checked. So how can I check the previously checked items in the Listview on the app start ? Please help me to find a solution.

Wassim01
  • 189
  • 3
  • 11
  • You would store the user's selections in a local store (Sqlite, Realm, a file, etc..) and retrieve them at the application startup. Example: https://learn.microsoft.com/en-us/xamarin/android/data-cloud/data-access/using-sqlite-orm – SushiHangover Jun 07 '18 at 16:53
  • I've removed your `visual-studio` tag for you because this isn't a question about the Visual Studio development environment (see the tags wiki) – ProgrammingLlama Jun 07 '18 at 17:04
  • @SushiHangover yea I am saving them using `Sqlite` but i didn't showed that in my code, I am asking about retrieving. I am not able to retrieve them on the start of the activity. – Wassim01 Jun 07 '18 at 17:34
  • What do you mean by `I am not able to retrieve them on the start of the activity`? I would like to get the data firstly in the [Application](https://forums.xamarin.com/discussion/2147/what-is-the-recipe-to-have-a-working-application-derived-class), because Application is the first class to run in Android. And you can define your `useritems` in your Application class as Global Variable. – Robbit Jun 11 '18 at 01:10
  • @JoeLv-MSFT Yes `useritems` is already a gobal list but I didn't put that in my question's code. Here's what i want to do: user checks his item for the first time, let them be germany and France then he quite the app. Then he re-open it, he needs to see his previously checked items (Germany and France) checked automatically in the Listview so he doesn't need to re-check them again. – Wassim01 Jun 11 '18 at 11:27
  • Hello, cause you have post your database code, so I did it by myself, you can refer to my demo. – Robbit Jun 12 '18 at 07:32

1 Answers1

0

I have stored the data(useritems) in both DataBase and memory.

If your app is killed by system or user, you can restore the data from DataBase.

If your app isn't killed by system or user, but user jump to other activity, when he back to this activity, you can use memory to restore the data.

About DataBase, I am use SQLite.Net. I am using DBHelper to operation the DataBase.

And I have add Application class in the app.

I have update the demo. Here is gif.

Robbit
  • 4,300
  • 1
  • 13
  • 29
  • Well, I have tried tour solution, when I first run the app, I am getting no items in my `listview`. Why is that ? Plus, I have already saved usercoin in a `database` so if you could edit your code by assuming it is saved in database and you are only getting it out of it. – Wassim01 Jun 12 '18 at 12:45
  • By `when I first run the app, I am getting no items in my listview`, ok, I will test it tomorrow, but I don't understand your question, now. so, I suggest that, tomorrow, I will debug my demo, and push it, you can compare it with yours. You can ask me any question about my code. Or show your code about the read database, so I can find why you can't get data from database. – Robbit Jun 12 '18 at 13:15
  • Okay, I ll provide how I am saving usercoin to `database` athough it is not easy to understand my method, it is complicated. Please tomorrow have a look at my up-dated code and edit your demo to suit my code. – Wassim01 Jun 12 '18 at 14:07
  • I have just updated my code, please review it. Everytime, the app starts, the `splash.cs` is launched and then the usercoin list is loaded with items – Wassim01 Jun 12 '18 at 14:24
  • Let's say i want to check in the Listview where "France" is available. What is the code to do so ? How to make this code to work with custom listview: `for (int i = 0; i <= useritems.Count; i++) { listView.SetItemChecked(i, true); }` ? – Wassim01 Jun 12 '18 at 16:50
  • If you can just tell me how to have access on the `Checkbox cb` from outside of the listview.ItemClick` event ? – Wassim01 Jun 12 '18 at 22:49
  • Hi, I have test my demo, can't reproduce your `when I first run the app, I am getting no items in my listview`. To be honest, I am disoriented from your comments. Ok, one question, one answer. Show your codes, say your question, I will find where is wrong, provide a solution. – Robbit Jun 13 '18 at 02:07
  • I am following your demo step by step, I have no clue why I have no items in my listview. Now if you can just tell me how can I have access on the `Checkbox cb` from outside of the `listview.ItemClick` event and I ll solve the problem. – Wassim01 Jun 13 '18 at 11:29
  • Yea right but I can't access it from outside of the listview.ItemClick event because `var ll = e.View as LinearLayout;` needs the `e` from the `listview event` – Wassim01 Jun 13 '18 at 12:04
  • Maybe I have understood what do you mean, you can find `useritems` and `daoList` from [here](https://github.com/xiaolvzi/ListViewCheckBox/blob/master/ListViewCheckBoxTest/MyApplication.cs), they are recording the `Checkbox`'s state. – Robbit Jun 13 '18 at 12:41
  • That doesn't help, I need to access the checkbox from outside of the listview event so that I can use shared preference and assign the state of the checkbox on the start of the app. But i can't do it now since `var ll` need the `e` from the event. – Wassim01 Jun 13 '18 at 12:47
  • Would you please give a look to this [thread](https://stackoverflow.com/questions/50859966/android-search-option-in-custom-listview-c-sharp) – Wassim01 Jun 14 '18 at 14:44
  • I have edited my whole question. Please check it again. – Wassim01 Jun 18 '18 at 09:25