innomotion media
innomotion media

Reputation: 922

Reload recyclerview from within the adapter of the recycler view

So, I build a custom recyclerview because I needed a clickable header inside of it. After many hours, I got that to work. Party!

But the problem is, that in within the header of the RecView, there is a button that is supposed to re-arrange the following photos in within the RecView.

So I build two different layout - one where there are always 3 photos in a horizontal row. Those rows repeat until there are no more photos left - and another layout which shows the photos vertically and fills the parent in width. So basically single photos.

Above those two layouts are two buttons: "Single Photos" || "In A Row".

When clicked, I need to reinflate the layout of the recycler view. The problem is, that the header is a class of its own and the adapter is instantiated in the activity that wraps the RecView.

Since I deliver a static bool to check whether it's supposed to be single pics or rows I can simply click on my button, close the activity via the back button of my phone and restart the activity. Then the other layout gets inflated. But this is pretty unconvinient.

I'd totally be ok with the whole activity reloading, but yet again, this needs to be done from within the adapter.

To make this a little clearer: this is my activity:

private void initRecView()
        {

            RecyclerView recycler;
            Profile_RecyclerViewAdapter adapter;
            LinearLayoutManager layoutManager;

            startNumberOfTask = 0;

            List<KumulosHelper.Objects.Picture> pictures = 
                KumulosHelper.Pictures.getNewestXPhotosFromUserInRange
                (strUsername, "6", startNumberOfTask.ToString(), "1"); 



            foreach (var picture in pictures)
            {
                startNumberOfTask++;

                var metrics = Resources.DisplayMetrics;

                lstData.Add(new DataForProfile()
                {
                    imageId = startNumberOfTask,
                    img = (Bitmap.CreateScaledBitmap
                    (KumulosGeneral.DecodePhotoFromBase64(picture.photo),
                    metrics.WidthPixels, metrics.WidthPixels, true)),
                    description = picture.taskId.ToString()
                });


            }

            recycler = FindViewById<RecyclerView>(Resource.Id.recview);
            recycler.HasFixedSize = true;
            layoutManager = new LinearLayoutManager(this, LinearLayoutManager.Vertical, false);
            recycler.SetLayoutManager(layoutManager);
            adapter = new Profile_RecyclerViewAdapter(lstData, this);
            recycler.SetAdapter(adapter);

            recycler.AddOnScrollListener(new OnScrollListener(this, layoutManager));
        }

And this is the adapter with the button:

public class HeaderViewHolder : RecyclerView.ViewHolder {

    public HeaderViewHolder(View itemView, Context ctx) : base(itemView)
    {

        if (ctx.Resources.DisplayMetrics.HeightPixels >= 2560)
        {
            intHeightOfDisplay = 2560;
        }
        else
        {
            intHeightOfDisplay = ctx.Resources.DisplayMetrics.HeightPixels;
        }

        InitTextViews(itemView, ctx);

    }

    private void InitTextViews(View itemView, Context ctx)
    {


        txtNewest.Click += delegate
        {
            MoveSlider(ProfilePhotoSelection.Newest, ctx);
        };

        txtMostAp.Click += delegate
        {
            MoveSlider(ProfilePhotoSelection.MostAp, ctx);
        };

        txtMostUpVotes.Click += delegate
        {
            MoveSlider(ProfilePhotoSelection.Gallery, ctx);               
        };
    }
 }

So I am just realizing it is not the adapter but the viewholder - but nevertheless:

How do I reload my recview from the ViewHolder Class?

This is the adpater in all its glory:

class Profile_RecyclerViewAdapter : RecyclerView.Adapter, IItemClickLIstener
{
    private List<DataForProfile> lstData = new List<DataForProfile>();
    private Context ctx;
    private static int TYPE_HEADER = 0;
    private static int TYPE_ITEM = 2;
    public static bool boolPicsInSingles = false;


    // Konstruktor
    public Profile_RecyclerViewAdapter(List<DataForProfile> lstData, Context ctx)
    {
        this.lstData = lstData;
        this.ctx = ctx;
    }

    // OnBindViewHolder beinhaltet die Items die recycelt (also immer mit neuen Daten bespielt) werden.
    public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
    {


        //Check ob Header oder Data
        if (holder.GetType() == typeof(HeaderViewHolder))
        {
            HeaderViewHolder headerHolder = holder as HeaderViewHolder;

        }
        else if (holder.GetType() == typeof(RecyclerViewHolderSingles) || holder.GetType() == typeof(RecyclerViewHolderRows))
        {
            if (boolPicsInSingles)
            {
                RecyclerViewHolderSingles viewHolder = holder as RecyclerViewHolderSingles;
                viewHolder.txtTitle.Text = (lstData[position - 1].description); 
                viewHolder.imageView.SetImageBitmap((lstData[position - 1].img));
                viewHolder.SetItemClickListener(this);
            }
            else
            {
                RecyclerViewHolderRows viewHolder = holder as RecyclerViewHolderRows;


                viewHolder.rowpic1.SetImageBitmap((lstData[position-1].img));


                viewHolder.rowpic2.SetImageBitmap((lstData[position - 1].img));


                viewHolder.rowpic3.SetImageBitmap((lstData[position - 1].img));

                viewHolder.SetItemClickListener(this);

            }

        }

    }

    // Welches Layout Inflatet wird!
    public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
    {

        if (viewType == TYPE_ITEM)
        {
            // Normale Items
            if (!boolPicsInSingles)
            {
                //Pics in Rows
                LayoutInflater inflater = LayoutInflater.From(parent.Context);
                View itemView = inflater.Inflate(Resource.Layout.RecView_Profile_Rows, parent, false);
                return new RecyclerViewHolderRows(itemView, ctx);
            }
            else
            {
                //Pics in Singles
                LayoutInflater inflater = LayoutInflater.From(parent.Context);
                View itemView = inflater.Inflate(Resource.Layout.RecView_Profile_Singles, parent, false);
                return new RecyclerViewHolderSingles(itemView, ctx);
            }

        }
        else if (viewType == TYPE_HEADER)
        {
            //Inflating header view
            LayoutInflater inflater = LayoutInflater.From(parent.Context);
            View itemView = inflater.Inflate(Resource.Layout.RecView_Profile_Header, parent, false);
            return new HeaderViewHolder(itemView, ctx);
        }
        else return null;
    }

    // Get Number Of Items
    public override int ItemCount
    {
        get
        {
            return lstData.Count + 1; // +1 wegen des headers!
        }
    }

    // Custom Override um zu bestimmen, ob Header oder Item
    public override int GetItemViewType(int position)
    {
        if (position == 0)
        {
            return TYPE_HEADER;
        }
        else if (position == lstData.Count() + 1) //+1 wegen des Headers
        {
            return TYPE_ITEM;
        }
        return TYPE_ITEM;
    }

    // Click Events On Picture
    public void OnClick(View itemView, int position, bool isLongClick)
    {
        var activity2 = new Intent(ctx, typeof(Activity_Userpicture_Fullscreen));
        activity2.PutExtra("username", Activity_Profile.strUsername);
        activity2.PutExtra("taskid", lstData[position - 1].description);
        ctx.StartActivity(activity2);
    }
}

Upvotes: 0

Views: 7798

Answers (3)

Prince Dholakiya
Prince Dholakiya

Reputation: 3391

when you perform with recyclerview then rais duplicate view.or unaspected situation

then, you add this two @override method on your adapter

@Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public int getItemViewType(int position) {
        return position;
    }

Upvotes: 0

innomotion media
innomotion media

Reputation: 922

Funny enough: an very simple way is:

((Activity_Profile)ctx).Recreate();

Upvotes: 1

Mustafa Dualeh
Mustafa Dualeh

Reputation: 156

In the method:
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)

Change this

   return new HeaderViewHolder(itemView, ctx);

To this:

  return new HeaderViewHolder(itemView, ctx, this);

in HeadeViewHolder Contstructor change to this:

public HeaderViewHolder(View itemView, Context ctx, Profile_RecyclerViewAdapter adapter) : base(itemView)

Then in the click listener call this.

adapter.notifyDataSetChanged();

Upvotes: 2

Related Questions