【问题标题】:Is there a way to use a ViewStub inside a RecyclerView?有没有办法在 RecyclerView 中使用 ViewStub?
【发布时间】:2015-07-24 11:19:06
【问题描述】:

我是安卓新手, 我一直在做一个项目,在我的新闻提要页面中,我试图包含一个模块化提要 RecyclerView,它显示了一个具有不同答案形式的问题,根据问题类型而变化。到目前为止,我这样做的方式是使用包含并在需要时将表单变为可见。最近因为我添加了更多模块,应用程序开始显着变慢,所以我正在尝试实现 ViewStubs。

这是我的 RecyclerView 适配器:

public class ReQuestionAdapter extends RecyclerView.Adapter<FeedItem> {
private ArrayList<Question> myQuestions;
public ReQuestionAdapter(Context context, ArrayList<Question> questions) {
    myQuestions = questions ;
}

@Override
public FeedItem onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.list_item_re_question, parent, false);
    return new FeedItem(view);
}

@Override
public void onBindViewHolder(FeedItem holder, int position) {
    Question q = myQuestions.get(position);
    holder.bindQuestion(q);
}

@Override
public int getItemViewType(int position) {
    return 0;
}

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

这是适配器的 ViewHolder 类:

public class FeedItem extends RecyclerView.ViewHolder{
private Question mQuestion;
public TextView tvName;
public TextView tvTime;
public TextView tvContent;
public ProfilePictureView profilePictureView;
public ViewStub moduleView;
private int moduleType;

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

}

public void bindQuestion(Question question) {
    mQuestion = question;
    tvTime = (TextView) itemView.findViewById(R.id.li_q_date);
    tvContent = (TextView) itemView.findViewById(R.id.li_q_content);
    moduleView = (ViewStub) itemView.findViewById(R.id.module_viewstub);
    tvTime.setText(TimeHandler.When(mQuestion.publish_time));
    tvContent.setText(mQuestion.content);
    moduleType = question.type;
        switch (moduleType) {
            case Question.TYPE_YN:
                moduleView.setLayoutResource(R.layout.module_yes_no);
                moduleView.inflate();
                break;
            case Question.TYPE_CUSTOM:
                moduleView.setLayoutResource(R.layout.module_custom);
                moduleView.inflate();
                break;
            default:
                break;
        }
    }
}

现在,问题是包含特定布局的 ViewStub 不能用新布局重新膨胀,原因是它一离开屏幕就会从视图层次结构中删除,症状: 向下滚动 RecyclerView 时,填满屏幕的第一个列表项工作正常,但其他列表项在前一个离开屏幕时加载会导致 FeedItem 绑定带来 NullPointerException。 (在列表项布局中找不到)。

我正在寻找一种像 ViewStubs 一样高效的解决方案,或者一种使它们正常工作的方法,因为我有很多模块,并且在每个项目中将它们全部膨胀为 不可见 会使我的应用程序变慢.

【问题讨论】:

    标签: android data-binding android-recyclerview android-viewholder viewstub


    【解决方案1】:

    在您的 bindQuestion() 方法中,您引用了两种不同的布局来膨胀,因此本质上您有两种不同的视图类型。

    适配器视图有一种有效的方式来处理这个内置的。

    首先覆盖getItemViewType()。当position处的item获取module_yes_no布局时,返回0。当它获取module_custom布局时,返回1。

    然后在onCreateViewHolder() 中,当viewType 参数为0 时,使用module_yes_no 布局填充list_item_re_question 视图。当viewType == 1 时,膨胀module_custom 版本的视图。

    现在,当您在onBindViewHolder() 中获得视图时,它已经具有正确的子视图,因此您可以根据需要继续填写该视图。通过使用getItemViewType()RecyclerView 正在与您一起回收您需要的确切视图。

    您甚至可以有两个FeedItem 子类,一个用于module_yes_no,一个用于module_custom,因此在onBindViewHolder() 中,您只需检查ViewHolder 的类并相应地进行分支。

    这应该有助于提高应用的性能。

    【讨论】:

    • 非常感谢,所以我知道使用两个不同的 FeedItem 类,recyclerview 会自己知道要保留哪些部分,哪些是不同的?还是会根据请求创建 2 个循环视图?
    • 这两个FeedItem 课程只是为了您的利益。 RecyclerView 通过覆盖 getItemViewType() 知道要为您回收哪个视图。因此,假设第 20 项是 yes_no。如果您设置getItemViewType() 为 yes_no 项目返回 0,那么当用户滚动到项目 20 时,RecyclerView 以位置 == 20 调用您的 getItemViewType()。它收到 0,并说:“哦,看,我有用于回收的 0 型视图”,并将该视图传递给 onBindViewHolder()。有意义吗?
    • 那么如果RecyclerView 没有可回收的视图,它会调用onCreateViewHolder()viewType == 0,这样你就知道要膨胀哪种类型的视图以及哪种类型的视图持有者创建。
    • 知道了,非常感谢先生,你真的帮助了我:P 我也想知道我是否应该使用问题显示布局和答案表单布局,并将它们一起包含在不同的布局中,我将用于通货膨胀:
    • @AJW 是的,您应该覆盖 getItemViewType()。非常简单: 第 1 步:覆盖 getItemViewType(),因此它返回 0 表示小数据,1 表示大数据。第 2 步:使用 viewType 参数上的开关覆盖 onCreateViewHolder():0 扩展小型布局,1 扩展扩展布局。第 3 步:在onBindViewHolder() 中,您的视图持有者参数将已经通过第 1 步和第 2 步为您的数据填充正确的布局。如果您遇到困难,请发布一个新问题,以便社区有机会回答。如果您在此处的评论中链接到您的问题,我会看一下。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-14
    • 1970-01-01
    • 2020-02-06
    • 2015-01-19
    • 2014-06-13
    • 2021-12-21
    相关资源
    最近更新 更多