question

Shaanky-9837 avatar image
0 Votes"
Shaanky-9837 asked JessieZhang-2116 edited

[Xamarin.Android] Cant save old data in recycler view / checklist

I have a recycler view with id, description, and a checkbox, I need to select a row from a list of data. but whenever I select one item from recycler view row, it needs to be refreshed and the selected item should not be gone.

My problem is everytime I check one checkbox and when the recyclerview is refreshed the selected item is resetted - doesnt save.

my current code.

private async void GetList()
{
long vnumber = Convert.ToInt64(voucher);
try
{

              HttpClient httpClient = new HttpClient();
              // var date = Convert.ToDateTime(datetime); 
              var url = APIHelper.GetUrl($"GetItems/{vnumber}");
              var json = await httpClient.GetStringAsync(url);
              item = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Item>>(json);
              if (item == null)
              {
                  Toast.MakeText(this, "No Data Found", ToastLength.Long).Show();
              }
              for (int i = 0; i <= (item.Count-1); i++)
              {
                  if (item[i].Barcode == flag.ToString())
                  {
                      item[i].ischecked = true;
                  }
              }                   
          }
          catch (System.Exception ex)
          {
              Toast.MakeText(this, "Item:" + ex.ToString(), ToastLength.Long).Show();
          }
          mAdapter = new ItemAdapter(item);
          mRecyclerView.SetAdapter(mAdapter);

I need to find a solution to save the checked item in recycler view ever when recycler view is refreshed.



dotnet-xamarinforms
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

JessieZhang-2116 avatar image
0 Votes"
JessieZhang-2116 answered JessieZhang-2116 edited

Hello,

Welcome to our Microsoft Q&A platform!

You can create an adapter which extends RecyclerView.Adapter and add event SetOnCheckedChangeListener for your checkbox.

You can refer to the following code included in my application which works properly.

  1. create an adapter (PhotoAlbumAdapter.cs)

     public class PhotoAlbumAdapter: RecyclerView.Adapter
         {
             public event EventHandler<int> ItemClick;
             public static List<Photo> mPhotoAlbum = new List<Photo>();
        
             public static RecyclerView.Adapter adapter;
        
             public PhotoAlbumAdapter(List<Photo> branchesList)
             {
                 adapter = this;
                 mPhotoAlbum = branchesList;
             }
        
             public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
             {
                 View itemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.PhotoCardView, parent, false);
        
                 PhotoViewHolder vh = new PhotoViewHolder(itemView, OnClick);
                   
                 return vh;
             }
        
             public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
             {
                 PhotoViewHolder vh = holder as PhotoViewHolder;
                    
                 Photo item=   mPhotoAlbum[position];
        
                 vh.Caption.Text = item.Caption;
        
                 vh.MyCheckBox.SetOnCheckedChangeListener(null);
                 vh.MyCheckBox.SetOnCheckedChangeListener(new MyListener(item));
                 vh.MyCheckBox.Checked = item.isChecked;
        
                 vh.DeleteButton.SetOnClickListener(new MyRemoveItem(item,position));
        
             }
        
        
             class MyRemoveItem : Java.Lang.Object, View.IOnClickListener
             {
                 Photo photo;
                 int position;
                 public MyRemoveItem(Photo item,int position) {
                     this.photo = item;
                     this.position = position;
                 }
        
                 public void OnClick(View v)
                 {
                     mPhotoAlbum.Remove(photo);
        
                     adapter.NotifyDataSetChanged();
                 }
             }
        
        
        
             class MyListener : Java.Lang.Object, CompoundButton.IOnCheckedChangeListener
             {
                 Photo photo;
        
                 public MyListener( Photo item)
                 {
                     this.photo = item;
                 }
        
                 public void OnCheckedChanged(CompoundButton buttonView, bool isChecked)
                 {
                     photo.isChecked = isChecked;
                 }
             }
        
             public override int ItemCount
             {
                 get { return mPhotoAlbum.Count; }
             }
        
             // Raise an event when the item-click takes place:
             void OnClick(int position)
             {
                 if (ItemClick != null)
                     ItemClick(this, position);
             }
         }
    

2.The code of PhotoViewHolder.cs

 public class PhotoViewHolder: RecyclerView.ViewHolder
 {
     public ImageView Image { get; private set; }
     public TextView Caption { get; private set; }
     public CheckBox MyCheckBox { get; set; }
     public bool IsChecked { get; set; }
    
    
     public Button DeleteButton { get; set; }
    
     public PhotoViewHolder(View itemView, Action<int> listener) : base(itemView)
     {
         Caption = itemView.FindViewById<TextView>(Resource.Id.textView);
         MyCheckBox = itemView.FindViewById<CheckBox>(Resource.Id.myCheckBox);
    
         DeleteButton = itemView.FindViewById<Button>(Resource.Id.deleteBtn);
    
         // Detect user clicks on the item view and report which item
         // was clicked (by layout position) to the listener:
         itemView.Click += (sender, e) => listener(base.LayoutPosition);
    
         MyCheckBox.Click += delegate
         {
             if (MyCheckBox.Checked)
             {
                 Console.WriteLine("I can get the adapter position here {0}", AdapterPosition);
                 IsChecked = true;
             }
             else
             {
                 Console.WriteLine("I can get the adapter position here {0}", AdapterPosition);
                 IsChecked = false;
             }
         };
     }
 }

3.The code of Photo.cs

    public class Photo
     {
         public int mPhotoID;
         public string mCaption;
    
         public bool isChecked {  get; set; }
    
         public int mBranchName;
    
         public int PhotoID
         {
             get { return mPhotoID; }
         }
    
         public string Caption
         {
             get { return mCaption; }
         }
    
         public int BranchName
         {
             get { return mBranchName; }
         }
     }

4.MainActivity.cs


  public class MainActivity : AppCompatActivity
     {
        public static  Photo[] mBuiltInPhotos;
    
         List<Photo> loadBranch = new List<Photo>();
    
         RecyclerView mRecyclerView;
         RecyclerView.LayoutManager mLayoutManager;
         PhotoAlbumAdapter mAdapter;
    
       public static  List<string> SelectedBranchCode = new List<string>();
    
    
         protected override void OnCreate(Bundle savedInstanceState)
         {
             base.OnCreate(savedInstanceState);
             // Set our view from the "main" layout resource
             SetContentView(Resource.Layout.activity_main);
    
             mRecyclerView = FindViewById<RecyclerView>(Resource.Id.recyclerView);
    
             mLayoutManager = new LinearLayoutManager(this);
             mRecyclerView.SetLayoutManager(mLayoutManager);
    
             initData();
    
             mAdapter = new PhotoAlbumAdapter(loadBranch);
             mAdapter.ItemClick += OnItemClick;
             mRecyclerView.SetAdapter(mAdapter);
    
         }
         }
    
    
         private void initData() {
    
              mBuiltInPhotos =  new Photo[] {
             new Photo { mPhotoID = Resource.Drawable.buckingham_guards,
                         mCaption = "Buckingham Palace",isChecked=false },
             new Photo { mPhotoID = Resource.Drawable.la_tour_eiffel,
                         mCaption = "The Eiffel Tower" ,isChecked=false},
             new Photo { mPhotoID = Resource.Drawable.louvre_1,
                         mCaption = "The Louvre",isChecked=false },
             new Photo { mPhotoID = Resource.Drawable.before_mobile_phones,
                         mCaption = "Before mobile phones",isChecked=false },
             new Photo { mPhotoID = Resource.Drawable.big_ben_1,
                         mCaption = "Big Ben skyline" ,isChecked=false},
             new Photo { mPhotoID = Resource.Drawable.big_ben_2,
                         mCaption = "Big Ben from below" ,isChecked=false},
             new Photo { mPhotoID = Resource.Drawable.london_eye,
                         mCaption = "The London Eye",isChecked=false },
             new Photo { mPhotoID = Resource.Drawable.eurostar,
                         mCaption = "Eurostar Train",isChecked=false }
             };
    
             loadBranch = new List<Photo>(mBuiltInPhotos);
    
    
         }
    
         void OnItemClick(object sender, int position)
         {
             int photoNum = position + 1;
             Toast.MakeText(this, "This is photo number " + photoNum, ToastLength.Short).Show();
         }
     }

5.The code of PhotoCardView.axml is:

 <?xml version="1.0" encoding="utf-8"?>
 <FrameLayout xmlns:card_view="http://schemas.android.com/apk/res-auto"
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content">
     <android.support.v7.widget.CardView
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         card_view:cardElevation="4dp"
         card_view:cardUseCompatPadding="true"
         card_view:cardCornerRadius="5dp">
    
         <LinearLayout
                
             android:orientation="horizontal"
             android:layout_width="match_parent"
             android:layout_height="wrap_content">
    
             <LinearLayout
              android:layout_weight="1"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:orientation="vertical"
             android:padding="8dp">
         
             <TextView
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:textAppearance="?android:attr/textAppearanceMedium"
                 android:textColor="#333333"
                 android:text="Caption"
                 android:id="@+id/textView"
  android:imeOptions="actionNext"
  android:singleLine="true"
                 android:layout_gravity="center_horizontal"
                 android:layout_marginLeft="4dp" />
  <CheckBox
  android:text="CheckBox"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:id="@+id/myCheckBox" />
         </LinearLayout>
    
             <Button
                 android:text="delete"
                 android:id="@+id/deleteBtn"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"/>
    
         </LinearLayout>
    
            
     </android.support.v7.widget.CardView>
 </FrameLayout>

The result is:

74708-image.png


Note:When you check the checkbox of the Item, event MyListener in PhotoAlbumAdapter will been triggered and field isChecked in item model (`Photo`) will been changed.

Best Regards,

Jessie Zhang


If the response is helpful, please click "Accept Answer" and upvote it.


Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.



image.png (73.7 KiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.