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

时间:2018-11-02 09:57:55

标签: java android performance android-recyclerview recycler-adapter

就性能而言,在Android应用中实现的更好选择是

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

假设我们需要创建

  • 评论,
  • 视频

  • 问题

    适配器中的

    列表以正确显示数据。每个列表属于不同的布局,因此我们有不同的TextViewsImageViews,依此类推。

    公共类FilesAdapter扩展了RecyclerView.Adapter {

    public static final int VIDEO_FILES_ADAPTER = 1; 公共静态最终诠释COMMENT_ADAPTER = 2; 公共静态最终诠释QUESTIONS_ADAPTER = 3;

    private int CURRENT_ADAPTER;

    私有列表videoFiles; 私人名单评论; 私人列表问题;

    boolean isForUser;

    public FilesAdapter(int currentAdapter,列出videoFiles,布尔值isForUser){     this.videoFiles = videoFiles;     this.CURRENT_ADAPTER = currentAdapter;     this.isForUser = isForUser; }

    public FilesAdapter(int currentAdapter,列出注释){     this.comments =评论;     this.CURRENT_ADAPTER = currentAdapter; }

    public FilesAdapter(int currentAdapter,列出问题,intunusedVariable){     this.questions =问题;     this.CURRENT_ADAPTER = currentAdapter; }

    @NonNull @Override public FilesViewHolder onCreateViewHolder(@NonNull ViewGroup parent,int viewType){     视图视图;     FilesViewHolder viewHolder;

    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持有人,int位置){

    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 个答案:

答案 0 :(得分:2)

无论布局和处理附加到单元格的复杂性如何,我建议您对每个列表使用单个适配器。

仅是一幅小图,以说明RecyclerView的主要操作: RecyclerView operation

根据RecyclerView.Adapter的documentation:当必须创建一个新的可重用单元格时(取决于屏幕上可以显示的单元格数量),将调用方法createViewHolder()。因此,执行if语句不会对性能产生太大影响。如果屏幕上显示10个单元格,则onCreateViewHolder()可能会再被调用10次。 问题可能出在每次RecyclerView需要显示新单元格时调用的onBindViewHolder()上。因此,如果您有一个包含100个元素的列表,并且您的用户跳到最底层,那么系统将比通常执行100个if语句。

此外,我认为如果您为每个列表创建单个适配器,您的代码将更易于维护。

我将得出这样的结论,即我不确定通过使用一个用于整个应用程序的适配器来降低系统效率。性能损失将不明显。我的意思是,最重要的一点是要确保您的代码易于理解,否则将来会浪费时间调试代码。我建议您通过在onCreateViewHolderonBindViewHolder(如果您感到好奇的话,可以更多)上设置断点以了解何时调用它们来测试RecyclerView生命周期。

希望对您有所帮助! 祝您好运,并与您的应用一起玩乐