7

i have a fragment with following design need help to implement this.

MainFragment

tried to put it as Header in adapter but no luck.

My Adapter

public class FeedListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements GetJSONListener {
private final int VIEW_TYPE_ITEM = 0;
private final int VIEW_TYPE_LOADING = 1;
private final int VIEW_TYPE_HEADER = 2;
private List<FeedItem> feedItems;
private Context mContext;
private CallWSTask callWSTask;
private View VaultsHeader;
private ArrayList<String> userVaults;
private MyVaultsAdapter vaultsAdapter;
private List<VaultsPojo> vaultsPojo;


// Provide a suitable constructor (depends on the kind of dataset)
public FeedListAdapter(Context context, List<FeedItem> feedItems, View header) {
    this.feedItems = feedItems;
    mContext = context;
    if(!header.equals(null)){
        this.VaultsHeader = header;
    }



}
public boolean isHeader(int position) {
    return position == 0;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.feed_note, null);


    if (viewType == VIEW_TYPE_ITEM) {
        View view = LayoutInflater.from(mContext).inflate(R.layout.feed_note, parent, false);
        return new FeedListViewHolder(view);

    } else if (viewType == VIEW_TYPE_LOADING) {
        View view = LayoutInflater.from(mContext).inflate(R.layout.layout_loading_item, parent, false);
        return new LoadingViewHolder(view);
    }else if(viewType == VIEW_TYPE_HEADER){
        View view = LayoutInflater.from(mContext).inflate(R.layout.vaults_header_view, parent, false);
        return new HeaderViewHolder(view);
    }
    return null;
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    if (holder instanceof FeedListViewHolder) {
        final FeedItem feedItem = feedItems.get(position);
        FeedListViewHolder feedListViewHolder = (FeedListViewHolder) holder;

        feedListViewHolder.display_name_tv.setText(feedItem.getUserDisp().getFirstName() + " " + feedItem.getUserDisp().getLastName());
        feedListViewHolder.display_name_tv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(mContext, UserProfileActivity.class);
                i.putExtra("userid", feedItem.getUserId());
                mContext.startActivity(i);
            }
        });
        CharSequence timeAgo = DateUtils.getRelativeTimeSpanString(
                Long.parseLong(feedItem.getCreateDate()),
                System.currentTimeMillis(), DateUtils.SECOND_IN_MILLIS);
        feedListViewHolder.timestamp_tv.setText(timeAgo);
        feedListViewHolder.abbreviationtxt.setText("Ma");
        Picasso.with(mContext).load(mContext.getString(R.string.ENVIRONMENT1) + feedItem.getUserDisp().getProfilepicName())
                .into(feedListViewHolder.user_iv);
        Picasso.with(mContext).load(SharedPreferenceUtils.getProfilePic(mContext)).into(((FeedListViewHolder) holder).comment_user_iv);

        feedListViewHolder.like_count.setText(feedItem.getFavoriteCount() + "");
        feedListViewHolder.comment_count.setText(feedItem.getCommentCount() + "");
        feedListViewHolder.share_count.setText(feedItem.getShareCount() + "");

        if (feedItem.isLike()) {
            feedListViewHolder.like_empty_iv.setImageDrawable(mContext.getDrawable(R.drawable.ic_action_helpful_selected));
        } else {
            feedListViewHolder.like_empty_iv.setImageDrawable(mContext.getDrawable(R.drawable.ic_action_helpful));
        }


        feedListViewHolder.like_empty_iv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(mContext, "Liked!", Toast.LENGTH_LONG).show();

            }
        });
        feedListViewHolder.comment_iv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(mContext, "coment!", Toast.LENGTH_LONG).show();

            }
        });
        feedListViewHolder.share_iv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(mContext, "shared!", Toast.LENGTH_LONG).show();

            }
        });
        if (feedItem.getFeedType().equals("Note")) {
            feedListViewHolder.FeedNote.setVisibility(View.VISIBLE);
            feedListViewHolder.FeedAskQuestion.setVisibility(View.GONE);
            feedListViewHolder.FedMcq.setVisibility(View.GONE);
            feedListViewHolder.FeedEmbedYouTube.setVisibility(View.GONE);
            feedListViewHolder.FeedEmbedWeb.setVisibility(View.GONE);
            feedListViewHolder.embed_disp_tv.setText(Html.fromHtml(feedItem.getNotedisp().getNoteContent()));

            if (feedItem.getNotedisp().getAttachment().toString() != "[]") {

                if (feedItem.getNoteDisp().getAttachment().size() == 1) {
                    if (feedItem.getNoteDisp().getAttachment().get(0).isImage()) {
                        feedListViewHolder.note_post_iv01.setVisibility(View.VISIBLE);
                        feedListViewHolder.gridView.setVisibility(View.GONE);
                        Picasso.with(mContext)
                                .load(mContext.getString(R.string.ENVIRONMENT1) + "/MediaImages/Medium/" + feedItem.getNoteDisp().getAttachment().get(0).getFileName())
                                .into(feedListViewHolder.note_post_iv01);

                        Log.v("one image",mContext.getString(R.string.ENVIRONMENT1) + "/MediaImages/Medium/" + feedItem.getNoteDisp().getAttachment().get(0).getFileName());

                    } else if (feedItem.getNoteDisp().getAttachment().get(0).isVideo()) {

                    }

                }else if(feedItem.getNoteDisp().getAttachment().size() > 1){
                    feedListViewHolder.gridView.setVisibility(View.VISIBLE);
                    feedListViewHolder.note_post_iv01.setVisibility(View.GONE);
                    FeedNoteAttachmentAdapter attachmentAdapter = new FeedNoteAttachmentAdapter(mContext, feedItem.getNoteDisp().getAttachment());
                    feedListViewHolder.gridView.setAdapter(attachmentAdapter);
                    feedListViewHolder.gridView.autoresize();

                }


            }else{
                feedListViewHolder.gridView.setVisibility(View.GONE);
                feedListViewHolder.note_post_iv01.setVisibility(View.GONE);
            }
        } else if (feedItem.getFeedType().equals("Embed")) {


            if (feedItem.getEmbed().getEmbedType().equals("youtube")) {
                feedListViewHolder.FeedNote.setVisibility(View.GONE);
                feedListViewHolder.FeedAskQuestion.setVisibility(View.GONE);
                feedListViewHolder.FedMcq.setVisibility(View.GONE);
                feedListViewHolder.FeedEmbedWeb.setVisibility(View.GONE);
                feedListViewHolder.FeedEmbedYouTube.setVisibility(View.VISIBLE);
                feedListViewHolder.btnplay.setVisibility(View.VISIBLE);
                ((FeedListViewHolder) holder).youtube_title.setText(Html.fromHtml(feedItem.getEmbed().getEmbedTitle()));
                ((FeedListViewHolder) holder).youtube_disp.setText(Html.fromHtml(feedItem.getEmbed().getEmbedDescription()));
                Picasso.with(mContext).load(feedItem.getEmbed().getEmbedImageUrl())
                        .into(feedListViewHolder.youtube_post_iv);

            } else {
                feedListViewHolder.FeedNote.setVisibility(View.GONE);
                feedListViewHolder.FeedAskQuestion.setVisibility(View.GONE);
                feedListViewHolder.FedMcq.setVisibility(View.GONE);
                feedListViewHolder.FeedEmbedYouTube.setVisibility(View.GONE);
                feedListViewHolder.FeedEmbedWeb.setVisibility(View.VISIBLE);
                ((FeedListViewHolder) holder).embed_title.setText(Html.fromHtml(feedItem.getEmbed().getEmbedTitle()));
                ((FeedListViewHolder) holder).embed_disp.setText(Html.fromHtml(feedItem.getEmbed().getEmbedDescription()));

                if ((feedItem.getEmbed().getEmbedImageUrl() != null) && (feedItem.getEmbed().getEmbedImageUrl().length() > 0) && (!feedItem.getEmbed().getEmbedImageUrl().equals("null"))) {
                    feedListViewHolder.embed_image.setVisibility(View.VISIBLE);
                    Picasso.with(mContext).load(feedItem.getEmbed().getEmbedImageUrl())
                            .into(feedListViewHolder.embed_image);
                } else {
                    feedListViewHolder.embed_image.setVisibility(View.GONE);
                }

            } //youTubeView.setVisibility(View.GONE);


        } else if (feedItem.getFeedType().equals("AskQuestion")) {
            feedListViewHolder.FeedNote.setVisibility(View.GONE);
            feedListViewHolder.FeedAskQuestion.setVisibility(View.VISIBLE);
            feedListViewHolder.FedMcq.setVisibility(View.GONE);
            feedListViewHolder.FeedEmbedYouTube.setVisibility(View.GONE);
            feedListViewHolder.FeedEmbedWeb.setVisibility(View.GONE);
            feedListViewHolder.question_txt.setText(Html.fromHtml(feedItem.getAskQuestions().getQuestionText()));
        } else if (feedItem.getFeedType().equals("MCQ")) {
            feedListViewHolder.FeedNote.setVisibility(View.GONE);
            feedListViewHolder.FeedAskQuestion.setVisibility(View.GONE);
            feedListViewHolder.FedMcq.setVisibility(View.VISIBLE);
            feedListViewHolder.FeedEmbedYouTube.setVisibility(View.GONE);
            feedListViewHolder.FeedEmbedWeb.setVisibility(View.GONE);
            feedListViewHolder.mcq_question.setText(Html.fromHtml(feedItem.getMCQ().getQuestion()));

            Typeface ubantulight = Typeface.createFromAsset(mContext.getAssets(), "fonts/Ubuntu-L.ttf");
            feedListViewHolder.radioButton01.setTypeface(ubantulight);
            feedListViewHolder.radioButton02.setTypeface(ubantulight);
            feedListViewHolder.radioButton03.setTypeface(ubantulight);
            feedListViewHolder.radioButton04.setTypeface(ubantulight);


            if (feedItem.getMCQ().getAnswer().size() == 4) {
                feedListViewHolder.radioButton01.setText(feedItems.get(position).getMCQ().getAnswer().get(0).getAnswerText());
                feedListViewHolder.radioButton02.setText(feedItems.get(position).getMCQ().getAnswer().get(1).getAnswerText());
                feedListViewHolder.radioButton03.setText(feedItems.get(position).getMCQ().getAnswer().get(2).getAnswerText());
                feedListViewHolder.radioButton04.setText(feedItems.get(position).getMCQ().getAnswer().get(3).getAnswerText());
                // viewHolder = (ViewHolder) convertView.getTag();
            } else if (feedItem.getMCQ().getAnswer().size() == 3) {
                feedListViewHolder.radioButton04.setVisibility(View.GONE);
                feedListViewHolder.radioButton03.setText(feedItems.get(position).getMCQ().getAnswer().get(2).getAnswerText());
                feedListViewHolder.radioButton01.setText(feedItems.get(position).getMCQ().getAnswer().get(0).getAnswerText());
                feedListViewHolder.radioButton02.setText(feedItems.get(position).getMCQ().getAnswer().get(1).getAnswerText());
                // viewHolder = (ViewHolder) convertView.getTag();
            } else if (feedItem.getMCQ().getAnswer().size() == 2) {
                feedListViewHolder.radioButton01.setText(feedItems.get(position).getMCQ().getAnswer().get(0).getAnswerText());
                feedListViewHolder.radioButton02.setText(feedItems.get(position).getMCQ().getAnswer().get(1).getAnswerText());
                feedListViewHolder.radioButton03.setVisibility(View.GONE);
                feedListViewHolder.radioButton04.setVisibility(View.GONE);
                // viewHolder = (ViewHolder) convertView.getTag();
            } else {
                feedListViewHolder.radioButton01.setVisibility(View.GONE);
                feedListViewHolder.radioButton02.setVisibility(View.GONE);
                feedListViewHolder.radioButton03.setVisibility(View.GONE);
                feedListViewHolder.radioButton04.setVisibility(View.GONE);
                //viewHolder = (ViewHolder) convertView.getTag();
            }

        }

        //this line is important
        feedListViewHolder.itemView.setTag(feedItems.get(position));
        //setAnimation(feedListViewHolder.mainlinear_feed,position);
    } else if (holder instanceof LoadingViewHolder) {
        LoadingViewHolder loadingViewHolder = (LoadingViewHolder) holder;

        if (!Utilities.Isconnetcted(mContext) && position >= 30) {
            loadingViewHolder.errormsg.setVisibility(View.VISIBLE);
        } else {
            loadingViewHolder.progressBar.setVisibility(View.VISIBLE);
            loadingViewHolder.progressBar.setIndeterminate(true);
        }
    }else if (holder instanceof HeaderViewHolder){
        HeaderViewHolder headerViewHolder = (HeaderViewHolder) holder;


        userVaults = SharedPreferenceUtils.getUserVaults(mContext);

        //String vaultsjsonstring = new Gson().toJson(userVaults);
        vaultsPojo = ResponseParser.parsevaultsJson(userVaults.toString());

        vaultsAdapter = new MyVaultsAdapter(mContext,vaultsPojo);
        headerViewHolder.vaultsRecyclerView.setLayoutManager(new GridLayoutManager(mContext,2));
        headerViewHolder.vaultsRecyclerView.setAdapter(vaultsAdapter);

    }


}

@Override
public int getItemCount() {
    return feedItems == null ? 0 : feedItems.size();
}

@Override
public void onRemoteCallComplete(String jsonFromWSCall) {

}

public void addFeedItem(List<FeedItem> feedItems) {
    //this.feedItems.add(position,feedItems);

    this.feedItems.addAll(feedItems);
    //notifyDataSetChanged();

}

public String getLastFeedId() {
    if (!this.feedItems.isEmpty()) {
        return this.feedItems.get(this.feedItems.size() - 2).getFeedId();
    } else {
        return null;
    }
}


@Override
public int getItemViewType(int position) {
    if(isHeader(position)){
        return VIEW_TYPE_HEADER;
    }else {
        return feedItems.get(position) == null ? VIEW_TYPE_LOADING : VIEW_TYPE_ITEM;
    }

}


static class LoadingViewHolder extends RecyclerView.ViewHolder {
    public ProgressBar progressBar;
    public TextView errormsg;

    public LoadingViewHolder(View itemView) {
        super(itemView);
        progressBar = (ProgressBar) itemView.findViewById(R.id.progressBar1);
        errormsg = (TextView) itemView.findViewById(R.id.errormsg);
    }
}
static class HeaderViewHolder extends RecyclerView.ViewHolder {
    public RecyclerView vaultsRecyclerView;


    public HeaderViewHolder(View itemView) {
        super(itemView);
        vaultsRecyclerView = (RecyclerView) itemView.findViewById(R.id.my_Vaults_recycler_view);

    }
}}

Tried library RvJoiner

I tried to implement two recycler views one below the other in the same xml but only one showed up and the other didnt. It would be great if you could link me up to some tutorials.

andrea.petreri
  • 4,137
  • 2
  • 22
  • 21
Ronak Makwana
  • 188
  • 2
  • 12

1 Answers1

8

Instead of merging two RecyclerView into one, you can just define one RecyclerView (so one adapter) with two different view types and play with GridLayoutManager, so that elements could fill a different number of columns depending on their type.

Here on GitHub I have an implementation that does exactly what you are trying to do.

I provide you below just few details about code and main things to highlight:

  • Define in your model two different item types, one for Grid part and another one for List part. They should both extend the same abstract class. Of course you can add all parameters you need for rendering your items. In this simple case I'm just using a label in each element.

    public abstract class AbstractItem {
    
        public static final int GRID_TYPE = 0;
        public static final int LIST_TYPE = 1;
    
        private String label;
    
        public AbstractItem(String label) {
            this.label = label;
        }
    
        // getters and setters here
    
        abstract public int getType();
    
    }
    
    public class GridItem extends AbstractItem {
    
        public GridItem(String label) {
            super(label);
        }
    
        @Override
        public int getType() {
            return GRID_TYPE;
        }
    
    }
    
    public class ListItem extends AbstractItem {
    
        public ListItem(String label) {
            super(label);
        }
    
        @Override
        public int getType() {
            return LIST_TYPE;
        }
    
    }
    
  • In your Activity, initialize RecyclerView by using a GridLayoutManager implementing behavior you need. In particular, your grid will have 2 columns. GridItem elements will take one column only, while ListItem elements will take 2 columns (so they will use a colspan equals to 2). You can get this result by using method setSpanSizeLookup as follows:

    GridLayoutManager manager = new GridLayoutManager(this, 2);
    manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
        @Override
        public int getSpanSize(int position) {
            AbstractItem item = mItems.get(position);
            switch (item.getType()) {
                case AbstractItem.GRID_TYPE:
                    // grid items to take 1 column
                    return 1;
                default:
                    // list items to take 2 columns
                    return 2;
            }
        }
    }); 
    

This is the final outcome I get:

enter image description here

Hope this could help.

andrea.petreri
  • 4,137
  • 2
  • 22
  • 21
  • @RonakMakwana Glad I could help! :) – andrea.petreri Feb 04 '16 at 08:26
  • My GridItem has Following items private String Text; private int NewPostCount; private String abbreviation; private String Color; private String FooterColor; private long TotalPost; private int UnAnswered; public boolean selected; my List item is collection of arraylist. so how can i make AbstractItem to combine both items in one. – Ronak Makwana Feb 04 '16 at 09:35
  • 1
    @RonakMakwana you don't need to share all data among different view types. Just common attributes can be put in AbstractItem. [Here](http://stackoverflow.com/questions/34936863/android-how-do-i-switch-layouts-for-a-recyclerview-list/34941058#34941058) is an answer where I explained how to proceed, by wrapping your model object inside class used for representing list item. – andrea.petreri Feb 04 '16 at 09:45
  • i tried your code. its working fine with my all views. but i am getting **android.support.v7.widget.recyclerview$viewholder.mitemviewtype' on a null object reference** while adding more data to adapter. can you please help? – Ronak Makwana Feb 04 '16 at 12:54
  • @RonakMakwana could you share [here](http://paste.ofcode.org/) code of your adapter, so that I can better understand what's going on? – andrea.petreri Feb 04 '16 at 12:59
  • @RonakMakwana can I ask you which is the row generating crash? – andrea.petreri Feb 04 '16 at 13:49
  • http://paste.ofcode.org/L5iFR8DZLNvUJ387sSeuuq this is my logcat. the error occurs when i am adding new data to adapter. – Ronak Makwana Feb 04 '16 at 13:54
  • @RonakMakwana at high level, I don't see relevant errors. Just I think you can remove line 245 in your adapter. Maybe there's something wrong in how you are filling and updating your RecyclerView from your fragment. Is it possible for you to share that code too? – andrea.petreri Feb 04 '16 at 14:10
  • There is a method to additemfeed in adapter I just call it in my fragment by passing data. (Data which has only one viewtype list_viewtype) – Ronak Makwana Feb 04 '16 at 15:34
  • @RonakMakwana uhm... looking at code it seems you have 3 view types, having 3 corresponding view holder: MyVaultViewHolder, LoadingViewHolder and FeedListViewHolder. Since you have just a method for adding FeedItems I'm wondering is how you add items for classes VaultsPojo and LoadingItem for example. – andrea.petreri Feb 04 '16 at 15:42
  • http://paste.ofcode.org/BDcv6XaKsuSWmYqUNbSDyz here is the Updated Fragment Where i am trying to add data to Adapter Thanks – Ronak Makwana Feb 05 '16 at 06:54
  • @RonakMakwana line 54... `newadapter.notifyItemInserted(mItems.size() + 1)`... after you insert item, `mItems` size changed and correct position is `mItems.size()-1`. – andrea.petreri Feb 05 '16 at 06:58
  • no luck.. do you need any more info? changed the position and notified adapter. but still having same issue – Ronak Makwana Feb 05 '16 at 07:36
  • @thetonrifles is it possible to add a title separating the grid from the list? – Eduardo Bonfa Sep 21 '16 at 18:18
  • @EduardoBonfa Yes sure. In the example there are just 2 view types but you can add other types. A header is basically another view type that will fill the entire width of the recycler view (like the list item) but will be rendered in a different way (using another layout and another binding logic in the adapter). – andrea.petreri Sep 25 '16 at 12:54