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

D. *_* B. 3 java performance android android-recyclerview

在性能方面,在 android 应用程序中实现什么是更好的选择:

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

假设我们需要创建

  • 注释,
  • 视频,

  • 问题

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

    公共类 FilesAdapter 扩展 RecyclerView.Adapter {

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

    私人整数 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 usedVariable){ this.questions = 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;
    
    Run Code Online (Sandbox Code Playgroud)

    }

    @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;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    }

    @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;
    
    Run Code Online (Sandbox Code Playgroud)

    }

    公共静态类 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;
        }
    
    }
    
    Run Code Online (Sandbox Code Playgroud)

    } }

还有另一种方法可以做到这一点。每个列表的单个适配器,例如:

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();
}
Run Code Online (Sandbox Code Playgroud)

}

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

Gui*_*lin 7

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

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

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

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

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

希望对你有帮助!祝你好运,享受你的应用程序的乐趣