有没有办法在 RecyclerView 中使用 ViewStub? [英] Is there a way to use a ViewStub inside a RecyclerView?

查看:45
本文介绍了有没有办法在 RecyclerView 中使用 ViewStub?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

i'm new to android, I've been working on a project, and in my news feeds page, I'm trying to include a modular feed RecyclerView, which shows a question with different answer forms, varrying according to the Question type. The way I was doing it so far was by using the include and turning the forms visible when needed. recently since i added more modules, the app started to slowdown segnificantly, so i'm trying to implement ViewStubs.

这是我的 RecyclerView 适配器:

This is my RecyclerView adapter:

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 类:

And this is the ViewHolder class for the adapter:

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.(在列表项布局中找不到它).

Now, the problem is that the ViewStub which contains a certain layout, cannot be reinflated with a new one, the reason for that is that it gets removed from the view hirarchy as soon as it leaves the screen, the symptoms: When scrolling down the RecyclerView, the first list items that fill the screen are working perfect, but others to load when the previous leave the screen cause the FeedItem binding to bring a NullPointerException. (It canno't find it in the list item layout).

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

I'm looking for a solution as efficiant as ViewStubs, or a way to make them work properly, since I got many modules and inflating them all in each item as invisible would make my app slow.

推荐答案

在你的 bindQuestion() 方法中,你引用了两个不同的布局来膨胀,所以本质上你有两种不同的视图类型.

In your bindQuestion() method you are referencing two different layouts to inflate, so in essence you have two different view types.

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

Adapter views have an efficient way way to handle this built right in.

首先覆盖 getItemViewType().当position的item得到module_yes_no布局时,返回0.当得到module_custom布局时,返回1.

Start by overriding getItemViewType(). When the item at position gets the module_yes_no layout, return 0. When it gets the module_custom layout, return 1.

然后在onCreateViewHolder()中,当viewType参数为0时,用module_yes_no完成一个list_item_re_question视图代码>布局.当 viewType == 1 时,扩充视图的 module_custom 版本.

Then in onCreateViewHolder(), when the viewType parameter is 0, inflate a list_item_re_question view complete with the module_yes_no layout. When viewType == 1, inflate the module_custom version of the view.

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

Now when you get a view in onBindViewHolder(), it will already have the correct subview, so you proceed to fill out that view as needed. By using getItemViewType(), the RecyclerView is working with you to recycle the exact view you need.

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

You can even have two FeedItem subclasses, one for module_yes_no and one for module_custom, so in onBindViewHolder(), you just check the class of the ViewHolder and branch accordingly.

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

That should help improve the performance of your app.

这篇关于有没有办法在 RecyclerView 中使用 ViewStub?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆