在RecyclerView中使用异构布局
在RecyclerView中使用异构布局
我正在开发一个天气应用程序,希望在其中使用两个Views
作为RecyclerView
的成员,其中使用了CursorAdapter
。我想使用一个View
显示今天的天气,另一个View
显示其他天的天气。如果只使用一个View
显示天气,我的RecyclerView
正常工作。我还重写了getItemViewType()
方法,以了解应该使用哪种View
类型。\ngetItemViewType()
的代码:\n
private static int VIEW_TYPE_TODAY = 0; private static int VIEW_TYPE_FUTURE_DAY = 1; @Override public int getItemViewType(int position) { if(position == VIEW_TYPE_TODAY) return VIEW_TYPE_TODAY; else return VIEW_TYPE_FUTURE_DAY; }
\n我重写的CursorAdapter
的newView()
代码:\n
@Override public View newView(Context context, Cursor cursor, ViewGroup parent) { int viewType = getItemViewType(cursor.getPosition()); int layoutId = -1; if(viewType==VIEW_TYPE_TODAY) layoutId = R.layout.list_item_forecast_today; else if(viewType==VIEW_TYPE_FUTURE_DAY) layoutId = R.layout.list_item_forecast; View view = LayoutInflater.from(context).inflate(layoutId, parent, false); return view; }
\n无论getItemViewType()
中的position
的值是什么,该函数始终返回VIEW_TYPE_TODAY
。\n请问我做错了什么?
在RecyclerView中使用异构布局的原因可能是为了实现不同类型的列表项,每个列表项的布局和样式可能不同。解决方法可能是使用RecyclerView的多布局功能,为每个类型的列表项创建不同的布局文件,并在适配器中根据列表项的类型选择相应的布局。以下是一种可能的解决方法的示例代码:
// 定义列表项的多种布局... ... ...
// 在适配器中根据列表项的类型选择相应的布局 @Override public int getItemViewType(int position) { // 根据位置获取列表项的类型 int type = getItemType(position); // 返回相应的布局类型 if (type == TYPE_1) { return R.layout.layout_type1; } else if (type == TYPE_2) { return R.layout.layout_type2; } ... } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { // 根据布局类型创建对应的ViewHolder View view = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false); if (viewType == R.layout.layout_type1) { return new Type1ViewHolder(view); } else if (viewType == R.layout.layout_type2) { return new Type2ViewHolder(view); } ... } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { // 根据位置获取列表项的类型 int type = getItemType(position); // 根据类型绑定相应的数据和视图 if (type == TYPE_1) { Type1ViewHolder type1ViewHolder = (Type1ViewHolder) holder; type1ViewHolder.bindData(getItem(position)); } else if (type == TYPE_2) { Type2ViewHolder type2ViewHolder = (Type2ViewHolder) holder; type2ViewHolder.bindData(getItem(position)); } ... }
这样,RecyclerView就可以根据列表项的类型选择相应的布局,并正确地绑定数据和视图。使用异构布局可以满足不同类型列表项的需求,使RecyclerView的布局更加灵活多样。
问题出现的原因是因为在RecyclerView中使用了不同类型的布局,但仅仅重写了getItemViewType方法是不够的。还需要重写getViewTypeCount方法,以返回所需的不同布局的数量(在这个例子中是2)。请记住,getItemViewType方法必须返回在范围[0, getViewTypeCount() - 1]内的连续整数。
解决方法是在newView方法中添加一行代码:if (cursor.getPosition() == -1) { cursor.moveToFirst(); }。这样可以确保cursor的位置正确,从而正确地加载不同的布局。
然而,目前的实现中存在一个bug,重写getViewTypeCount方法并不能改变正常的行为。因此,需要检查代码中是否还存在其他问题。
你可以在以下链接中查看RecyclerView适配器的代码,并指出其中的bug:[链接](http://stackoverflow.com/questions/38309177)
你是如何加载cursor的?
我是使用loaders来加载cursor的。
cursor.getPosition()返回-1?尝试在newView方法的最开始加上if (cursor.getPosition() == -1) { cursor.moveToFirst(); },然后检查它是否能正确工作。
现在今天的天气能够得到正确的布局,但明天和其他一些随机的天气也得到了为今天设计的布局。