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

时间:2018-03-30 17:32:31

标签: android android-recyclerview android-viewholder

我在聊天应用中使用了回收站视图,现在大家知道我们在聊天室中有两种不同的视图。

右视图:您发送的视频。

左视图:你收到的那个。

现在我通过使用一个布局项目实现了我想要的目标,在该项目中我使用了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个视图持有者?我应该使用它吗?

2 个答案:

答案 0 :(得分:3)

首先:在你的情况下,我不确定是否真的有必要使用两种视图类型。移动电话上的典型RecyclerView将一次显示7到10行,并且会产生更多,以便在需要时能够平滑滚动。与游戏应用相比,用户界面几乎没有什么可做的。但是你问为什么有人可能想要使用多种视图类型,所以这里有:

现在你膨胀的View中有50%会被设置为GONE,所以这就像是不断浪费CPU时间和(在移动设备上更糟)它正在耗尽电池电量不必要的。通过使用两种视图类型,可以避免这种情况(在某种程度上,我认为确定视图类型需要的能量较少)。

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

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

答案 1 :(得分: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:
        // ...
    }
}