如何为 android gridview 中的行设置不同的列
How to set different columns for rows in android gridview
我想要一个类似这样的gridview
每个奇数行将有两个大尺寸的图像,偶数行将有四个较小的图像images.How我可以实现吗?
创建两个不同的 XML 文件并根据 Adapter 中的位置进行膨胀,如下所示。
if(position%2==0){
//Inflate Even number layout with 4 images
}else{
//Inflate ODD number layout with 2 images
}
我有类似的问题,我用新的 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" />
在您的 Fragment/Activity 上(在我的片段案例中是 OnViewCreated)。
我找到了 RecyclerView 并设置了一个 Adapter- 一个普通的 Adapter class 继承自 RecyclerView.Adapter< YOUR VIEW HOLDER class >-
然后我创建一个 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);
有了这个,您将获得行中单元格的动态数量。
额外:
然后,如果您在适配器上使用相同的 view/type 视图,您将获得相同的 w & h 视图。您需要为 TYPE_HIGH 创建 2 个 xml 视图,为 TYPE_LOW.
创建其他视图
因此,在您的适配器中,您需要有两种数据(一种用于高图像,一种用于低图像)。
您必须覆盖此方法
@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;
}
我希望我说清楚了,有什么问题告诉我。
我没有考虑单个图像视图,而是将三个图像组作为单个网格项,
在您的网格适配器中试试这个
<?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>
您唯一需要注意的是图像的顺序。也许这会对你有所帮助
如果您将 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);
希望这对你有用!
使用可扩展列表视图并为每一行提供不同的视图。
http://developer.android.com/reference/android/widget/ExpandableListView.html
你试过RecyclerView in a combination with a StaggeredGridLayoutManager吗?
这种组合的结果是这样的:video。
我想,这就是您要找的。
试试这个,
https://github.com/etsy/AndroidStaggeredGrid
交错网格视图,
非常简单,容易上手。
我想最好的方法是使用回收视图..
此外,它优于 list/grid 的性能
下面的链接可能会有很大帮助 - 所有内容都与 Lucas 的双向视图有关
https://github.com/lucasr/twoway-view
它在我的项目中是如何工作的我有不同的单元格高度,还有 header
适配器:
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);
}
}
}
在你的 activity 中:
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();
}
您应该在 RecyclerView
中设置:
recyclerView.setLayoutManager(new GridLayoutManager(this, 4));
我想要一个类似这样的gridview
每个奇数行将有两个大尺寸的图像,偶数行将有四个较小的图像images.How我可以实现吗?
创建两个不同的 XML 文件并根据 Adapter 中的位置进行膨胀,如下所示。
if(position%2==0){
//Inflate Even number layout with 4 images
}else{
//Inflate ODD number layout with 2 images
}
我有类似的问题,我用新的 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" />
在您的 Fragment/Activity 上(在我的片段案例中是 OnViewCreated)。 我找到了 RecyclerView 并设置了一个 Adapter- 一个普通的 Adapter class 继承自 RecyclerView.Adapter< YOUR VIEW HOLDER class >- 然后我创建一个 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);
有了这个,您将获得行中单元格的动态数量。
额外: 然后,如果您在适配器上使用相同的 view/type 视图,您将获得相同的 w & h 视图。您需要为 TYPE_HIGH 创建 2 个 xml 视图,为 TYPE_LOW.
创建其他视图因此,在您的适配器中,您需要有两种数据(一种用于高图像,一种用于低图像)。 您必须覆盖此方法
@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;
}
我希望我说清楚了,有什么问题告诉我。
我没有考虑单个图像视图,而是将三个图像组作为单个网格项,
在您的网格适配器中试试这个
<?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>
您唯一需要注意的是图像的顺序。也许这会对你有所帮助
如果您将 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);
希望这对你有用!
使用可扩展列表视图并为每一行提供不同的视图。
http://developer.android.com/reference/android/widget/ExpandableListView.html
你试过RecyclerView in a combination with a StaggeredGridLayoutManager吗?
这种组合的结果是这样的:video。
我想,这就是您要找的。
试试这个,
https://github.com/etsy/AndroidStaggeredGrid
交错网格视图,
非常简单,容易上手。
我想最好的方法是使用回收视图.. 此外,它优于 list/grid 的性能
下面的链接可能会有很大帮助 - 所有内容都与 Lucas 的双向视图有关
https://github.com/lucasr/twoway-view
它在我的项目中是如何工作的我有不同的单元格高度,还有 header
适配器:
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);
}
}
}
在你的 activity 中:
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();
}
您应该在 RecyclerView
中设置:
recyclerView.setLayoutManager(new GridLayoutManager(this, 4));