当前位置: 首页 > 知识库问答 >
问题:

不同列表和对象的多个适配器或一个适配器-代码性能

申屠宗清
2023-03-14

就性能而言,在android应用程序中实现的更好选项是什么:

  • 每个具有不同布局的对象列表都有多个适配器,
  • 处理不同数据的单个适配器

假设我们需要创建

>

  • 注释,
  • 视频,

    问题

    在适配器中列出以正确显示数据。每个列表属于不同的布局,这样我们就有了不同的TextViewsImageViews等等。

    公共类FilesAdapter扩展RecyclerView.Adapter{

    public static final int VIDEO_FILES_ADAPTER=1;public static final int COMMENT_ADAPTER=2;public static final int QUESTIONS_ADAPTER=3;

    专用int current_adapter;

    私人名单录像;私人名单评论;私人清单问题;

    布尔ISforUser;

    public FilesAdapter(int currentAdapter,List videoFiles,boolean isForUser){this.videoFiles=videoFiles;this.current_adapter=currentAdapter;this.isForUser=isForUser;}

    public FilesAdapter(int currentAdapter,List comments){This.comments=comments;This.Current_Adapter=currentAdapter;}

    public FilesAdapter(int currentAdapter,List questions,int unusedVariable){This.questions=问题;This.Current_Adapter=currentAdapter;}

    @nonnull@override public FilesViewWholder OnCreateViewWholder(@nonnull ViewGroup parent,int viewType){View View;FilesViewWholder ViewWholder;

    switch(CURRENT_ADAPTER){
    
        case VIDEO_FILES_ADAPTER:
    
            if(isForUser){
                view = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_layout_file_user, parent, false);
            }else{
                view = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_layout_file_main, parent, false);
            }
    
            viewHolder = new FilesViewHolder(VIDEO_FILES_ADAPTER, view, isForUser);
    
            return viewHolder;
    
        case COMMENT_ADAPTER:
            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_layout_comment, parent, false);
            viewHolder = new FilesViewHolder(COMMENT_ADAPTER, view, false);
    
            return viewHolder;
    
        case QUESTIONS_ADAPTER:
            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_layout_question, parent, false);
            viewHolder = new FilesViewHolder(QUESTIONS_ADAPTER, view, false);
    
            return viewHolder;
    }
    
    return null;
    

    }

    @override public void onBindViewHolder(@nonnull FilesViewHolder holder,int position){

    switch (CURRENT_ADAPTER){
    
        case VIDEO_FILES_ADAPTER:
            holder.videoTitle.setText(videoFiles.get(position).getFileName());
            holder.videoDescription.setText(videoFiles.get(position).getFileDescription());
            if(isForUser){
                holder.videoDate.setText(videoFiles.get(position).getFileCreatedAt());
            }else{
                holder.videoUser.setText(videoFiles.get(position).getUsername());
            }
    
            holder.videoCount.setText(videoFiles.get(position).getWatched());
            break;
    
        case COMMENT_ADAPTER:
            holder.commentComment.setText(comments.get(position).getComment());
            holder.commentUsername.setText(comments.get(position).getUsername());
            holder.commentCreatedAt.setText(comments.get(position).getCreatedAt());
            break;
    
        case QUESTIONS_ADAPTER:
            holder.questionTitle.setText(questions.get(position).getProviderUsername());
            break;
    }
    

    }

    @override public int getItemCount(){

    switch (CURRENT_ADAPTER){
        case VIDEO_FILES_ADAPTER:
            return videoFiles.size();
        case COMMENT_ADAPTER:
            return comments.size();
        case QUESTIONS_ADAPTER:
            return questions.size();
    }
    
    return 0;
    

    }

    公共静态类FilesViewHolder扩展了RecyclerView.ViewHolder{

    private static final int VIDEO_FILES_ADAPTER = 1;
    private static final int COMMENT_ADAPTER = 2;
    private static final int QUESTIONS_ADAPTER = 3;
    
    private int CURRENT_ADAPTER;
    
    // Related to audio file class
    public TextView videoTitle, videoDescription, videoDate, videoUser, videoCount;
    
    // Related to comment class
    private TextView commentComment, commentUsername, commentCreatedAt;
    
    // Related to subscription class
    private TextView questionTitle;
    
    
    // @param isForUser applies only if CURRENT_ADAPTER == VIDEO_FILES_ADAPTER
    public FilesViewHolder(int CURRENT_ADAPTER, View itemView, boolean isForUser) {
        super(itemView);
    
        switch(CURRENT_ADAPTER){
    
            case VIDEO_FILES_ADAPTER:
    
                videoTitle = itemView.findViewById(R.id.tV_title);
                videoDescription = itemView.findViewById(R.id.tV_description);
                if(isForUser){
                    videoDate = itemView.findViewById(R.id.tV_date);
                }else{
                    videoUser = itemView.findViewById(R.id.tV_username);
                }
                videoCount = itemView.findViewById(R.id.tV_watched);
    
                break;
    
            case COMMENT_ADAPTER:
    
                commentComment = itemView.findViewById(R.id.tV_comment);
                commentUsername = itemView.findViewById(R.id.tV_comment_username);
                commentCreatedAt = itemView.findViewById(R.id.tV_comment_created_at);
    
                break;
    
            case QUESTIONS_ADAPTER:
    
                questionTitle = itemView.findViewById(R.id.tV_question);
    
                break;
        }
    
    }
    

    }}

    还有另一种方法。每个列表都有一个适配器,例如:

    public class CommentAdapter extends RecyclerView.Adapter<CommentAdapter.CommentViewHolder>{
    
    private List<Comment> commentList;
    
    public CommentAdapter(List<Comment> comments){
        this.commentList = comments;
    }
    
    public static class CommentViewHolder extends RecyclerView.ViewHolder{
    
        private TextView comment, username, createdAt;
    
        public CommentViewHolder(View itemView) {
            super(itemView);
    
            comment = itemView.findViewById(R.id.tV_comment);
            username = itemView.findViewById(R.id.tV_comment_username);
            createdAt = itemView.findViewById(R.id.tV_comment_created_at);
        }
    }
    
    @NonNull
    @Override
    public CommentViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_layout_comment, parent, false);
    
        return new CommentViewHolder(view);
    }
    
    @Override
    public void onBindViewHolder(@NonNull CommentViewHolder holder, int position) {
        holder.comment.setText(commentList.get(position).getComment());
        holder.username.setText(commentList.get(position).getUsername());
        holder.createdAt.setText(commentList.get(position).getCreatedAt());
    }
    
    @Override
    public int getItemCount() {
        return commentList.size();
    }
    

    }

    我的问题是,就表现而言,实施什么会更好?如果我决定为不同的列表实现一个适配器,是否会有任何明显的延迟或性能补丁?

  • 共有1个答案

    卓正业
    2023-03-14

    无论布局和单元格的处理是否复杂,我都建议您为每个列表使用单个适配器。

    仅用一张小图来说明RecyclerView的主要操作:RecyclerView操作

    根据RecyclerView.Adapter的文档:当必须创建新的可重用单元格(取决于屏幕上可以显示的单元格的数量)时,将调用createViewWholder()方法。因此执行if语句不会对性能产生太大影响。如果屏幕上显示了10个单元格,则OnCreateViewWholder()可以再调用10次。问题可能出在OnBindViewWholder()上,每次RecyclerView需要显示新单元格时都会调用它。因此,如果您有一个100个元素的列表,而您的用户将其抛到底部,那么系统将比通常执行100个if语句。

    而且,我认为,如果为每个列表制作单个适配器,您的代码将更易维护。

    我将以这样一个事实作为结论,即我并不确定整个应用程序使用一个适配器的方式会降低系统的效率。业绩损失不会明显。我的意思是,最重要的一点是确保您的代码易于理解,否则您将在将来调试代码时浪费时间。我建议您通过在OnCreateViewWholderOnBindViewWholder上放置断点来测试RecolyerView生命周期(如果您有兴趣的话,还有更多),以了解何时调用它们。

    希望对你有帮助!祝你好运,玩得开心

     类似资料:
    • 我正在寻找在Android中使用列表适配器和Recyview适配器的区别。关于性能的任何不同,使用它们的利弊。

    • 我有一个聊天屏幕,我可以与其他用户聊天,我发送聊天数据(消息,时间和发件人通过列表)到RecycerAdapter,用数据填充聊天视图。现在我有一个列表,其中有不同布局的数据。像这样 下面是我的方法,从这里我将第二个arraylist调用到RecycerAdapter中 与上述方法一样,当我尝试通过时,它会从屏幕上删除所有消息,并显示我的图像数据。但我想保留所有的消息,并通过新的列表显示数据图像

    • 我试图在我的RecycerViewdAdapter类中创建cv应用程序,我想传递列表和一个模型类,我已经传递了第二个虚拟数据。我正在跟踪这个stackoverflow链接,两个ArrayList,一个RecycerView适配器 我想实现这个ui 第二张当前截图 在educution_item下面。 subjectList下面

    • Android适配器是否使用适配器设计模式?GoF设计模式书将适配器设计模式描述为 适配器模式将一个类的接口转换为客户机期望的另一个接口。Adapter允许由于接口不兼容而无法正常工作的类一起工作。 适配器实现了一个目标接口,客户机使用(预期)一个适配器,适配器将客户机发出的所有请求委托给该适配器。 我知道它的理论和现实世界中的模式适配器接口看起来并不完全像它,但我仍然无法弄清楚android适配

    • 将 HTTP 参数转换成一个函数参数的过程是一个典型适配过程,执行这个过程的对象被称为适配器了。 Nutz.Mvc 提供了 org.nutz.mvc.HttpAdaptor 接口,隔离了这种行为。 在每一个入口函数上,你都可以通过注解 @AdaptBy 来声明如何适配 HTTP 参数。当然,你 没必要在每一个入口函数上都声明,在子模块类上声明,或者在整个应用的主模块上声明均可。 如何使用适配器?