如何在android gridview中为行设置不同的列

时间:2015-04-05 13:18:06

标签: android gridview

我想要一个与此类似的网格视图

enter image description here

每个奇数行都会有两个大尺寸的图像,偶数行会有四个较小的图像。我怎样才能实现这个目标?

10 个答案:

答案 0 :(得分:33)

我有类似的东西,我用新的RecyclerView解决了。

我创建了一个带有RecyclerView的片段。 在xml上的RecyclerView:

<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/filter_subtypes" android:layout_width="match_parent" android:layout_height="match_parent" />

在你的片段/活动上(在我的片段情况下是OnViewCreated)。 我找到了RecyclerView并设置了一个适配器 - 一个普通的Adapter类继承自 RecyclerView.Adapter&lt;您的观看持有人类&gt; - 然后我创建一个GridLayoutManager

final GridLayoutManager mng_layout = new GridLayoutManager(this.getActivity(), TOTAL_CELLS_PER_ROW/*In your case 4*/);


然后我重写此方法以设置动态数量的列(单元格)

mng_layout.setSpanSizeLookup( new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                switch( adapterSubtype.getItemViewType(position) ) {
                    case FilterSubtypesAdapter.TYPE_LOW:
                        return TOTAL_CELLS_PER_ROW;
                    case FilterSubtypesAdapter.TYPE_HIGH:
                        return 2;
                    default:
                        return -1;
                }
            }
        });
myRecyclerView.setLayoutManager(mng_layout);

通过这种方式,您可以在行上获得动态的单元格数。

EXTRA: 然后,如果您在适配器上使用相同的视图/类型视图,您将得到相同的w&amp;我认为。您需要为TYPE_HIGH创建2个xml视图,为TYPE_LOW创建其他视图。

因此,在适配器中,您需要有2种数据(1表示高图像,1表示低图像)。 您必须覆盖此方法

@Override
public SubtypeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = null;
    if (viewType==TYPE_HIGH) {
        view = inflater.inflate(R.layout.item_image_high, parent, false);
    } else {
        view = inflater.inflate(R.layout.item_image_low, parent, false);
    }
    return new SubtypeViewHolder(view, viewType);
}

 @Override
 public int getItemViewType(int position) {
     return (list.get(position).getType()==Subtype_type.HIGH) ? TYPE_HIGH : TYPE_LOW;
 }

我希望我很清楚,任何问题都告诉我。

答案 1 :(得分:22)

不是考虑单个图像视图而是将三个图像组作为单个网格项,

enter image description here

在你的网格适配器中试试这个

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linear"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/green"
    android:orientation="vertical">
<ImageView
    android:id="@+id/image"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:scaleType="fitXY"
    android:src="@drawable/user"
     />
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <ImageView
            android:id="@+id/image_1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:scaleType="fitXY"
            android:src="@drawable/user"

            />
        <ImageView
            android:id="@+id/image_2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:src="@drawable/user"
            android:scaleType="fitXY"
            android:layout_weight="1"
            />

        </LinearLayout>

    </LinearLayout>

,您的网格视图就像

<GridView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/RelativeLayout1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:numColumns="2"
    >

</GridView>

唯一需要注意的是图像的顺序。可能这会帮助你

答案 2 :(得分:10)

如果您将RecyclerView用于GridView,那么有适用于您的解决方案:

GridLayoutManager layoutManager = new GridLayoutManager(this, 4);
layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
    @Override
    public int getSpanSize(int position) {
         int mod = position % 6;    

         if(position == 0 || position == 1)
              return 2;
         else if(position < 6)
              return 1;
         else if(mod == 0 || mod == 1)
              return 2;
         else
              return 1;
    }
});

recyclerView.setLayoutManager(layoutManager);

希望这对你有用!

答案 3 :(得分:1)

我想最好的方法是使用Recycler view .. 此外,它优于列表/网格的性能

可能在链接下方可以提供很多帮助 - 所有这些都与Lucas的双向视图有关

https://github.com/lucasr/twoway-view

https://plus.google.com/+LucasRocha/posts/WBaryNqAHiy

http://lucasr.org/2014/07/31/the-new-twowayview/

答案 4 :(得分:1)

在我的项目中它有什么作用我有不同的单元格高度和标题

enter image description here

适配器:

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

private List<BaseMarkerElement> mainCardList;
private final int HEADER_VIEW = 0;
private final int FOOTER_VIEW = 1;

public AdapterRecViewMain() {
}

public void setData(List<BaseMarkerElement> mainCardList) {
    this.mainCardList = mainCardList;
}

@Override public int getItemViewType(int position) {
    if (position == 0) {
        return HEADER_VIEW;
    }
    return FOOTER_VIEW;
}

@Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int type) {
    if (type == FOOTER_VIEW) {
        View v = LayoutInflater.from(viewGroup.getContext())
                .inflate(R.layout.card_main_activity, viewGroup, false);
        return new MainCardViewHolder(v);
    } else {
        View v = LayoutInflater.from(viewGroup.getContext())
                .inflate(R.layout.header_view_main_activity, viewGroup, false);
        return new HeaderViewHolder(v);
    }
}

@Override public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int positionItem) {
    final int position = viewHolder.getAdapterPosition();

    if (viewHolder instanceof HeaderViewHolder) {
        StaggeredGridLayoutManager.LayoutParams layoutParams =
                (StaggeredGridLayoutManager.LayoutParams) viewHolder.itemView.getLayoutParams();
        layoutParams.setFullSpan(true);

        BaseMarkerElement item = mainCardList.get(position);
        if (item instanceof HeaderView) {
            HeaderView header = (HeaderView) mainCardList.get(position);
            // need to add implementation
        }
    } else if (viewHolder instanceof MainCardViewHolder) {
        MainCardViewHolder currentView = (MainCardViewHolder) viewHolder;
        CardMainActivity currentCard = (CardMainActivity) mainCardList.get(position);

        currentView.ivMainCard.setImageResource(currentCard.getIvMainCard());
        currentView.tvBrandName.setText(currentCard.getTvBrandName());
        currentView.tvPrice.setText(currentCard.getTvPrice());
        currentView.tvType.setText(currentCard.getTvType());
    }
}

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

private class MainCardViewHolder extends RecyclerView.ViewHolder {
    ImageView ivMainCard;
    TextView tvBrandName;
    TextView tvType;
    TextView tvPrice;

    MainCardViewHolder(View view) {
        super(view);
        ivMainCard = (ImageView) view.findViewById(R.id.imageViewMainCard);
        tvBrandName = (TextView) view.findViewById(R.id.tvBrandName);
        tvType = (TextView) view.findViewById(R.id.tvType);
        tvPrice = (TextView) view.findViewById(R.id.tvPrice);
    }
}

private class HeaderViewHolder extends RecyclerView.ViewHolder {

    public HeaderViewHolder(View itemView) {
        super(itemView);

    }
}
}

在您的活动中:

private AdapterRecViewMain adapter;
private RecyclerView rvMain;

@Override protected void onResume() {
    super.onResume();
    Logger.logGeneral("onResume()");

    if (adapter == null) {
        setUpRecView();
    }
}

private void setUpRecView() {
    adapter = new AdapterRecViewMain();
    adapter.setData(controller.loadData());
    rvMain = (RecyclerView) findViewById(R.id.rvMain);
    final StaggeredGridLayoutManager layoutManager =
            new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
    rvMain.setLayoutManager(layoutManager);

    rvMain.addOnScrollListener(scrollListener);
    rvMain.setAdapter(adapter);
    adapter.notifyDataSetChanged();
    rvMain.invalidate();
}

答案 5 :(得分:1)

您应该在RecyclerView中进行设置:

recyclerView.setLayoutManager(new GridLayoutManager(this, 4));

答案 6 :(得分:0)

创建两个不同的XML文件,并根据适配器中的位置进行充气,如下所示。

if(position%2==0){
//Inflate Even number layout with 4 images
}else{
//Inflate ODD number layout with 2 images
}

答案 7 :(得分:0)

您是否与RecyclerView组合使用了StaggeredGridLayoutManager

此组合会产生如下结果:video

我想,这就是你要找的东西。

答案 8 :(得分:0)

试试这个,

https://github.com/etsy/AndroidStaggeredGrid

交错网格视图,

非常简单,易于使用。

答案 9 :(得分:-1)

使用可扩展列表视图并为每行提供不同的视图。

http://developer.android.com/reference/android/widget/ExpandableListView.html