android - 有没有办法在 RecyclerView 中使用 ViewStub?

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

我是安卓新手, 我一直在做一个项目,在我的新闻提要页面中,我试图包含一个模块化的提要 RecyclerView,它显示一个具有不同答案形式的问题,根据问题类型而变化。到目前为止,我的做法是使用 include 并在需要时将表单变为可见。最近,由于我添加了更多模块,应用程序开始明显变慢,所以我正在尝试实现 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 无法用新布局重新填充,原因是它一离开屏幕就会从 View 层次结构中删除,症状: 向下滚动 RecyclerView 时,第一个填满屏幕的列表项运行良好,但其他列表项在前一个离开屏幕时加载会导致 FeedItem 绑定(bind)带来 NullPointerException。 (在列表项布局中找不到它)。

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

最佳答案

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

适配器 View 有一种有效的方式来处理这个内置的问题。

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

然后在 onCreateViewHolder() 中,当 viewType 参数为 0 时,使用 module_yes_nolist_item_re_question View 布局。当 viewType == 1 时,膨胀 View 的 module_custom 版本。

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

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

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

关于android - 有没有办法在 RecyclerView 中使用 ViewStub?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31609215/

相关文章:

wpf - 不反射(reflect)在 UI 上的任务更新数据绑定(bind) OC

c# - 与 UI 怪癖的两种方式绑定(bind)

android - undefined reference 错误,无法创建共享库

android - 列表项引导内容可以在 Jetpack Compose Material3 中顶部对齐吗?

Android VpnService - 如何检查 VpnService 是否已启动?

java - Android 5.0 - 向 RecyclerView 添加页眉/页脚

java - 是否有任何类可以处理 RecyclerView ViewHolders 的数据绑定(bind)?

android - 在 actionbarsherlock 的左侧显示菜单项

wpf - 如何将命令附加到 CheckBox 的选中和取消选中?

android - 一些 Youtube 视频显示在 RecyclerView 中