Android View的background和padding


版權聲明:本文為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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM