Home » Android » android – How to design Gridview like guardian app

android – How to design Gridview like guardian app

Posted by: admin June 15, 2020 Leave a comment

Questions:

I am trying to make layout like guardian app. I know what is gridview and how to design it and inflate it with data etc.

what i want to design?

enter image description here

This layout have items with images and not with and there is also lazy loading going on in it.

What are the problem i am facing?

1-Confused which viewi should i go with. GridView,ListView or
RecyclerView.

2-if i go with GridView then how to have different item layouts for
some items.

What i have tried?

I have tried using linear layout as seperate xml and then i add that xml to root layout on run time. it works somewhat but problem rise when i need to add clicklistener to show relevent post since there would be more than 100+ post data.

It would be a lot of help if somebody guide me in right direction. Thanks!

EDIT. After going through the answer here. I used this approach. I used to xml. Then i change the layout with getViewType in adapter but that doesn’t give such results. I am still looking for more convincing solution.

Here is the code that i have tired.

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder>{

MainDTO mainDTO;
public RecyclerAdapter(MainDTO mainDTO){
    this.mainDTO=mainDTO;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view;
    ViewHolder viewHolder;
    switch (viewType){
        case 0:
            view= LayoutInflater.from(parent.getContext()).inflate(R.layout.header,parent,false);
            viewHolder=new ViewHolder(view,viewType);
            return viewHolder;
        default:
            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.box,parent,false);
            viewHolder=new ViewHolder(view,viewType);
            return viewHolder;
    }
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    ImageLoader imageLoader = ImageLoader.getInstance();
    if(position == 0){
        imageLoader.displayImage(mainDTO.getPosts().get(position).getThumbnail_images().getFull().getUrl(),holder.thumbnail);
        holder.title.setText(mainDTO.getPosts().get(position).getTitle());
    }
    else if (position > 0 ){
        if(mainDTO.getPosts().get(position).getThumbnail_images()!=null)
            imageLoader.displayImage(mainDTO.getPosts().get(position).getThumbnail_images().getFull().getUrl(),holder.thumbnail);
        holder.title.setText(mainDTO.getPosts().get(position).getTitle());
    }
}

@Override
public int getItemCount() {
    return mainDTO.getPosts().size();
}

@Override
public int getItemViewType(int position) {
    int viewType = 1; //Default is 1
    if (position == 0) viewType = 0; //if zero, it will be a header view
    return viewType;
}

public static class ViewHolder extends RecyclerView.ViewHolder{
    public TextView title;
    public ImageView thumbnail;
    public ViewHolder(View itemView,int viewType) {
        super(itemView);

        if(viewType == 0){
            title = (TextView)itemView.findViewById(R.id.tv_title);
            thumbnail = (ImageView)itemView.findViewById(R.id.iv_thumbnail);
        }else if(viewType == 1){
            title = (TextView)itemView.findViewById(R.id.tv_title_2);
            thumbnail = (ImageView)itemView.findViewById(R.id.iv_thumbnail_2);
        }
    }
}
}
How to&Answers:

You will need to use StaggeredGridLayoutManager with RecyclerView to achieve what is being done in the guardian app. See this link StaggeredGridLayoutManager Tutorial

Edit 1

I have written a small sample application which can demonstrate what guardian application is achieving. Here is the Github link. I will explain it along the way with each step:

  • I used a StaggerdGridLayoutManager since in guardian app you are referring to have occupied different cell heights. This layout enables us to have items with different height.

  • For every different view type we have to create different view holders. For instance I have created 3 different view holders for every different item type in the sample application.

  • Override getItemViewType to let the recyclerview adapter know which view to inflate.

For instance of sample, I stored my data objects in an List of type Object to store heterogeneous objects and checked every item if its an instance of a particular class. I created 3 different types:

@Override
public int getItemViewType(int position) {
    // we check here which item type to return based on object type
    if (items.get(position) instanceof ImageModel)
        return ITEM_TYPE_IMAGE;
    if (items.get(position) instanceof TextViewModel)
        return ITEM_TYPE_TEXT;
    if (items.get(position) instanceof ButtonModel)
        return ITEM_TYPE_BUTTON;

    return -1;
}
  • Get itemViewType for the current view holder in OnCreateViewHolder in order to determine which layout to inflate.

For the instance of sample:

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    switch (viewType){
        case ITEM_TYPE_IMAGE:
            View image = ((LayoutInflater)BaseApplication.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.item_image, parent, false);
            return new ImageViewHolder(image);
        case ITEM_TYPE_BUTTON:
            View button = ((LayoutInflater)BaseApplication.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.item_button, parent, false);
            return new ButtonViewHolder(button);
        case ITEM_TYPE_TEXT:
            View text = ((LayoutInflater)BaseApplication.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.item_text, parent, false);
            return new TextViewHolder(text);
    }

    return null;
}
  • Make specific type of items cover full row span.

Since some posts types are occupying full span in guardian application, we can use below code in OnBindViewHolder method to make any item expand to full span of layout.

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    if (holder.getItemViewType() == ITEM_TYPE_IMAGE){
        StaggeredGridLayoutManager.LayoutParams layoutParams = (StaggeredGridLayoutManager.LayoutParams) holder.itemView.getLayoutParams();
        layoutParams.setFullSpan(true);
    }
}

This makes the item cover all the span of layout like the biggest post in guardian application.

By following above steps, you can create a similar layout like this (image from sample github application):

enter image description here

Here there are 3 different item types: above two items are Buttons, middle one is ImageView and bottom are TextView.

Answer:

You can use recycler view with GridLayoutManager. And In your adapter make different layout type as per your requirements.

GridLayoutManager manager = new GridLayoutManager(getActivity(), 6);
        manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                // return your span size as per your layout type.
                return 6;
                }
            }
        });

Go to this for more info.

Edit:

Follow my github demo

enter image description here

Answer:

There is three different kinds of views, one large grid, two small grids and 3-4 list view items. It is hard to use only one kind of view to complete such a task.
I suggest you to create some custom views to handle the grids (large and small), and a list view to handle the list item. After that, you can reuse the custom views for the grids and the list view’s custom adapter in other sessions.

If you really want to use one Grid view to handle different views, then create a generic view that has all the functions and disable/enable the functions when you needed. However, this is much more complicated.

Answer:

You can use RecyclerView because it gives you method to define different item types. but still to create such view you have to do so much code on the basis of its layout.

You have to override getItemViewType method and try to find which view type will be next to display. example code

@Override
public int getItemViewType(int position) {
    if (isPositionHeader(position))
        return TYPE_HEADER;

    return TYPE_ITEM;
}

Hope this will help

Answer:

You require: Asymmetric Gridview

https://github.com/felipecsl/AsymmetricGridView

Above link will help.

You can define a common onClickListener

Answer:

I will explain You How to do instead of writing the whole code we will use Recylerview for it

  • Recylervew which have four Items (Item1,Item2,Item3,Item4)

  • Item1 : it will contains the View1

  • Item2 : It will contains the VIew2
  • Item3 : It will contains the VIew3
  • Item4 : It will contains the VIew4

  • View1 : It will contains one Layout for text and other layout for comment and day section

  • View2 : It will contain the Image View
  • View3 : It will contains the tablelayout with one row and two columns
  • View4 : It will contains the linearlayout

enter image description here

Answer:

TO achieve above layout design, you need to use recyclerView with StaggaredGridLayoutManager.

Answer:

You have to use RecyclerView with StaggeredGridLayoutManager.