1d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang/* 2d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang * Copyright (C) 2016 The Android Open Source Project 3d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang * 4d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang * Licensed under the Apache License, Version 2.0 (the "License"); 5d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang * you may not use this file except in compliance with the License. 6d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang * You may obtain a copy of the License at 7d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang * 8d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang * http://www.apache.org/licenses/LICENSE-2.0 9d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang * 10d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang * Unless required by applicable law or agreed to in writing, software 11d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang * distributed under the License is distributed on an "AS IS" BASIS, 12d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang * See the License for the specific language governing permissions and 14d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang * limitations under the License. 15d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang */ 16d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 17d51affa86a445be576c95785dc8a638e5eb0d128Noah Wangpackage com.android.settings.display; 18d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 19d51affa86a445be576c95785dc8a638e5eb0d128Noah Wangimport android.content.Context; 20d51affa86a445be576c95785dc8a638e5eb0d128Noah Wangimport android.content.res.Resources; 21d51affa86a445be576c95785dc8a638e5eb0d128Noah Wangimport android.content.res.TypedArray; 22d51affa86a445be576c95785dc8a638e5eb0d128Noah Wangimport android.graphics.PorterDuff; 23d51affa86a445be576c95785dc8a638e5eb0d128Noah Wangimport android.graphics.drawable.Drawable; 24d51affa86a445be576c95785dc8a638e5eb0d128Noah Wangimport android.util.AttributeSet; 25d51affa86a445be576c95785dc8a638e5eb0d128Noah Wangimport android.view.Gravity; 26d51affa86a445be576c95785dc8a638e5eb0d128Noah Wangimport android.view.LayoutInflater; 27d51affa86a445be576c95785dc8a638e5eb0d128Noah Wangimport android.view.View; 28d51affa86a445be576c95785dc8a638e5eb0d128Noah Wangimport android.view.ViewGroup; 29d51affa86a445be576c95785dc8a638e5eb0d128Noah Wangimport android.widget.FrameLayout; 30d51affa86a445be576c95785dc8a638e5eb0d128Noah Wangimport android.widget.LinearLayout; 31d51affa86a445be576c95785dc8a638e5eb0d128Noah Wangimport android.widget.TextView; 32d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 33d51affa86a445be576c95785dc8a638e5eb0d128Noah Wangimport com.android.settings.R; 34d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 35d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang/** 36d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang * The view for a single entry in a conversation. This is a simplified version of 37d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang * com.android.messaging.ui.conversation.ConversationMessageView class. 38d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang */ 39d51affa86a445be576c95785dc8a638e5eb0d128Noah Wangpublic class ConversationMessageView extends FrameLayout { 40d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang private final boolean mIncoming; 41d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang private final CharSequence mMessageText; 42d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang private final CharSequence mTimestampText; 43d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang private final CharSequence mIconText; 44d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang private final int mIconTextColor; 45d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang private final int mIconBackgroundColor; 46d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 47d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang private LinearLayout mMessageBubble; 48d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang private ViewGroup mMessageTextAndInfoView; 49d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang private TextView mMessageTextView; 50d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang private TextView mStatusTextView; 51d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang private TextView mContactIconView; 52d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 53d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang public ConversationMessageView(Context context) { 54d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang this(context, null); 55d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang } 56d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 57d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang public ConversationMessageView(final Context context, final AttributeSet attrs) { 58d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang this(context, attrs, 0); 59d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang } 60d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 61d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang public ConversationMessageView(Context context, AttributeSet attrs, int defStyleAttr) { 62d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang this(context, attrs, defStyleAttr, 0); 63d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang } 64d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 65d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang public ConversationMessageView(Context context, AttributeSet attrs, int defStyleAttr, 66d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang int defStyleRes) { 67d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang super(context, attrs, defStyleAttr, defStyleRes); 68d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 69d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final TypedArray a = context.obtainStyledAttributes(attrs, 70d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang R.styleable.ConversationMessageView); 71d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 72d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang mIncoming = a.getBoolean(R.styleable.ConversationMessageView_incoming, true); 73d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang mMessageText = a.getString(R.styleable.ConversationMessageView_messageText); 74d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang mTimestampText = a.getString(R.styleable.ConversationMessageView_timestampText); 75d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang mIconText = a.getString(R.styleable.ConversationMessageView_iconText); 76d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang mIconTextColor = a.getColor(R.styleable.ConversationMessageView_iconTextColor, 0); 77d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang mIconBackgroundColor = a.getColor(R.styleable.ConversationMessageView_iconBackgroundColor, 78d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 0); 79d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 80d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang LayoutInflater.from(context).inflate(R.layout.conversation_message_icon, this); 81d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang LayoutInflater.from(context).inflate(R.layout.conversation_message_content, this); 82d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang } 83d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 84d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang @Override 85d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang protected void onFinishInflate() { 86d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang mMessageBubble = (LinearLayout) findViewById(R.id.message_content); 87d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang mMessageTextAndInfoView = (ViewGroup) findViewById(R.id.message_text_and_info); 88d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang mMessageTextView = (TextView) findViewById(R.id.message_text); 89d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang mStatusTextView = (TextView) findViewById(R.id.message_status); 90d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang mContactIconView = (TextView) findViewById(R.id.conversation_icon); 91d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang updateViewContent(); 92d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang } 93d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 94d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang @Override 95d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) { 96d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang updateViewAppearance(); 97d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 98d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final int horizontalSpace = MeasureSpec.getSize(widthMeasureSpec); 99d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 100d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final int unspecifiedMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); 10135a95617fd467b823a6c1c66f0f5d9651752f2efNoah Wang int iconMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); 102d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 103d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang mContactIconView.measure(iconMeasureSpec, iconMeasureSpec); 10435a95617fd467b823a6c1c66f0f5d9651752f2efNoah Wang iconMeasureSpec = MeasureSpec.makeMeasureSpec( 10535a95617fd467b823a6c1c66f0f5d9651752f2efNoah Wang Math.max(mContactIconView.getMeasuredWidth(), mContactIconView.getMeasuredHeight()), 10635a95617fd467b823a6c1c66f0f5d9651752f2efNoah Wang MeasureSpec.EXACTLY); 10735a95617fd467b823a6c1c66f0f5d9651752f2efNoah Wang mContactIconView.measure(iconMeasureSpec, iconMeasureSpec); 108d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 109d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final int arrowWidth = 110d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang getResources().getDimensionPixelSize(R.dimen.message_bubble_arrow_width); 111d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 112d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang // We need to subtract contact icon width twice from the horizontal space to get 113d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang // the max leftover space because we want the message bubble to extend no further than the 114d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang // starting position of the message bubble in the opposite direction. 115d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final int maxLeftoverSpace = horizontalSpace - mContactIconView.getMeasuredWidth() * 2 116d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang - arrowWidth - getPaddingLeft() - getPaddingRight(); 117d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final int messageContentWidthMeasureSpec = MeasureSpec.makeMeasureSpec(maxLeftoverSpace, 118d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang MeasureSpec.AT_MOST); 119d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 120d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang mMessageBubble.measure(messageContentWidthMeasureSpec, unspecifiedMeasureSpec); 121d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 122d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final int maxHeight = Math.max(mContactIconView.getMeasuredHeight(), 123d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang mMessageBubble.getMeasuredHeight()); 124d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang setMeasuredDimension(horizontalSpace, maxHeight + getPaddingBottom() + getPaddingTop()); 125d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang } 126d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 127d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang @Override 128d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang protected void onLayout(final boolean changed, final int left, final int top, final int right, 129d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final int bottom) { 130d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final boolean isRtl = isLayoutRtl(this); 131d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 132d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final int iconWidth = mContactIconView.getMeasuredWidth(); 133d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final int iconHeight = mContactIconView.getMeasuredHeight(); 134d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final int iconTop = getPaddingTop(); 135d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final int contentWidth = (right -left) - iconWidth - getPaddingLeft() - getPaddingRight(); 136d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final int contentHeight = mMessageBubble.getMeasuredHeight(); 137d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final int contentTop = iconTop; 138d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 139d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final int iconLeft; 140d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final int contentLeft; 141d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 142d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang if (mIncoming) { 143d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang if (isRtl) { 144d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang iconLeft = (right - left) - getPaddingRight() - iconWidth; 145d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang contentLeft = iconLeft - contentWidth; 146d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang } else { 147d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang iconLeft = getPaddingLeft(); 148d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang contentLeft = iconLeft + iconWidth; 149d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang } 150d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang } else { 151d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang if (isRtl) { 152d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang iconLeft = getPaddingLeft(); 153d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang contentLeft = iconLeft + iconWidth; 154d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang } else { 155d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang iconLeft = (right - left) - getPaddingRight() - iconWidth; 156d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang contentLeft = iconLeft - contentWidth; 157d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang } 158d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang } 159d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 160d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang mContactIconView.layout(iconLeft, iconTop, iconLeft + iconWidth, iconTop + iconHeight); 161d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 162d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang mMessageBubble.layout(contentLeft, contentTop, contentLeft + contentWidth, 163d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang contentTop + contentHeight); 164d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang } 165d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 166d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang private static boolean isLayoutRtl(final View view) { 167d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang return View.LAYOUT_DIRECTION_RTL == view.getLayoutDirection(); 168d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang } 169d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 170d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang private void updateViewContent() { 171d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang mMessageTextView.setText(mMessageText); 172d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang mStatusTextView.setText(mTimestampText); 173d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang mContactIconView.setText(mIconText); 174d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 175d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang mContactIconView.setTextColor(mIconTextColor); 176d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final Drawable iconBase = getContext().getDrawable(R.drawable.conversation_message_icon); 177d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang mContactIconView 178d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang .setBackground(getTintedDrawable(getContext(), iconBase, mIconBackgroundColor)); 179d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang } 180d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 181d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang private void updateViewAppearance() { 182d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final Resources res = getResources(); 183d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 184d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final int arrowWidth = res.getDimensionPixelOffset( 185d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang R.dimen.message_bubble_arrow_width); 186d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final int messageTextLeftRightPadding = res.getDimensionPixelOffset( 187d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang R.dimen.message_text_left_right_padding); 188d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final int textTopPadding = res.getDimensionPixelOffset( 189d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang R.dimen.message_text_top_padding); 190d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final int textBottomPadding = res.getDimensionPixelOffset( 191d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang R.dimen.message_text_bottom_padding); 192d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 193d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final int textLeftPadding, textRightPadding; 194d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 195d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang if (mIncoming) { 196d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang textLeftPadding = messageTextLeftRightPadding + arrowWidth; 197d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang textRightPadding = messageTextLeftRightPadding; 198d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang } else { 199d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang textLeftPadding = messageTextLeftRightPadding; 200d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang textRightPadding = messageTextLeftRightPadding + arrowWidth; 201d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang } 202d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 203d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang // These values do not depend on whether the message includes attachments 204d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final int gravity = mIncoming ? (Gravity.START | Gravity.CENTER_VERTICAL) : 205d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang (Gravity.END | Gravity.CENTER_VERTICAL); 206d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final int messageTopPadding = res.getDimensionPixelSize( 207d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang R.dimen.message_padding_default); 208d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final int metadataTopPadding = res.getDimensionPixelOffset( 209d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang R.dimen.message_metadata_top_padding); 210d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 211d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang // Update the message text/info views 212d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final int bubbleDrawableResId = mIncoming ? R.drawable.msg_bubble_incoming 213d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang : R.drawable.msg_bubble_outgoing; 214d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final int bubbleColorResId = mIncoming ? R.color.message_bubble_incoming 215d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang : R.color.message_bubble_outgoing; 216d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final Context context = getContext(); 217d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 218d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final Drawable textBackgroundDrawable = getTintedDrawable(context, 219d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang context.getDrawable(bubbleDrawableResId), 220d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang context.getColor(bubbleColorResId)); 221d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang mMessageTextAndInfoView.setBackground(textBackgroundDrawable); 222d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 223d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang if (isLayoutRtl(this)) { 224d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang // Need to switch right and left padding in RtL mode 225d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang mMessageTextAndInfoView.setPadding(textRightPadding, 226d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang textTopPadding + metadataTopPadding, 227d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang textLeftPadding, textBottomPadding); 228d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang } else { 229d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang mMessageTextAndInfoView.setPadding(textLeftPadding, 230d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang textTopPadding + metadataTopPadding, 231d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang textRightPadding, textBottomPadding); 232d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang } 233d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 234d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang // Update the message row and message bubble views 235d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang setPadding(getPaddingLeft(), messageTopPadding, getPaddingRight(), 0); 236d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang mMessageBubble.setGravity(gravity); 237d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 238d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang updateTextAppearance(); 239d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang } 240d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 241d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang private void updateTextAppearance() { 242d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final int messageColorResId = (mIncoming ? R.color.message_text_incoming 243d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang : R.color.message_text_outgoing); 244d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final int timestampColorResId = mIncoming ? R.color.timestamp_text_incoming 245d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang : R.color.timestamp_text_outgoing; 246d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final int messageColor = getContext().getColor(messageColorResId); 247d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 248d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang mMessageTextView.setTextColor(messageColor); 249d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang mMessageTextView.setLinkTextColor(messageColor); 250d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang mStatusTextView.setTextColor(timestampColorResId); 251d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang } 252d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang 253d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang private static Drawable getTintedDrawable(final Context context, final Drawable drawable, 254d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final int color) { 255d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang // For some reason occassionally drawables on JB has a null constant state 256d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final Drawable.ConstantState constantStateDrawable = drawable.getConstantState(); 257d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang final Drawable retDrawable = (constantStateDrawable != null) 258d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang ? constantStateDrawable.newDrawable(context.getResources()).mutate() 259d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang : drawable; 260d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang retDrawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP); 261d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang return retDrawable; 262d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang } 263d51affa86a445be576c95785dc8a638e5eb0d128Noah Wang} 264