我想用一个数据集列表创建以下UI。
我尝试使用多种视图类型但无法达到我的要求。我还实施了此博客Android Horizontal and Vertical RecyclerView Example。
但是这使用了两个recyclerviews,并且有两组数据(水平数据和垂直数据)。
我也试过这个。 RecyclerView with multiple views using custom adapter in Android
但是这是在XML中使用静态卡视图并将它们加载到适配器中。
我是Android开发的初学者。请帮忙!
提前谢谢。
答案 0 :(得分:3)
使用GridLayoutManager
和两个"项目视图类型&#34>可以实现所需的布局。在RecyclerView.Adapter
内。
以下是我的布局XML文件:
activity_main.xml:
-------------------------
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
horizontal.xml:
-------------------------
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="120dp"
android:layout_margin="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:id="@+id/image"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#ccc"/>
<TextView
android:id="@+id/text"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:background="#fff"
android:textColor="#000"
android:textSize="18sp"
android:text="TEXT"/>
</LinearLayout>
</android.support.v7.widget.CardView>
vertical.xml:
-------------------------
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="120dp"
android:layout_margin="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#ccc"/>
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center"
android:background="#fff"
android:textColor="#000"
android:textSize="18sp"
android:text="TEXT"/>
</LinearLayout>
</android.support.v7.widget.CardView>
&#13;
这是我的Java文件:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GridLayoutManager manager = new GridLayoutManager(this, 2);
manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return (position % 4) < 2 ? 2 : 1;
}
});
RecyclerView recycler = (RecyclerView) findViewById(R.id.recycler);
recycler.setLayoutManager(manager);
recycler.setAdapter(new MyAdapter());
}
private static class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
@Override
public int getItemViewType(int position) {
return (position % 4) < 2
? R.layout.horizontal
: R.layout.vertical;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View itemView = inflater.inflate(viewType, parent, false);
return new MyViewHolder(itemView);
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.image.setImageResource(R.drawable.mouse);
holder.text.setText("" + position);
}
@Override
public int getItemCount() {
return Integer.MAX_VALUE;
}
}
private static class MyViewHolder extends RecyclerView.ViewHolder {
private final ImageView image;
private final TextView text;
public MyViewHolder(View itemView) {
super(itemView);
this.image = (ImageView) itemView.findViewById(R.id.image);
this.text = (TextView) itemView.findViewById(R.id.text);
}
}
}
&#13;
让我们回顾一下重要的部分。首先是GridLayoutManager
和SpanSizeLookup
的组合。我们使用以下行创建布局管理器:
GridLayoutManager manager = new GridLayoutManager(this, 2);
这意味着,默认情况下,我们网格的每一行都会有两张卡片。但是我们应用SpanSizeLookup
,它表示我们的一半行(由语句position % 4 < 2
找到)应该实际占用两列。所以我们会在我们的&#34;网格&#34;中重复使用一张卡,一张卡,两张卡片。
然后,在RecyclerView.Adapter
类中,我们覆盖getItemViewType()
方法。在这里,我们再次使用position % 4 < 2
语句说我们的一半视图应该是水平的,一半应该是垂直的。
getItemViewType()
只需要为每种视图类型返回任何唯一的int
,因此我们使用从此方法返回R.layout
常量的好方法。由于视图类型将传递到onCreateViewHolder()
,我们可以使用viewType
参数来扩展正确的布局。
那就是它!毕竟还不错。这是我的代码实际操作的屏幕截图:
答案 1 :(得分:1)
不久前我遇到过这个问题,虽然我可能不是专家,但我认为我的回答也可以帮到你。您可以通过创建两种不同类型的布局来完成此操作,类似于文章。您需要创建一个两个布局类型都可以扩展的抽象类。然后,在适配器中,检查应显示的对象类型。
抽象类:
Do Not Allow Emails
横向项目:
public abstract class ListItem {
public static final int TYPE_HORIZONTAL = 0;
public static final int TYPE_VERTICAL = 1;
abstract public int getType();
}
垂直项目:
public class HorizontalItem extends ListItem {
private String text;
private Bitmap image;
public HorizontalItem(String text, Bitmap image) {
this.text = text;
this.image = image;
}
/*
* Getter and setter methods here
*/
@Override
public int getType() {
return ListItem.TYPE_HORIZONTAL;
}
}
适配器:
public class VerticalItem extends ListItem {
private String text1;
private Bitmap image1;
private String text2;
private Bitmap image2;
public VerticalItem(String text1, String text2, Bitmap image1, Bitmap image2) {
this.text1 = text1;
this.image1 = image1;
this.text2 = text2;
this.image2 = image2;
}
/*
* Getter and setter methods here
*/
@Override
public int getType() {
return ListItem.TYPE_HORIZONTAL;
}
}
的活动:
public class ListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private ArrayList<ListItem> listItems;
public static class HorizontalViewHolder extends RecyclerView.ViewHolder {
public TextView text;
public ImageView imageView;
public HorizontalHolder(View v) {
super(v);
text = (TextView) v.findViewById(R.id.text);
imageView = (ImageView) v.findViewById(R.id.imageView);
}
}
public static class VerticalViewHolder extends RecyclerView.ViewHolder {
public TextView text1;
public ImageView imageView1;
public TextView text2;
public ImageView imageView2;
public HorizontalHolder(View v) {
super(v);
text1 = (TextView) v.findViewById(R.id.text1);
imageView1 = (ImageView) v.findViewById(R.id.imageView1);
text2 = (TextView) v.findViewById(R.id.text2);
imageView2 = (ImageView) v.findViewById(R.id.imageView2);
}
}
// constructor
public ListAdapter(ArrayList<ListItem> listItems) {
this.listItems = listItems;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v;
RecyclerView.ViewHolder holder = null;
switch (viewType) {
case ListItem.TYPE_HORIZONTAL:
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.template_horizontal, parent, false);
holder = new HorizontalViewHolder(v);
break;
case ListItem.TYPE_VERTICAL:
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.template_vertical, parent, false);
holder = new VerticalViewHolder(v);
break;
}
return holder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
case ListItem.TYPE_HORIZONTAL:
((HorizontalViewHolder) holder).text.setText(listItems.get(position).getText());
((HorizontalViewHolder) holder).imageView.setImageBitmap(listItems.get(position).getBitmap());
// the getText() and getBitmap() methods come from the getters of the HorizontalItems and VerticalItems that are stored in the ArrayList, listItems
break;
case ListItem.TYPE_DECK:
// Identical to above
break;
}
}
@Override
public int getItemCount() {
return listItems.size();
}
// This is extremely important, it is what lets the adapter know what type each listItem element is
@Override
public int getItemViewType(int position) {
return listItems.get(position).getType();
}
}
在垂直列表项的布局中,我只创建一个带有两半的文件。您可以使用LinearLayout轻松地将子部分分成完美的一半。