2

I am working with a recyclerView and i succeeded in inflating two views but each view content comes from different json data types. i tried passing the two datatypes in the adapter but they are not properly binded

  • source code

    public class SimpleStringRecyclerViewAdapter : RecyclerView.Adapter {

    private Article[] mValues;
    private List<YouTubeItem> mValues2;
    
    Context context;
    
    public SimpleStringRecyclerViewAdapter(Context context, Article[] items, List<YouTubeItem> item )
    {
        this.context = context;
        mValues = items;
        mValues2 = item;
    }
    
    public override int ItemCount
    {
    
        get
        {
           return mValues.Count() + mValues2.Count();
        }
    }
    
    public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
    {
        if (holder is SimpleViewHolder)
        try
        {
            Article item = mValues[position];
            var simpleHolder = holder as SimpleViewHolder;
    
            simpleHolder.mTxtView.Text = Android.Text.Html.FromHtml(item.Title).ToString();
            simpleHolder.mTxtView2.Text = item.Description;
    
    
            using (var imageView = simpleHolder.mImageView)
            {
                string url = Android.Text.Html.FromHtml(item.UrlToImage).ToString();
    
                //Download and display image
                UrlImageViewHelper.SetUrlDrawable(imageView,
                    url, Resource.Drawable.cheese_1
                    );
    
    
    
            }
            //    simpleHolder.mprogressbar.Visibility = ViewStates.Gone;
        }
        catch (Exception e)
        {
            //Toast.MakeText(this.context, e.ToString(), ToastLength.Long).Show();
        }
        else
        {
            try
            {
                YouTubeItem item = mValues2[position];
                var simpleHolder = holder as SimpleViewHolder2;
    
                simpleHolder.mTxtView.Text = Android.Text.Html.FromHtml(item.Title).ToString();
                // simpleHolder.mTxtView2.Text = item.DescriptionShort;
    
    
                using (var imageView = simpleHolder.mImageView)
                {
                    string url = Android.Text.Html.FromHtml(item.MaxResThumbnailUrl).ToString();
    
                    //Download and display image
                    UrlImageViewHelper.SetUrlDrawable(imageView,
                        url, Resource.Drawable.cheese_1
                        );
    
    
    
                }
            }
            catch (Exception e)
            {
                //Toast.MakeText(this.context, e.ToString(), ToastLength.Long).Show();
            }
    
        }
    }
    
    public override int GetItemViewType(int position)
    {
        if ((position % 2) == 0)
        {
            //Even number
            return Resource.Layout.List_Item;
        }
    
        else
        {
            //Odd number
            return Resource.Layout.VideoList;
        }
    }
    
    
    
    public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
    {
        if (viewType == Resource.Layout.List_Item)
        {
            View view = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.List_Item, parent, false);
            view.SetBackgroundColor(Color.White);
    
    
            SimpleViewHolder holder = new SimpleViewHolder(view);
            // holder.mprogressbar = view.FindViewById<ProgressBar>(Resource.Id.progressBar);
            // holder.mprogressbar.Visibility = ViewStates.Visible;
    
    
            //Showing loading progressbar
    
            return holder;
        }
        else
        {
            View view = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.VideoList, parent, false);
            view.SetBackgroundColor(Color.White);
            SimpleViewHolder2 holder = new SimpleViewHolder2(view);
    
            return holder;
        }
    
    }
    

    }

    public class SimpleViewHolder : RecyclerView.ViewHolder { public string mBoundString; public readonly View mView; public readonly ImageView mImageView; public readonly TextView mTxtView; public readonly TextView mTxtView2; // public ProgressBar mprogressbar;

    public SimpleViewHolder(View view) : base(view)
    {
        mView = view;
        mImageView = view.FindViewById<ImageView>(Resource.Id.avatar);
        mTxtView = view.FindViewById<TextView>(Resource.Id.Text1);
        mTxtView2 = view.FindViewById<TextView>(Resource.Id.Text2);
        //   mprogressbar = view.FindViewById<ProgressBar>(Resource.Id.progressBar);
    
    
    }
    
    
    
    
    public override string ToString()
    {
        return base.ToString() + " '" + mTxtView.Text;
    
    }
    

    } public class SimpleViewHolder2 : RecyclerView.ViewHolder { public string mBoundString; public readonly View mView; public readonly ImageView mImageView; public readonly TextView mTxtView; public readonly TextView mTxtView2;

    public SimpleViewHolder2(View view) : base(view)
    {
        mView = view;
        mImageView = view.FindViewById<ImageView>(Resource.Id.videoavatar);
        mTxtView = view.FindViewById<TextView>(Resource.Id.videoText1);
        //   mprogressbar = view.FindViewById<ProgressBar>(Resource.Id.progressBar);
    
    
    }
    
1
  • 1
    You will have to merge your two lists into one. Commented Apr 16, 2018 at 9:33

3 Answers 3

8

You should merge data to one data source only. You can try this way:

  1. Create data source class

    public class Data {
       int type; // 1 is article and 2 is youtubeitem
       public Article article;
       public YouTubeItem youTubeItem;
    }
    
  2. Now merge two data source to only one

    public List<Data> merge(Articel[] articles, List<YouTubeItem> items) {
        List<Data> datas = new ArrayList<>();
        for(Article article : articles) {
           Data data = new Data();
           data.article = article;
           data.youTubeItem = null;
           data.type = 1;
           datas.add(data);
        }
    
        for(YouTubeItem item : items) {
           Data data = new Data();
           data.article = null;
           data.youTubeItem = item;
           data.type = 2;
           datas.add(data);
        }
    
       return datas;
    }
    
  3. Change constructor of adapter

    private List<Data> datas;
    
    public SimpleStringRecyclerViewAdapter(Context context, List<Data> datas )
    {
      this.datas = datas;
    }
    
  4. Change get Item count

    public override int ItemCount
    {
    
        get
        {
            return datas.Count();
        }
    }
    
  5. Change getViewType

    public override int GetItemViewType(int position)
    {
       if (datas.get(position).type == 1)
       {
            return Resource.Layout.List_Item;
       }
    
       else
       {
           return Resource.Layout.VideoList;
       }
    }
    

EDITED: For merge random method

 public List<Data> mergeRandom(Articel[] articles, List<YouTubeItem> items) {
     List<Data> datas = new ArrayList<>();

     List<Integer> random = new ArrayList<>();
     int maxLength = articles.length + items.size(); 
     for(int i = 0; i< maxLength; i++) { 
        random.add(i);
     }

     while (random.size() > 0) {
        // get random item
        int index = new Random().nextInt(random.size());
        int position = random.get(index);

        if(position <= article.length - 1) {
            Data data = new Data();
            data.article = articles[position];
            data.youTubeItem = null;
            data.type = 1;
            datas.add(data);
        } else {
            Data data = new Data();
            data.article = null;
            data.youTubeItem = items.get(position - article.length);
            data.type = 2;
            datas.add(data);
        }

        random.remove(index);
    }

    return datas;
 }

For merge odd&even method

List<Data> mergeOddEven(Articel[] articles, List<YouTubeItem> items) {
    List<Data> datas = new ArrayList<>();

    int articleIndex = 0;
    int youtubeIndex = 0;
    int length = articles.length + items.size();

    for(int i = 0; i< length; i++) {
        if(articleIndex >= articles.length || youtubeIndex >= items.size()) {
            if(articleIndex < articles.length) {
                for(int j = articleIndex; j < articles.length ; j++) {
                   Data data = new Data();
                   data.article = articles[j];
                   data.youTubeItem = null;
                   data.type = 1;
                   datas.add(data);

                }
            } else {
                for(int j = youtubeIndex; j < items.size() ; j++) {
                   Data data = new Data();
                   data.article = null;
                   data.youTubeItem = items.get(j);
                   data.type = 2;
                   datas.add(data);

                }
            }

            break;
        }


        if(i % 2 == 0) {
            Data data = new Data();
            data.article = articles[articleIndex];
            data.youTubeItem = null;
            data.type = 1;
            datas.add(data);

            articleIndex++;
        } else {
            Data data = new Data();
            data.article = null;
            data.youTubeItem = tems.get(youtubeIndex);
            data.type = 2;
            datas.add(data);

            youtubeIndex++;
        }
    }

    return datas;
}

Hope it help

Sign up to request clarification or add additional context in comments.

8 Comments

Thanks, it helped, but it displayed all the articles first, then the youtube items, i'll really love to have them shuffled
It depend on logic in merge(Articel[] articles, List<YouTubeItem> items) method. Tell me which kind of shuffled do you want ? Even position -> article, odd position -> youtubeitem ? or you want random item for random position ?
Thanks for replying, I'll love random item for random position
Check my edited answer, I've add mergeRandom() method
Thanks a lot,but I get out of memory exception, I think using odd and even position will be more realistic, I'll be glad if you can help with that
|
0

use this function to merge the data and use this in your adapter :

public List<Data> merge(Articel[] articles, List<YouTubeItem> items) {


        int counter = 0,counter1=0,size=0;


        size = articles.length + items.size();

        List<Data> datas = new ArrayList<>();
        for (int i = 0; i < size;i++) {

            if (i % 2 == 0) {

                if(counter1<articles.length){

                Article article = articles[counter1];
                Data data = new Data();
                data.article = article;
                data.youTubeItem = null;
                data.type = 1;
                datas.add(data);
                counter1++;

                }else if(counter<items.size()){

                 YouTubeItem item = items.get(counter);
                Data data = new Data();
                data.article = null;
                data.youTubeItem = item;
                data.type = 2;
                datas.add(data);
                counter++;
                }

            } else {

                if(counter<items.size()){

                   YouTubeItem item = items.get(counter);
                Data data = new Data();
                data.article = null;
                data.youTubeItem = item;
                data.type = 2;
                datas.add(data);
                counter++;
                }else if(counter1<articles.length){

                Article article = articles[counter1];
                Data data = new Data();
                data.article = article;
                data.youTubeItem = null;
                data.type = 1;
                datas.add(data);
                counter1++;
                }

            }

        }


        return datas;
    }

5 Comments

thanks but i get ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
No, I get it in the merge function
Thanks but subtracting the lists in my own case returns only five items since articles.length = 20 and items.size() = 15
your answer is okey for if i load the data at a time but if i need to implement lazyloading feature like call the api after user scroll 10 item from recycle view . so anyone can explan that situation "? can you check my question : stackoverflow.com/questions/53730109/…
0

Make one interface to implement your data pojo class like below..

public interface Parent{
}

Then pojo class like

public class User implements Parent{
    private String name,addres;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddres() {
        return addres;
    }

    public void setAddres(String addres) {
        this.addres = addres;
    }
}

Then add all the data into parent list and bind into adapter .. Adapter bind data according to pojo class like below..

public class SearchListAdapter extends ArrayAdapter<Parent> {
    Context context;
    Parent parent[] = null;
        public SearchListAdapter(Context context, int layoutResourceId, Parent[] parent) {
        super(context, layoutResourceId, parent);
        this.context = context;
        this.parent = parent;
    }
    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        final LayoutInflater inflater = ((Activity) context).getLayoutInflater();
        final View outerContainer = inflater.inflate(R.layout.food_list_item, parent, false);
        if (this.parent != null) {
            Parent temp = this.parent[position];
            if (temp instanceof FoodItem) {
                final FoodItem item = (FoodItem) temp;
            }
        }   
    }
}

1 Comment

your answer is okey for if i load the data at a time but if i need to implement lazyloading feature like call the api after user scroll 10 item from recycle view . so anyone can explan that situation "? can you check my question : stackoverflow.com/questions/53730109/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.