如何设计Gridview像监护人的应用程序

时间:2016-05-04 08:13:19

标签: android listview gridview android-recyclerview

我正在努力制作像监护人应用程序一样的布局。我知道什么是gridview以及如何设计它并用数据等充气。

我想设计什么?

enter image description here

此布局包含带图像但没有图像的项目,并且还有延迟加载。

我面临的问题是什么?

  

1 - 我应该选择哪种观点。 GridView,ListView或   RecyclerView。

     

2 - 如果我使用GridView,那么如何使用不同的项目布局   一些项目。

我尝试了什么?

我尝试使用线性布局作为单独的xml,然后在运行时将xml添加到root布局。虽然我需要添加clicklistener以显示相关帖子,但它会有一定的工作但问题会增加,因为会有超过100个帖子数据。

如果有人指导我正确的方向,那会很有帮助。谢谢!

EDIT。经过这里的答案后。我用这种方法。我习惯了xml。然后我用适配器中的getViewType更改布局,但是没有给出这样的结果。我仍在寻找更有说服力的解决方案。

这是我累了的代码。

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);
        }
    }
}
}

8 个答案:

答案 0 :(得分:6)

您需要使用带有RecyclerView的StaggeredGridLayoutManager来实现监护人应用程序中正在执行的操作。请参阅此链接StaggeredGridLayoutManager Tutorial

修改1

我编写了一个小样本应用程序,可以演示监护应用程序正在实现的目标。这是Github link。我将在每个步骤中解释它:

  • 我使用的是StaggerdGridLayoutManager,因为你所指的守护程序应用程序占用了不同的单元格高度。这种布局使我们能够拥有不同高度的物品。

  • 对于每种不同的视图类型,我们必须创建不同的视图持有者。例如,我为示例应用程序中的每个不同项目类型创建了3个不同的视图持有者。

  • 覆盖getItemViewType,让recyclerview适配器知道哪个视图要膨胀。

例如,我将数据对象存储在Object类型的List中以存储异构对象,并检查每个项目是否为特定类的实例。我创建了3种不同的类型:

@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;
}
  • 获取OnCreateViewHolder中当前视图持有者的itemViewType,以确定要扩张的布局。

对于样本的实例:

@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;
}
  • 使特定类型的项目覆盖整行范围。

由于某些帖子类型在监护人应用程序中占据全部范围,我们可以在OnBindViewHolder方法中使用以下代码使任何项目扩展到完整的布局范围。

@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);
    }
}

这使得该项目覆盖了所有布局范围,就像监护人应用程序中最大的帖子一样。

通过以上步骤,您可以创建类似这样的布局(来自示例github应用程序的图像):

enter image description here

这里有3种不同的项目类型:上面两个项目是按钮,中间一个是ImageView,底部是TextView。

答案 1 :(得分:3)

您可以将Recycler视图与GridLayoutManager一起使用。并在您的适配器中根据您的要求制作不同的布局类型。

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;
                }
            }
        });

转到this了解详情。

编辑:

关注我的github demo

enter image description here

答案 2 :(得分:1)

有三种不同的视图,一个大网格,两个小网格和3-4个列表视图项目。很难仅使用一种视图来完成这样的任务。 我建议你创建一些自定义视图来处理网格(大和小),以及一个列表视图来处理列表项。之后,您可以在其他会话中重用网格的自定义视图和列表视图的自定义适配器。

如果您确实想使用一个网格视图来处理不同的视图,那么创建一个包含所有功能的通用视图,并在需要时禁用/启用这些功能。但是,这要复杂得多。

答案 3 :(得分:1)

您可以使用RecyclerView,因为它为您提供了定义不同项目类型的方法。但是仍然要创建这样的视图,你必须根据它的布局做很多代码。

您必须覆盖getItemViewType方法并尝试查找下一个要显示的视图类型。示例代码

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

    return TYPE_ITEM;
}

希望这会有所帮助

答案 4 :(得分:1)

您需要:非对称网格视图

  

https://github.com/felipecsl/AsymmetricGridView

上面的链接会有所帮助。

您可以定义一个常见的onClickListener

答案 5 :(得分:1)

您必须将RecyclerViewStaggeredGridLayoutManager一起使用。

答案 6 :(得分:1)

我将解释你如何做而不是编写我们将使用Recylerview的整个代码

  • Recylervew有四个项目(Item1,Item2,Item3,Item4)

  • 第1项:它将包含View1

  • 第2项:它将包含VIew2
  • 第3项:它将包含VIew3
  • 第4项:它将包含VIew4

  • View1:它将包含一个用于评论和日期部分的文本布局和其他布局

  • View2:它将包含图像视图
  • View3:它将包含一行和两列的tablelayout
  • View4:它将包含linearlayout

enter image description here

答案 7 :(得分:1)

要实现上述布局设计,您需要将recyclerViewStaggaredGridLayoutManager一起使用。