带有标题的GridviewLayoutManager

时间:2015-06-04 16:29:04

标签: java android android-layout

我正在开发一款应用

我已经实现了一个工作的回收站视图,它接收一个jsonarray,将数据传递给字符串数组。

我现在想要将部分标题添加到布局管理器中。

我已经阅读了两种思想流派: - 更改视图的跨度大小以匹配网格的总列数 - 创建一个自定义适配器,如果该项是节标题,则加载不同的视图。

我不确定哪种方式可以解决这个问题,并且开始让我迷惑

我有一个数组列表,其中包括标题和网格数据(myDataset),我还创建了另一个数组,其中包含(myDatamap)中数据集的映射。在myDatamap中,我有一个字段类型列表(1表示标题,0表示griddata。我希望将两个数组传递给适配器,并决定它是一个标题还是一个griditem,然后加载相应的视图。

我更倾向于为标题项加载不同的视图,允许我更容易自定义标题的布局。

这是我的适配器代码

package com.example.alex.recyclerview2;

import java.util.ArrayList;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.squareup.picasso.Picasso;

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    private ArrayList<String> mDataset;
    private ArrayList<Integer> mDatamap;

    private Context context;
    // Provide a reference to the views for each data item
    // Complex data items may need more than one view per item, and
    // you provide access to all the views for a data item in a view holder
    public class ViewHolder extends RecyclerView.ViewHolder {
        // each data item is just a string in this case
        public TextView txtHeader;
        public TextView txtFooter;
        public ImageView imgImage;

        public ViewHolder(View v) {
            super(v);
            txtHeader = (TextView) v.findViewById(R.id.firstLine);
            txtFooter = (TextView) v.findViewById(R.id.secondLine);
            imgImage = (ImageView) v.findViewById(R.id.icon);
        }
    }

    public void add(int position, String item) {
        mDataset.add(position, item);
        notifyItemInserted(position);
    }

    public void remove(String item) {
        int position = mDataset.indexOf(item);
        mDataset.remove(position);
        notifyItemRemoved(position);
    }

    // Provide a suitable constructor (depends on the kind of dataset)
    public MyAdapter(ArrayList<String> myDataset, ArrayList<Integer> myDatamap) {mDataset = myDataset;myDatamap=mDatamap; }

    // Create new views (invoked by the layout manager)
    @Override
    public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                   int viewType) {
        // create a new view
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.sub_layout, parent, false);

        context = v.getContext();

        // set the view's size, margins, paddings and layout parameters
        ViewHolder vh = new ViewHolder(v);
        return vh;
    }

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        // - get element from your dataset at this position
        // - replace the contents of the view with that element
        final String name = mDataset.get(position);

        Picasso.with(context).load("http://www.500kgiveaway.co.uk/" + name).resize(200,200).into(holder.imgImage);

//        holder.txtHeader.setText(mDataset.get(position));
        holder.txtHeader.setText(name);

        holder.txtHeader.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                remove(name);
            }
        });

        holder.txtFooter.setText("Footer: " + mDataset.get(position));

    }

    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return mDataset.size();
    }

}

2 个答案:

答案 0 :(得分:0)

ive not had much interest in this post but here is the answer

i hope this help someone else

What i have done is implemented a custom view adaptor to manage the item types

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.squareup.picasso.Picasso;

import java.util.ArrayList;

public class ElementsAdapter extends RecyclerView.Adapter<ElementsAdapter.ViewHolder> {
    private ArrayList<String> mDataset;
    private ArrayList<Integer> mDatamap;

    public Context context;

    private static final int VIEW_HEADER = 0;
    private static final int VIEW_NORMAL = 1;

    private View headerView;
    private int datasetSize;

    public class ViewHolder extends RecyclerView.ViewHolder {
        // each data item is just a string in this case
        public TextView txtHeader;
        public TextView txtFooter;
        public ImageView imgImage;


        //header
        public TextView headertext;

        public ViewHolder(View v, int viewType) {
            super(v);

           switch (viewType){
                case 1:
                    txtHeader = (TextView) v.findViewById(R.id.firstLine);
                    txtFooter = (TextView) v.findViewById(R.id.secondLine);
                    imgImage = (ImageView) v.findViewById(R.id.icon);
               case 0:
                    headertext = (TextView) v.findViewById(R.id.headertext);
           }
        }

    }

    public ElementsAdapter(ArrayList<String> myDataset, ArrayList<Integer> myDatamap) {
        mDataset = myDataset;
        mDatamap = myDatamap;
    }

      @Override
    public int getItemViewType(int position) {
        return isHeader(position) == 1 ? VIEW_HEADER : VIEW_NORMAL;
    }

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

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == VIEW_HEADER) {
            // create a new view
            View sub_view = LayoutInflater.from(parent.getContext()).inflate(R.layout.header, parent, false);

            Context context = sub_view.getContext();

            // set the view's size, margins, paddings and layout parameters
            ViewHolder vh = new ViewHolder(sub_view,viewType);

            return vh;


//            return new HeaderViewHolder(headerView);

        } else {
            // create a new view
            View sub_view = LayoutInflater.from(parent.getContext()).inflate(R.layout.sub_layout, parent, false);

            context = sub_view.getContext();

            // set the view's size, margins, paddings and layout parameters
            ViewHolder vh = new ViewHolder(sub_view, viewType);

            return vh;


        }
    }

    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int position) {
        if (isHeader(position) == 1) {

            // - get element from your dataset at this position
            // - replace the contents of the view with that element
            final String name = mDataset.get(position);

//        holder.txtHeader.setText(mDataset.get(position));
            viewHolder.headertext.setText(name);

        } else {

    // - get element from your dataset at this position
    // - replace the contents of the view with that element
    final String name = mDataset.get(position);

    Picasso.with(context).load("http://www.500kgiveaway.co.uk/"+name).resize(200,200).into(viewHolder.imgImage);

//        holder.txtHeader.setText(mDataset.get(position));
    viewHolder.txtHeader.setText(name);

    viewHolder.txtHeader.setOnClickListener(new View.OnClickListener()

    {
        @Override
        public void onClick (View v){
        //remove(name);
    }
    }

    );

    viewHolder.txtFooter.setText("Footer: "+mDataset.get(position));
}

        //ViewHolder holder = (ViewHolder) viewHolder;
        //holder.textView.setText("Position " + (position - 1));
    }

    public int isHeader(int position) {
        return mDatamap.get(position) ==1 ? 1:0;}
}

答案 1 :(得分:0)

为什么不使用这两种解决方案?如果设置跨度大小,则可以轻松设置文本视图或任何您想要的标题。

gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                return adapter.isHeader(position) ? gridLayoutManager.getSpanCount() : 1;
            }
        });

然后在适配器中有一个通用的类Item,它说明项目是否是标题并且有关于应该显示的真实项目的一些信息,在我的情况下,因为我有用于显示图像和标题标题的图像路径我只是使用属性文本但您可以使用int realPositionInTheirLists之类的内容,因为标题标题和图像路径位于两个单独的列表中:

private static class Item {

    public boolean isHeader;

    public String text;

    public Item(String text, boolean isHeader) {
        this.isHeader = isHeader;
        this.text = text;
    }
}

然后你会在方法上找到类似的东西,告诉它是哪种类型的物品:

@Override
public int getItemViewType(int position) {
    return mItems.get(position).isHeader ? VIEW_TYPE_HEADER : VIEW_TYPE_CONTENT;
}

public boolean isHeader(int position) {
    return mItems.get(position).isHeader;
}

然后最后在两个方法中膨胀视图并绑定数据,根据它是否是标题来扩展您想要的视图,并使用Item类绑定数据:

@Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    View view;
    if (viewType == VIEW_TYPE_HEADER) {
        view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.grid_header, parent, false);
    } else {
        view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.grid_item, parent, false);
    }

    return new ViewHolder(view);
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {

    final Item item = mItems.get(position);

    holder.bindItem(item, position);
}

作为holder.bindItem的ViewHolder类的方法。在那里,您可以选择将两个视图分开。