版權聲明:本文為xing_star原創文章,轉載請註明出處! 本文同步自http://javaexception.com/archives/181 最近在做一個需求,是對im聊天消息設置氣泡背景,之前呢,設計師沒有特別遵循一定的設計規範,導致,氣泡背景有的是.9的圖片,有的是自己用xml畫出來的背景 ...
版權聲明:本文為xing_star原創文章,轉載請註明出處!
本文同步自http://javaexception.com/archives/181
最近在做一個需求,是對im聊天消息設置氣泡背景,之前呢,設計師沒有特別遵循一定的設計規範,導致,氣泡背景有的是.9的圖片,有的是自己用xml畫出來的背景。這樣在給聊天消息設置背景的時候出現了不少的問題。
問題場景回溯:
設置背景,我們常用的Api是setBackgroundResource。最開始考慮的比較簡單,每條消息都只用setBackgroundResource
接著就碰到了第一個問題,有的消息用的是.9圖,有的是xml,整體的效果看起來不是很協調,也就是消息的間隔有大有小,看起來特別醜。
這裡我們想到了一個辦法,我們需要讓不同的氣泡上的文本內容看起來間隔差不多,考慮的是設置padding,而不是使用background裡面的間隔。對於每一條消息,根據它是什麼樣的氣泡,決定設置padding值的參數。
大致的代碼是
setBgContainerPadding(bgContainer, SystemUtils.dip2px(10), SystemUtils.dip2px(4), SystemUtils.dip2px(18), SystemUtils.dip2px(4)); bgContainer.setBackgroundResource(R.drawable.xxx);//設置背景
然後我就掉入了第二個坑中,發現設置了padding後,效果沒變化,一時之間找不到原因,很是惱火。只好先放棄這塊工作,去忙其他的了,不知道過了多久,靈感來了,想到了調整padding和background的先後順序。
bgContainer.setBackgroundResource(R.drawable.xxx);//設置背景 setBgContainerPadding(bgContainer, SystemUtils.dip2px(10), SystemUtils.dip2px(4), SystemUtils.dip2px(18), SystemUtils.dip2px(4));
一定得是先設置背景,在設置padding值。不能是先設置padding,再設置背景。https://www.jianshu.com/p/4432b19ec6cd 這篇文章深入分析了下原因,對於這塊推薦看這篇文章。
到這裡大致的效果就比較接近了,但是還是有些item的氣泡背景包裹的內容間隔有問題,感覺是view的復用機制(RecyclerView,ListView的item)在作怪。(此外設置padding值的時候,不要使用view的getPaddingLeft()這樣的方法,全部給定具體的數值,從源頭上避免復用機制)
於是再次修改代碼,代碼覆蓋各種case,相當於每個itemView都手動設置一遍,padding,氣泡背景這塊不使用view的復用。
完整的處理氣泡的代碼如下:
private void setBackground(View bgContainer, int position) { Conversation conversation = conversationList.get(position); if (position == 0) { if (conversation.getIsSend() == Conversation.SEND_RECEIVE_TYPE_SEND) { bgContainer.setBackgroundResource(R.drawable.balloon_outgoing_normal);//marginLeft marginRight 10dp setBgContainerPadding(bgContainer, SystemUtils.dip2px(10), SystemUtils.dip2px(4), SystemUtils.dip2px(18), SystemUtils.dip2px(4)); } else { bgContainer.setBackgroundResource(R.drawable.balloon_incoming_normal); setBgContainerPadding(bgContainer, SystemUtils.dip2px(18), SystemUtils.dip2px(4), SystemUtils.dip2px(10), SystemUtils.dip2px(4)); } setBgContainerMargin(bgContainer, SystemUtils.dip2px(10), 0, SystemUtils.dip2px(10), 0); } else if (isDifferentTypePre(position)) { if (conversation.getIsSend() == Conversation.SEND_RECEIVE_TYPE_SEND) { bgContainer.setBackgroundResource(R.drawable.balloon_outgoing_normal); setBgContainerPadding(bgContainer, SystemUtils.dip2px(10), SystemUtils.dip2px(4), SystemUtils.dip2px(18), SystemUtils.dip2px(4)); } else { bgContainer.setBackgroundResource(R.drawable.balloon_incoming_normal); setBgContainerPadding(bgContainer, SystemUtils.dip2px(18), SystemUtils.dip2px(4), SystemUtils.dip2px(10), SystemUtils.dip2px(4)); } setBgContainerMargin(bgContainer, SystemUtils.dip2px(10), 0, SystemUtils.dip2px(10), 0); } else { lineHeader.setVisibility(View.GONE); if (conversation.getIsSend() == Conversation.SEND_RECEIVE_TYPE_SEND) { bgContainer.setBackgroundResource(R.drawable.green_msg); setBgContainerMargin(bgContainer, 0, SystemUtils.dip2px(0.5f), SystemUtils.dip2px(17), SystemUtils.dip2px(0.5f)); } else { bgContainer.setBackgroundResource(R.drawable.white_msg); setBgContainerMargin(bgContainer, SystemUtils.dip2px(17), SystemUtils.dip2px(0.5f), 0, SystemUtils.dip2px(0.5f)); } setBgContainerPadding(bgContainer, SystemUtils.dip2px(10), SystemUtils.dip2px(4), SystemUtils.dip2px(10), SystemUtils.dip2px(4)); } }
這塊的代碼,也是調整了好久才完善好,我覺得這塊還是很值得總結的。希望對大家有用。
總結:
做這塊的工作,碰到了2個問題,設置background跟padding的先後順序,一定得是先設置background再設置padding;第二個是要考慮到view的復用,但是對於氣泡,特定的背景padding值而言,要用代碼的方式禁用掉view的復用效果。最終的消息聊天氣泡效果很讓我滿意,整個頁面的佈局效果也很好,仿的特別成功。
參考資料:
https://www.jianshu.com/p/4432b19ec6cd