diff options
30 files changed, 511 insertions, 6 deletions
diff --git a/res/drawable-hdpi/msg_bubble_incoming.9.png b/res/drawable-hdpi/msg_bubble_incoming.9.png Binary files differnew file mode 100644 index 00000000000..7fed0a806a0 --- /dev/null +++ b/res/drawable-hdpi/msg_bubble_incoming.9.png diff --git a/res/drawable-hdpi/msg_bubble_outgoing.9.png b/res/drawable-hdpi/msg_bubble_outgoing.9.png Binary files differnew file mode 100644 index 00000000000..8e7ccc0cc81 --- /dev/null +++ b/res/drawable-hdpi/msg_bubble_outgoing.9.png diff --git a/res/drawable-ldrtl-hdpi/msg_bubble_incoming.9.png b/res/drawable-ldrtl-hdpi/msg_bubble_incoming.9.png Binary files differnew file mode 100644 index 00000000000..8e7ccc0cc81 --- /dev/null +++ b/res/drawable-ldrtl-hdpi/msg_bubble_incoming.9.png diff --git a/res/drawable-ldrtl-hdpi/msg_bubble_outgoing.9.png b/res/drawable-ldrtl-hdpi/msg_bubble_outgoing.9.png Binary files differnew file mode 100644 index 00000000000..7fed0a806a0 --- /dev/null +++ b/res/drawable-ldrtl-hdpi/msg_bubble_outgoing.9.png diff --git a/res/drawable-ldrtl-mdpi/msg_bubble_incoming.9.png b/res/drawable-ldrtl-mdpi/msg_bubble_incoming.9.png Binary files differnew file mode 100644 index 00000000000..5ca9b14d641 --- /dev/null +++ b/res/drawable-ldrtl-mdpi/msg_bubble_incoming.9.png diff --git a/res/drawable-ldrtl-mdpi/msg_bubble_outgoing.9.png b/res/drawable-ldrtl-mdpi/msg_bubble_outgoing.9.png Binary files differnew file mode 100644 index 00000000000..4e7e4640376 --- /dev/null +++ b/res/drawable-ldrtl-mdpi/msg_bubble_outgoing.9.png diff --git a/res/drawable-ldrtl-xhdpi/msg_bubble_incoming.9.png b/res/drawable-ldrtl-xhdpi/msg_bubble_incoming.9.png Binary files differnew file mode 100644 index 00000000000..52cb936a8ee --- /dev/null +++ b/res/drawable-ldrtl-xhdpi/msg_bubble_incoming.9.png diff --git a/res/drawable-ldrtl-xhdpi/msg_bubble_outgoing.9.png b/res/drawable-ldrtl-xhdpi/msg_bubble_outgoing.9.png Binary files differnew file mode 100644 index 00000000000..0661fdba789 --- /dev/null +++ b/res/drawable-ldrtl-xhdpi/msg_bubble_outgoing.9.png diff --git a/res/drawable-ldrtl-xxhdpi/msg_bubble_incoming.9.png b/res/drawable-ldrtl-xxhdpi/msg_bubble_incoming.9.png Binary files differnew file mode 100644 index 00000000000..5d8fc747ee3 --- /dev/null +++ b/res/drawable-ldrtl-xxhdpi/msg_bubble_incoming.9.png diff --git a/res/drawable-ldrtl-xxhdpi/msg_bubble_outgoing.9.png b/res/drawable-ldrtl-xxhdpi/msg_bubble_outgoing.9.png Binary files differnew file mode 100644 index 00000000000..009c721919e --- /dev/null +++ b/res/drawable-ldrtl-xxhdpi/msg_bubble_outgoing.9.png diff --git a/res/drawable-ldrtl-xxxhdpi/msg_bubble_incoming.9.png b/res/drawable-ldrtl-xxxhdpi/msg_bubble_incoming.9.png Binary files differnew file mode 100644 index 00000000000..8378db57676 --- /dev/null +++ b/res/drawable-ldrtl-xxxhdpi/msg_bubble_incoming.9.png diff --git a/res/drawable-ldrtl-xxxhdpi/msg_bubble_outgoing.9.png b/res/drawable-ldrtl-xxxhdpi/msg_bubble_outgoing.9.png Binary files differnew file mode 100644 index 00000000000..f0d0d9ee5c9 --- /dev/null +++ b/res/drawable-ldrtl-xxxhdpi/msg_bubble_outgoing.9.png diff --git a/res/drawable-mdpi/msg_bubble_incoming.9.png b/res/drawable-mdpi/msg_bubble_incoming.9.png Binary files differnew file mode 100644 index 00000000000..4e7e4640376 --- /dev/null +++ b/res/drawable-mdpi/msg_bubble_incoming.9.png diff --git a/res/drawable-mdpi/msg_bubble_outgoing.9.png b/res/drawable-mdpi/msg_bubble_outgoing.9.png Binary files differnew file mode 100644 index 00000000000..5ca9b14d641 --- /dev/null +++ b/res/drawable-mdpi/msg_bubble_outgoing.9.png diff --git a/res/drawable-xhdpi/msg_bubble_incoming.9.png b/res/drawable-xhdpi/msg_bubble_incoming.9.png Binary files differnew file mode 100644 index 00000000000..0661fdba789 --- /dev/null +++ b/res/drawable-xhdpi/msg_bubble_incoming.9.png diff --git a/res/drawable-xhdpi/msg_bubble_outgoing.9.png b/res/drawable-xhdpi/msg_bubble_outgoing.9.png Binary files differnew file mode 100644 index 00000000000..52cb936a8ee --- /dev/null +++ b/res/drawable-xhdpi/msg_bubble_outgoing.9.png diff --git a/res/drawable-xxhdpi/msg_bubble_incoming.9.png b/res/drawable-xxhdpi/msg_bubble_incoming.9.png Binary files differnew file mode 100644 index 00000000000..ab693b3e7c1 --- /dev/null +++ b/res/drawable-xxhdpi/msg_bubble_incoming.9.png diff --git a/res/drawable-xxhdpi/msg_bubble_outgoing.9.png b/res/drawable-xxhdpi/msg_bubble_outgoing.9.png Binary files differnew file mode 100644 index 00000000000..5b2a2fffc0d --- /dev/null +++ b/res/drawable-xxhdpi/msg_bubble_outgoing.9.png diff --git a/res/drawable-xxxhdpi/msg_bubble_incoming.9.png b/res/drawable-xxxhdpi/msg_bubble_incoming.9.png Binary files differnew file mode 100644 index 00000000000..34130fc6d1b --- /dev/null +++ b/res/drawable-xxxhdpi/msg_bubble_incoming.9.png diff --git a/res/drawable-xxxhdpi/msg_bubble_outgoing.9.png b/res/drawable-xxxhdpi/msg_bubble_outgoing.9.png Binary files differnew file mode 100644 index 00000000000..cfd5734f106 --- /dev/null +++ b/res/drawable-xxxhdpi/msg_bubble_outgoing.9.png diff --git a/res/drawable/conversation_message_icon.xml b/res/drawable/conversation_message_icon.xml new file mode 100644 index 00000000000..a1192ec5f1e --- /dev/null +++ b/res/drawable/conversation_message_icon.xml @@ -0,0 +1,26 @@ +<!-- + Copyright (C) 2015 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<shape + xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="oval"> + + <solid + android:color="#FF0000"/> + + <size + android:width="42dp" + android:height="42dp"/> +</shape> diff --git a/res/layout/conversation_message_content.xml b/res/layout/conversation_message_content.xml new file mode 100644 index 00000000000..7bc53e5074a --- /dev/null +++ b/res/layout/conversation_message_content.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2016 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/message_content" + android:orientation="vertical" + android:layout_width="wrap_content" + android:layout_height="wrap_content" > + + <com.android.settings.display.MessageBubbleBackground + android:id="@+id/message_text_and_info" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical" + android:minHeight="@dimen/conversation_message_contact_icon_size" + android:layout_marginTop="0dp" > + + <TextView + android:id="@+id/message_text" + android:textSize="@dimen/conversation_message_text_size" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> + + <TextView + android:id="@+id/message_status" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textSize="@dimen/conversation_status_text_size" /> + + </com.android.settings.display.MessageBubbleBackground> + +</LinearLayout> diff --git a/res/layout/conversation_message_icon.xml b/res/layout/conversation_message_icon.xml new file mode 100644 index 00000000000..4ffd2859cee --- /dev/null +++ b/res/layout/conversation_message_icon.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2016 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<TextView xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/conversation_icon" + android:layout_width="@dimen/conversation_message_contact_icon_size" + android:layout_height="@dimen/conversation_message_contact_icon_size" + android:fontFamily="sans-serif" + android:textStyle="bold" + android:textSize="@dimen/conversation_message_contact_icon_text_size" + android:gravity="center" /> diff --git a/res/layout/screen_zoom_preview_1.xml b/res/layout/screen_zoom_preview_1.xml index ca2ecca738c..62cd0933007 100644 --- a/res/layout/screen_zoom_preview_1.xml +++ b/res/layout/screen_zoom_preview_1.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2015 The Android Open Source Project +<!-- Copyright (C) 2016 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,10 +14,52 @@ limitations under the License. --> -<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" - android:scrollbars="none" - android:background="?android:attr/colorBackgroundFloating"> + android:background="@color/conversation_background" + android:padding="@dimen/conversation_message_list_padding" + android:orientation="vertical" > -</ScrollView> + <com.android.settings.display.ConversationMessageView + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:incoming="false" + app:messageText="@string/screen_zoom_conversation_message_1" + app:timestampText="@string/screen_zoom_conversation_timestamp_1" + app:iconText="@string/screen_zoom_conversation_icon_alex" + app:iconTextColor="@color/message_icon_text_outgoing" + app:iconBackgroundColor="@color/message_icon_background_outgoing" /> + + <com.android.settings.display.ConversationMessageView + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:incoming="true" + app:messageText="@string/screen_zoom_conversation_message_2" + app:timestampText="@string/screen_zoom_conversation_timestamp_2" + app:iconText="@string/screen_zoom_conversation_icon_pete" + app:iconTextColor="@color/message_icon_text_incoming" + app:iconBackgroundColor="@color/message_icon_background_incoming" /> + + <com.android.settings.display.ConversationMessageView + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:incoming="false" + app:messageText="@string/screen_zoom_conversation_message_3" + app:timestampText="@string/screen_zoom_conversation_timestamp_3" + app:iconText="@string/screen_zoom_conversation_icon_alex" + app:iconTextColor="@color/message_icon_text_outgoing" + app:iconBackgroundColor="@color/message_icon_background_outgoing" /> + + <com.android.settings.display.ConversationMessageView + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:incoming="true" + app:messageText="@string/screen_zoom_conversation_message_4" + app:timestampText="@string/screen_zoom_conversation_timestamp_4" + app:iconText="@string/screen_zoom_conversation_icon_pete" + app:iconTextColor="@color/message_icon_text_incoming" + app:iconBackgroundColor="@color/message_icon_background_incoming" /> + +</LinearLayout> diff --git a/res/values/attrs.xml b/res/values/attrs.xml index d94ff13d1be..c6dd2461314 100644 --- a/res/values/attrs.xml +++ b/res/values/attrs.xml @@ -106,6 +106,16 @@ <attr name="currentPageIndicatorColor" format="color" /> </declare-styleable> + <!-- For ConversationMessageView --> + <declare-styleable name="ConversationMessageView"> + <attr name="incoming" format="boolean" /> + <attr name="messageText" format="reference" /> + <attr name="timestampText" format="reference" /> + <attr name="iconText" format="reference" /> + <attr name="iconTextColor" format="reference|color" /> + <attr name="iconBackgroundColor" format="reference|color" /> + </declare-styleable> + <attr name="switchBarTheme" format="reference" /> <attr name="switchBarMarginStart" format="dimension" /> <attr name="switchBarMarginEnd" format="dimension" /> diff --git a/res/values/colors.xml b/res/values/colors.xml index 90884c9b96b..f27b693bf5c 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -111,7 +111,20 @@ <color name="material_blue_500">#4285F4</color> <color name="material_blue_700">#3367D6</color> + <color name="message_text_incoming">#ffffffff</color> + <color name="message_text_outgoing">#ff323232</color> + <color name="timestamp_text_outgoing">#99323232</color> + <color name="timestamp_text_incoming">#99ffffff</color> + <color name="message_bubble_incoming">#689f38</color> + <color name="message_bubble_outgoing">#ffffffff</color> + <color name="conversation_background">#eeeeee</color> + <color name="message_icon_background_incoming">#689f38</color> + <color name="message_icon_text_incoming">#ffffffff</color> + <color name="message_icon_background_outgoing">#4285f4</color> + <color name="message_icon_text_outgoing">#ffffffff</color> + + <color name="seek_bar_preference_preview_text">#fff</color> <!-- Black at 80% opacity --> - <color name="seek_bar_preference_preview_border_tint">#CC000000</color> + <color name="seek_bar_preference_preview_border_tint">#cc000000</color> </resources> diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 14aac55209f..53dd515d324 100755 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -258,6 +258,18 @@ <!-- Display, Screen zoom --> <dimen name="screen_zoom_preview_height">240dp</dimen> <dimen name="screen_zoom_preview_app_icon_width">88dp</dimen> + <dimen name="conversation_message_list_padding">10dp</dimen> + <dimen name="conversation_message_contact_icon_size">42dp</dimen> + <dimen name="conversation_message_contact_icon_text_size">32sp</dimen> + <dimen name="conversation_message_text_size">16sp</dimen> + <dimen name="conversation_status_text_size">12sp</dimen> + <dimen name="conversation_bubble_width_snap">20dp</dimen> + <dimen name="message_bubble_arrow_width">9dp</dimen> + <dimen name="message_padding_default">18dp</dimen> + <dimen name="message_text_left_right_padding">14dp</dimen> + <dimen name="message_text_top_padding">10dp</dimen> + <dimen name="message_text_bottom_padding">12dp</dimen> + <dimen name="message_metadata_top_padding">4dp</dimen> <!-- Accessibility Settings --> <dimen name="accessibility_layout_margin_start_end">24dp</dimen> diff --git a/res/values/strings.xml b/res/values/strings.xml index 0e7ca629610..383506e6275 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -6883,6 +6883,27 @@ density in raw pixels per inch rather than using a relative description. [CHAR LIMIT=24] --> <string name="screen_zoom_summary_custom">Custom (<xliff:g id="densityDpi" example="160">%d</xliff:g>)</string> + <!-- Name Initial shown in the conversation message icon. [CHAR LIMIT=1] --> + <string name="screen_zoom_conversation_icon_alex">A</string> + <!-- Name Initial shown in the conversation message icon. [CHAR LIMIT=1] --> + <string name="screen_zoom_conversation_icon_pete">P</string> + <!-- Conversation message body of the messaging app preview screen. [CHAR LIMIT=NONE] --> + <string name="screen_zoom_conversation_message_1">Hi Pete!</string> + <!-- Conversation message body of the messaging app preview screen. [CHAR LIMIT=NONE] --> + <string name="screen_zoom_conversation_message_2">Hey, want to grab coffee and catch up today?</string> + <!-- Conversation message body of the messaging app preview screen. [CHAR LIMIT=NONE] --> + <string name="screen_zoom_conversation_message_3">Sounds great. I know of a good place not too far from here.</string> + <!-- Conversation message body of the messaging app preview screen. [CHAR LIMIT=NONE] --> + <string name="screen_zoom_conversation_message_4">Perfect!</string> + <!-- Conversation message timestamp of the messaging app preview screen. [CHAR LIMIT=20] --> + <string name="screen_zoom_conversation_timestamp_1">Tue 6:00PM</string> + <!-- Conversation message timestamp of the messaging app preview screen. [CHAR LIMIT=20] --> + <string name="screen_zoom_conversation_timestamp_2">Tue 6:01PM</string> + <!-- Conversation message timestamp of the messaging app preview screen. [CHAR LIMIT=20] --> + <string name="screen_zoom_conversation_timestamp_3">Tue 6:02PM</string> + <!-- Conversation message timestamp of the messaging app preview screen. [CHAR LIMIT=20] --> + <string name="screen_zoom_conversation_timestamp_4">Tue 6:03PM</string> + <!-- Button to show all top-level settings items [CHAR LIMIT=20] --> <string name="see_all">See all</string> <!-- Button to show less top-level settings items [CHAR LIMIT=20] --> diff --git a/src/com/android/settings/display/ConversationMessageView.java b/src/com/android/settings/display/ConversationMessageView.java new file mode 100644 index 00000000000..a0889c4ecf7 --- /dev/null +++ b/src/com/android/settings/display/ConversationMessageView.java @@ -0,0 +1,261 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.display; + +import android.content.Context; +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.android.settings.R; + +/** + * The view for a single entry in a conversation. This is a simplified version of + * com.android.messaging.ui.conversation.ConversationMessageView class. + */ +public class ConversationMessageView extends FrameLayout { + private final boolean mIncoming; + private final CharSequence mMessageText; + private final CharSequence mTimestampText; + private final CharSequence mIconText; + private final int mIconTextColor; + private final int mIconBackgroundColor; + + private LinearLayout mMessageBubble; + private ViewGroup mMessageTextAndInfoView; + private TextView mMessageTextView; + private TextView mStatusTextView; + private TextView mContactIconView; + + public ConversationMessageView(Context context) { + this(context, null); + } + + public ConversationMessageView(final Context context, final AttributeSet attrs) { + this(context, attrs, 0); + } + + public ConversationMessageView(Context context, AttributeSet attrs, int defStyleAttr) { + this(context, attrs, defStyleAttr, 0); + } + + public ConversationMessageView(Context context, AttributeSet attrs, int defStyleAttr, + int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + + final TypedArray a = context.obtainStyledAttributes(attrs, + R.styleable.ConversationMessageView); + + mIncoming = a.getBoolean(R.styleable.ConversationMessageView_incoming, true); + mMessageText = a.getString(R.styleable.ConversationMessageView_messageText); + mTimestampText = a.getString(R.styleable.ConversationMessageView_timestampText); + mIconText = a.getString(R.styleable.ConversationMessageView_iconText); + mIconTextColor = a.getColor(R.styleable.ConversationMessageView_iconTextColor, 0); + mIconBackgroundColor = a.getColor(R.styleable.ConversationMessageView_iconBackgroundColor, + 0); + + LayoutInflater.from(context).inflate(R.layout.conversation_message_icon, this); + LayoutInflater.from(context).inflate(R.layout.conversation_message_content, this); + } + + @Override + protected void onFinishInflate() { + mMessageBubble = (LinearLayout) findViewById(R.id.message_content); + mMessageTextAndInfoView = (ViewGroup) findViewById(R.id.message_text_and_info); + mMessageTextView = (TextView) findViewById(R.id.message_text); + mStatusTextView = (TextView) findViewById(R.id.message_status); + mContactIconView = (TextView) findViewById(R.id.conversation_icon); + updateViewContent(); + } + + @Override + protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) { + updateViewAppearance(); + + final int horizontalSpace = MeasureSpec.getSize(widthMeasureSpec); + final int iconSize = getResources() + .getDimensionPixelSize(R.dimen.conversation_message_contact_icon_size); + + final int unspecifiedMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); + final int iconMeasureSpec = MeasureSpec.makeMeasureSpec(iconSize, MeasureSpec.EXACTLY); + + mContactIconView.measure(iconMeasureSpec, iconMeasureSpec); + + final int arrowWidth = + getResources().getDimensionPixelSize(R.dimen.message_bubble_arrow_width); + + // We need to subtract contact icon width twice from the horizontal space to get + // the max leftover space because we want the message bubble to extend no further than the + // starting position of the message bubble in the opposite direction. + final int maxLeftoverSpace = horizontalSpace - mContactIconView.getMeasuredWidth() * 2 + - arrowWidth - getPaddingLeft() - getPaddingRight(); + final int messageContentWidthMeasureSpec = MeasureSpec.makeMeasureSpec(maxLeftoverSpace, + MeasureSpec.AT_MOST); + + mMessageBubble.measure(messageContentWidthMeasureSpec, unspecifiedMeasureSpec); + + final int maxHeight = Math.max(mContactIconView.getMeasuredHeight(), + mMessageBubble.getMeasuredHeight()); + setMeasuredDimension(horizontalSpace, maxHeight + getPaddingBottom() + getPaddingTop()); + } + + @Override + protected void onLayout(final boolean changed, final int left, final int top, final int right, + final int bottom) { + final boolean isRtl = isLayoutRtl(this); + + final int iconWidth = mContactIconView.getMeasuredWidth(); + final int iconHeight = mContactIconView.getMeasuredHeight(); + final int iconTop = getPaddingTop(); + final int contentWidth = (right -left) - iconWidth - getPaddingLeft() - getPaddingRight(); + final int contentHeight = mMessageBubble.getMeasuredHeight(); + final int contentTop = iconTop; + + final int iconLeft; + final int contentLeft; + + if (mIncoming) { + if (isRtl) { + iconLeft = (right - left) - getPaddingRight() - iconWidth; + contentLeft = iconLeft - contentWidth; + } else { + iconLeft = getPaddingLeft(); + contentLeft = iconLeft + iconWidth; + } + } else { + if (isRtl) { + iconLeft = getPaddingLeft(); + contentLeft = iconLeft + iconWidth; + } else { + iconLeft = (right - left) - getPaddingRight() - iconWidth; + contentLeft = iconLeft - contentWidth; + } + } + + mContactIconView.layout(iconLeft, iconTop, iconLeft + iconWidth, iconTop + iconHeight); + + mMessageBubble.layout(contentLeft, contentTop, contentLeft + contentWidth, + contentTop + contentHeight); + } + + private static boolean isLayoutRtl(final View view) { + return View.LAYOUT_DIRECTION_RTL == view.getLayoutDirection(); + } + + private void updateViewContent() { + mMessageTextView.setText(mMessageText); + mStatusTextView.setText(mTimestampText); + mContactIconView.setText(mIconText); + + mContactIconView.setTextColor(mIconTextColor); + final Drawable iconBase = getContext().getDrawable(R.drawable.conversation_message_icon); + mContactIconView + .setBackground(getTintedDrawable(getContext(), iconBase, mIconBackgroundColor)); + } + + private void updateViewAppearance() { + final Resources res = getResources(); + + final int arrowWidth = res.getDimensionPixelOffset( + R.dimen.message_bubble_arrow_width); + final int messageTextLeftRightPadding = res.getDimensionPixelOffset( + R.dimen.message_text_left_right_padding); + final int textTopPadding = res.getDimensionPixelOffset( + R.dimen.message_text_top_padding); + final int textBottomPadding = res.getDimensionPixelOffset( + R.dimen.message_text_bottom_padding); + + final int textLeftPadding, textRightPadding; + + if (mIncoming) { + textLeftPadding = messageTextLeftRightPadding + arrowWidth; + textRightPadding = messageTextLeftRightPadding; + } else { + textLeftPadding = messageTextLeftRightPadding; + textRightPadding = messageTextLeftRightPadding + arrowWidth; + } + + // These values do not depend on whether the message includes attachments + final int gravity = mIncoming ? (Gravity.START | Gravity.CENTER_VERTICAL) : + (Gravity.END | Gravity.CENTER_VERTICAL); + final int messageTopPadding = res.getDimensionPixelSize( + R.dimen.message_padding_default); + final int metadataTopPadding = res.getDimensionPixelOffset( + R.dimen.message_metadata_top_padding); + + // Update the message text/info views + final int bubbleDrawableResId = mIncoming ? R.drawable.msg_bubble_incoming + : R.drawable.msg_bubble_outgoing; + final int bubbleColorResId = mIncoming ? R.color.message_bubble_incoming + : R.color.message_bubble_outgoing; + final Context context = getContext(); + + final Drawable textBackgroundDrawable = getTintedDrawable(context, + context.getDrawable(bubbleDrawableResId), + context.getColor(bubbleColorResId)); + mMessageTextAndInfoView.setBackground(textBackgroundDrawable); + + if (isLayoutRtl(this)) { + // Need to switch right and left padding in RtL mode + mMessageTextAndInfoView.setPadding(textRightPadding, + textTopPadding + metadataTopPadding, + textLeftPadding, textBottomPadding); + } else { + mMessageTextAndInfoView.setPadding(textLeftPadding, + textTopPadding + metadataTopPadding, + textRightPadding, textBottomPadding); + } + + // Update the message row and message bubble views + setPadding(getPaddingLeft(), messageTopPadding, getPaddingRight(), 0); + mMessageBubble.setGravity(gravity); + + updateTextAppearance(); + } + + private void updateTextAppearance() { + final int messageColorResId = (mIncoming ? R.color.message_text_incoming + : R.color.message_text_outgoing); + final int timestampColorResId = mIncoming ? R.color.timestamp_text_incoming + : R.color.timestamp_text_outgoing; + final int messageColor = getContext().getColor(messageColorResId); + + mMessageTextView.setTextColor(messageColor); + mMessageTextView.setLinkTextColor(messageColor); + mStatusTextView.setTextColor(timestampColorResId); + } + + private static Drawable getTintedDrawable(final Context context, final Drawable drawable, + final int color) { + // For some reason occassionally drawables on JB has a null constant state + final Drawable.ConstantState constantStateDrawable = drawable.getConstantState(); + final Drawable retDrawable = (constantStateDrawable != null) + ? constantStateDrawable.newDrawable(context.getResources()).mutate() + : drawable; + retDrawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP); + return retDrawable; + } +} diff --git a/src/com/android/settings/display/MessageBubbleBackground.java b/src/com/android/settings/display/MessageBubbleBackground.java new file mode 100644 index 00000000000..b2e1e9701c1 --- /dev/null +++ b/src/com/android/settings/display/MessageBubbleBackground.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.display; + +import android.content.Context; +import android.util.AttributeSet; +import android.util.Log; +import android.widget.LinearLayout; + +import com.android.settings.R; + +public class MessageBubbleBackground extends LinearLayout { + private final int mSnapWidthPixels; + + public MessageBubbleBackground(Context context, AttributeSet attrs) { + super(context, attrs); + mSnapWidthPixels = context.getResources().getDimensionPixelSize( + R.dimen.conversation_bubble_width_snap); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + final int widthPadding = getPaddingLeft() + getPaddingRight(); + int bubbleWidth = getMeasuredWidth() - widthPadding; + final int maxWidth = MeasureSpec.getSize(widthMeasureSpec) - widthPadding; + // Round up to next snapWidthPixels + bubbleWidth = Math.min(maxWidth, + (int) (Math.ceil(bubbleWidth / (float) mSnapWidthPixels) * mSnapWidthPixels)); + super.onMeasure( + MeasureSpec.makeMeasureSpec(bubbleWidth + widthPadding, MeasureSpec.EXACTLY), + heightMeasureSpec); + Log.w(this.getClass().getSimpleName(), + String.format("onMeasure called; width:%d, height:%d", this.getMeasuredWidth(), + this.getMeasuredHeight())); + } +} |