0

我想創建一個類似於WhatsApp的視圖。我收到的數據是存儲在對象的ArrayList中的一組對話。該對象具有消息的所有屬性,即, sendersID,receiversID,MessageID,消息,時間戳等。我已經能夠創建基於sendersID == myID條件膨脹的發送者/接收者視圖。在沒有數據的情況下在RecyclerView/ListView中創建視圖

我面臨的問題是用什麼條件來膨脹datelayout。我不想在我的arrayList中添加新數據來檢測日期更改。是否可以在不操縱列表數據的情況下獲取視圖?我已經完成了頁眉和頁腳視圖,這很容易檢測到第一個/最後一個項目。但是從適配器檢測日期變化並從那裏創建視圖看起來是一個挑戰。爲了擴大同樣的想法,我計劃在我的List/Recycler中添加不同種類的視圖,並且會喜歡解決這類問題的解決方案。

+0

如果你喜歡做有風險的,在使用測試版的產品沒有問題,你可以看看機器人會數據綁定功能 - 這將幫助你更新你的看法。 我想說,使用RecyclerView.Adapter將不同的佈局膨脹爲'sectionheader'並不難,只需在正確的條件下設置並檢查Adapters方法中的viewType即可。 – yennsarah

+0

只需在更新數據模型後調用適配器上的notifyDataSetChanged即可實現該功能,那麼問題是什麼? – Nanoc

+0

問題是關於基於某些條件(如檢測和顯示日期更改)創建額外的視圖,其數據在arrayList中不可用。數組列表僅包含與對話時間戳的對話。你可以參考相同的whatsapp。 – Roadblock

回答

1

注意:爲清楚起見,我將把您的數據對象稱爲「消息」。

您可以用兩種方法之一處理日期TextView。無論哪種方法都行得通,儘管我的傾向是#2的效果更好一些。

1.日期TextView是一個獨立的項目,除了收集消息之外,適配器還需要考慮它們。

2.日期TextView包含在表示消息的項目(例如,它是在該行的佈局XML),你只需要確定哪些行使其可見,哪些沒有。


適配器端更有趣一點。根據上面採用的方法,您需要修改由getCount()ListView)或getItemCount()RecyclerView)報告的項目數,或者您需要跟蹤哪些項目具有其他顯示邏輯。當然,您可能需要預先處理集合(如果可能,在後臺進行),以發現並存儲這些額外的信息。以下可能性是我過去使用過的所有東西:

A.修改您的數據結構以跟蹤日期及其在數據集中的位置;它可能僅僅是封裝在某個包裝類中的兩個集合。您的數據提取邏輯可能應該返回此結構,而不是收集消息。這可以與以上的#1numItems = numMessages + numDates)或#2numItems = numMessages)一起使用。

B.不要修改您的數據結構,但在消息中添加一個可變字段(boolean)。您的預處理只是標記哪些消息需要顯示日期。這幾乎只適用於#2以上。

C.如果日期是真正「分離」兩個消息的唯一事情,那麼可以讓您的適配器知道數據的「部分」,並且您只需在開始(或結束時顯示日期,由你決定)。你並不需要修改您的收藏要做到這一點,例如:

List<Message> items; 
List<AdapterSection> sections; 

static class AdapterSection { 
    int start; // an index of the items list, e.g. in the range [0, items.size()) 
    int count; // how many items in the section 
} 

切片適配器可以同#1#以上2工作。如果您正在使用#1,那麼您可以讓每個部分報告其自己的大小(日期加1),並且僅對部分大小進行求和。這種方法的主要缺點是在數據發生變化時使這些部分與您的數據保持同步。

我會打電話D的最後一個選項根本不需要任何預處理。當您的適配器綁定某個項目的數據時,您可以查看下一個項目並確定是否需要顯示日期。這隻適用於#2以上。下面是基於RecyclerView適配器上一些僞代碼:

@Override 
public void onBindViewHolder(MessageViewHolder holder, int position) { 
    Message item = getItem(position); 
    // bind stuff to views ... 

    if (position < getItemCount() - 1) { 
     Message nextItem = getItem(position + 1); 
     if (hasDifferentDates(item, nextItem) { 
      // show TextView, bind date ... 
     } else { 
      // hide TextView 
     } 
    } 
} 
相關問題