在RecyclerView中使用异构布局

15 浏览
0 Comments

在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我重写的CursorAdapternewView()代码:\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请问我做错了什么?

0
0 Comments

在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的布局更加灵活多样。

0
0 Comments

问题出现的原因是因为在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(); },然后检查它是否能正确工作。

现在今天的天气能够得到正确的布局,但明天和其他一些随机的天气也得到了为今天设计的布局。

0