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

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

问题描述

我是Android的新手,
我一直在做一个项目,在我的新闻Feed页面中,我试图包含一个模块化的Feed 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类: / p>

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不能被重新填充,原因是它一旦离开屏幕就会从视图hirarchy中删除,症状如下:
当向下滚动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一样有效的解决方案,或者使它们正常工作的一种方式,因为我有很多模块和充气它们都在每个项目,因为隐形会使我的应用程序慢。

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.

推荐答案

p>在你的 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()。当位置的项目获取 module_yes_no 布局时,返回0.当它获取 module_custom layout,return 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,将$ code> list_item_re_question 查看完整的 module_yes_no 布局。当 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()中,你只需检查 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天全站免登陆