Recyclerview:使用多种视图类型与为不同布局设置可见性

Recyclerview: using multiple viewtypes vs setting visibility for different layouts

我在聊天应用程序中使用回收站视图,现在你们都知道在聊天室中我们有 2 个不同的视图。

右视图:您发送的那个。

左视图:您收到的那个。

现在我设法通过使用一个布局项目实现了我想要的效果,在该项目中我使用了 2 个相对布局,一个布局用于右视图,另一个布局用于左视图。

为了知道要显示什么布局,我在 onBindViewholder 中做了这个:

onBindViewHolder(){
    if(/*I sent the message*/){
        right_layout.setVisibility(view.VISIBLE);
        left_layout.setVisibility(view.GONE);  
    }
    else {
        right_layout.setVisibility(view.GONE);
        left_layout.setVisibility(view.VISIBLE);
    }
}

我使用上面的方法没有任何问题。但我的问题是为什么其他人使用所谓的 多视图类型 的东西,他们在其中使用 2 个视图持有者?我应该改用它吗?

是的,您应该为每种类型的视图实现不同的 ViewHolder。这提供了一些优势,比如不必维护相关状态、整理布局,并且通常更容易推断将来是否包含额外的功能。

也很容易实现:

@Override                                                
public int getItemViewType(int position) {               
    Message message = messages.get(position);                    
    if (message instanceof ReceivedMessage) {
        return VIEWTYPE_RECEIVED;                                                                                                                    
    }                                                    
    if (message instanceof SentMessage) {                    
        return VIEWTYPE_SENT;                          
    }                                                    
    return 0;                                            
}

然后:

@Override                                                                                        
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {              
    LayoutInflater inflater = LayoutInflater.from(mContext);                                     
    switch (viewType) {                                                                          
        case VIEWTYPE_RECEIVED:                                                                                                                    
            View receivedView = inflater.inflate(R.layout.item_received, parent, false);           
            ReceivedViewHolder receivedViewHolder = new ReceivedViewHolder(receivedView);            
            return receievedViewHolder;                                                            
        case VIEWTYPE_SENT:                                                                    
            // ...                                                               
    }                                                                                                                                                                                                                                                                   
} 

最后:

@Override                                                                                        
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {                     

    switch (getItemViewType(position)) {                                                         
        case VIEWTYPE_RECEIEVED:
        // ...
    }
} 

首先:对于您的情况,我不确定是否真的有必要使用两种视图类型。移动设备 phone 上的典型 RecyclerView 一次会显示 7 到 10 行,它会生成更多行,以便在需要时能够平滑滚动。与游戏应用程序相比,几乎无事可做 UI-wise。但是你问为什么有人可能想要使用多种视图类型,所以这里是:

现在,您正在膨胀的 View 的 50% 将设置为 GONE,因此这就像是在不断浪费 CPU 时间,而且(在手机上更糟设备)它正在不必要地耗尽电池电量。通过使用两种视图类型,您可以避免这种情况(在某种程度上,我认为确定视图类型需要更少的精力)。

另一个原因是更好的性能可以带来更好的用户体验:RecyclerView 的开发是为了有效地处理项目列表。通过告诉它哪一行可以重复用于哪个列表位置,您可以充分利用它的回收算法。

从开发人员的角度来看,只要两种类型之间的差异不超过两三行代码,我就会保留您的方法。但是有些列表的区别更像是二十行代码。在这种情况下,使用不同的视图类型、布局文件和 ViewHolders 可以提高代码的可读性。