Android 有没有办法在RecyclerView中使用ViewStub?

Android 有没有办法在RecyclerView中使用ViewStub?,android,data-binding,android-recyclerview,android-viewholder,viewstub,Android,Data Binding,Android Recyclerview,Android Viewholder,Viewstub,我是android新手, 我一直在做一个项目,在我的新闻提要页面中,我试图包括一个模块化的提要回收视图,它显示了一个不同答案形式的问题,根据问题类型而变化。到目前为止,我所采用的方法是使用include并在需要时将表单显示出来。最近,由于我添加了更多的模块,应用程序开始明显减速,所以我尝试实现ViewStubs 这是我的RecyclerView适配器: public class ReQuestionAdapter extends RecyclerView.Adapter<FeedItem&

我是android新手, 我一直在做一个项目,在我的新闻提要页面中,我试图包括一个模块化的提要回收视图,它显示了一个不同答案形式的问题,根据问题类型而变化。到目前为止,我所采用的方法是使用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();
}
}
现在的问题是,包含特定布局的ViewStub无法用新布局重新展开,原因是它一离开屏幕就从视图HIRACHY中删除,症状如下: 向下滚动RecyclerView时,填充屏幕的第一个列表项工作正常,但当前一个列表项离开屏幕时加载的其他列表项会导致FeedItem绑定带来一个NullPointerException。(在列表项布局中找不到它)

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

在您的
bindQuestion()
方法中,您引用了两种不同的布局进行充气,所以本质上有两种不同的视图类型

适配器视图有一种有效的方法来处理这个内置的问题

首先重写
getItemViewType()
。当位于
位置的项获得
模块\u yes\u no
布局时,返回0。当它获得
module\u custom
布局时,返回1

然后在
onCreateViewHolder()
中,当
viewType
参数为0时,用
模块的“是”和“否”布局将
列表项的问题
视图充气。当
viewType
==1时,对视图的
模块进行充气

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

您甚至可以有两个子类
FeedItem
,一个用于
module\u yes\u no
,另一个用于
module\u custom
,因此在
onBindViewHolder()
中,您只需检查
ViewHolder
的类并相应地进行分支


这将有助于提高应用程序的性能。

Thx很多,因此我了解到,使用两个不同的FeedItem类,recyclerview将自己知道哪些部分需要保留,哪些部分不同?或者它会根据请求创建两个重复的循环视图吗?这两个
FeedItem
类只是为了您的利益
RecyclerView
通过覆盖
getItemViewType()
知道要为您回收哪个视图。假设项目20是一个yes\u no。如果您设置了
getItemViewType()
为yes\u no项目返回0,那么当用户滚动到项目20时,
RecyclerView
调用您的
getItemViewType()
,位置==20。它接收到0,并说,“哦,看,我这里有一个用于回收的type 0视图”,然后将该视图传递给
onBindViewHolder()
。有意义吗?如果
RecyclerView
没有可供回收的视图,它将调用
onCreateViewHolder()
viewType
==0,以便您知道要充气的视图类型和要创建的视图支架类型。明白了,非常感谢您,先生,您真的帮助了我:P我还想知道我是否应该使用问题显示布局和答案表单布局,并将它们一起包含到不同的布局中,我将使用它们进行充气:@AJW是的,您应该覆盖
getItemViewType()
。它非常简单:步骤1:覆盖
getItemViewType()
,因此它为小数据返回0,为大数据返回1。步骤2:通过打开
viewType
参数的开关覆盖
onCreateViewHolder()
:0为小版面充气,1为展开版面充气。步骤3:在
onBindViewHolder()
中,您的视图持有者参数将已经根据步骤1和步骤2为您的数据扩展了正确的布局。如果你陷入困境,发布一个新问题,让社区有机会回答。如果你在这里的评论中链接到你的问题,我会看一看。
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;
        }
    }
}