【问题标题】:Recyclerview: using multiple viewtypes vs setting visibility for different layoutsRecyclerview:使用多种视图类型与为不同布局设置可见性
【发布时间】:2018-03-31 19:21:38
【问题描述】:

我在聊天应用程序中使用回收站视图,现在大家都知道,在聊天室中我们有 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 个视图持有者的称为 multiple view types 的东西?我应该改用它吗?

【问题讨论】:

标签: android android-recyclerview android-viewholder


【解决方案1】:

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

现在,您正在充气的 Views 中有 50% 将设置为 GONE,因此这就像在持续浪费 CPU 时间并且(在移动设备上更糟糕)它会不必要地耗尽电池。通过使用两种视图类型,您可以避免这种情况(在某种程度上,我认为确定视图类型需要更少的能量)。

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

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

【讨论】:

  • 我使用一个项目视图,它有太多嵌套的相对布局,一个用于右消息,一个用于左消息,另一个用于消息之间的日期......在这种情况下你怎么看?
  • @svi.data - 在这种情况下,我更喜欢两种视图类型。它更容易开发,更容易维护,我希望它对电池也更容易。
  • 也就是说recyclerview的layout item的复杂度会影响它的滚动吗?
  • @svi.data - 我认为确实如此:每次滚动时,如果 RecyclerView 需要特定类型的其他视图,它都会调用 onCreateViewHolder。如果它在缓存中有一些(因为它们不再附加到窗口并且可以回收),那么它只会调用 onBindViewHolder。在这种情况下,您不必切换可见性(这意味着重新计算布局),而只需填写您的数据。这对性能会更好
  • @svi.data - “recyclerview 的布局项的复杂性是否会影响其滚动”当然是的,只要涉及到滚动时发生的绘图
【解决方案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:
        // ...
    }
} 

【讨论】:

  • 在 getItemViewType() 中我们可以访问 pojo 类的详细信息吗?还有一件事是这种方式对性能更好吗?
  • 整理布局是什么意思?
  • 如何在android中另外显示日期时间
猜你喜欢
  • 2020-12-05
  • 1970-01-01
  • 2020-09-12
  • 1970-01-01
  • 2014-02-22
  • 1970-01-01
  • 2021-12-27
  • 2017-11-07
  • 1970-01-01
相关资源
最近更新 更多