diff options
-rw-r--r-- | res/layout/voicemail_promo_card.xml | 99 | ||||
-rw-r--r-- | res/values/colors.xml | 5 | ||||
-rw-r--r-- | res/values/dimens.xml | 11 | ||||
-rw-r--r-- | res/values/styles.xml | 14 | ||||
-rw-r--r-- | src/com/android/dialer/calllog/CallLogAdapter.java | 146 | ||||
-rw-r--r-- | src/com/android/dialer/calllog/PromoCardViewHolder.java | 71 |
6 files changed, 338 insertions, 8 deletions
diff --git a/res/layout/voicemail_promo_card.xml b/res/layout/voicemail_promo_card.xml new file mode 100644 index 000000000..103fa30b3 --- /dev/null +++ b/res/layout/voicemail_promo_card.xml @@ -0,0 +1,99 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2015 Google Inc. All Rights Reserved. --> + +<android.support.v7.widget.CardView + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:card_view="http://schemas.android.com/apk/res-auto" + android:id="@+id/promo_card" + style="@style/CallLogCardStyle" + android:orientation="vertical" + android:gravity="center_vertical" + card_view:cardBackgroundColor="@color/visual_voicemail_promo_card_background"> + + <LinearLayout + android:id="@+id/promo_card_content" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingStart="@dimen/promo_card_start_padding" + android:paddingEnd="@dimen/promo_card_main_padding" + android:paddingTop="@dimen/promo_card_top_padding" + android:paddingBottom="@dimen/promo_card_main_padding" + android:orientation="horizontal" + android:gravity="top"> + + <ImageView + android:id="@+id/promo_card_icon" + android:layout_width="@dimen/promo_card_icon_size" + android:layout_height="@dimen/promo_card_icon_size" + android:layout_gravity="top" + android:src="@drawable/ic_voicemail_24dp"/> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="@dimen/promo_card_main_padding" + android:orientation="vertical" + android:gravity="center_vertical"> + + <TextView + android:id="@+id/promo_card_header" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginBottom="@dimen/promo_card_title_padding" + android:layout_gravity="center_vertical" + android:textColor="@color/background_dialer_white" + android:textSize="@dimen/call_log_primary_text_size" + android:textStyle="bold" + android:text="@string/visual_voicemail_title" + android:singleLine="false"/> + + <TextView + android:id="@+id/promo_card_details" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textColor="@color/background_dialer_white" + android:textSize="@dimen/call_log_secondary_text_size" + android:text="@string/visual_voicemail_text" + android:lineSpacingExtra="@dimen/promo_card_line_spacing" + android:singleLine="false"/> + </LinearLayout> + </LinearLayout> + + <View + android:layout_width="match_parent" + android:layout_height="1dp" + android:background="@color/visual_voicemail_promo_card_divider"/> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingEnd="@dimen/promo_card_action_end_padding" + android:paddingTop="@dimen/promo_card_action_vertical_padding" + android:paddingBottom="@dimen/promo_card_action_vertical_padding" + android:orientation="horizontal" + android:gravity="end"> + + <TextView + android:id="@+id/settings_action" + style="@style/PromoCardActionStyle" + android:background="?android:attr/selectableItemBackground" + android:text="@string/visual_voicemail_settings" + android:nextFocusLeft="@+id/promo_card" + android:nextFocusRight="@+id/ok_action" + android:paddingEnd="@dimen/promo_card_action_between_padding"/> + + <TextView + android:id="@+id/ok_action" + style="@style/PromoCardActionStyle" + android:background="?android:attr/selectableItemBackground" + android:text="@android:string/ok" + android:nextFocusLeft="@+id/settings_action" + android:nextFocusRight="@+id/promo_card"/> + </LinearLayout> + </LinearLayout> +</android.support.v7.widget.CardView> diff --git a/res/values/colors.xml b/res/values/colors.xml index f83c3284c..c3b0fb5bc 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -36,6 +36,11 @@ <!-- Color of the text describing an unconsumed voicemail. --> <color name="call_log_voicemail_highlight_color">#33b5e5</color> + <!-- Background color of visual voicemail promo card. --> + <color name="visual_voicemail_promo_card_background">#673ab7</color> + <color name="visual_voicemail_promo_card_divider">#7d57c1</color> + <color name="promo_card_text">#ffffff</color> + <!-- Tint of the recent card phone icon; 30% black --> <color name="call_log_list_item_primary_action_icon_tint">#4d000000</color> diff --git a/res/values/dimens.xml b/res/values/dimens.xml index bcde855b5..206b44740 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -134,4 +134,15 @@ <dimen name="preference_summary_line_spacing_extra">4dp</dimen> <dimen name="call_log_list_item_primary_action_dimen">36dp</dimen> + + <!-- Dimensions for promo cards --> + <dimen name="promo_card_icon_size">24dp</dimen> + <dimen name="promo_card_start_padding">16dp</dimen> + <dimen name="promo_card_top_padding">21dp</dimen> + <dimen name="promo_card_main_padding">24dp</dimen> + <dimen name="promo_card_title_padding">12dp</dimen> + <dimen name="promo_card_action_vertical_padding">4dp</dimen> + <dimen name="promo_card_action_end_padding">4dp</dimen> + <dimen name="promo_card_action_between_padding">11dp</dimen> + <dimen name="promo_card_line_spacing">4dp</dimen> </resources> diff --git a/res/values/styles.xml b/res/values/styles.xml index dab5c6aa1..7d5d42f8f 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -218,4 +218,18 @@ <item name="cardCornerRadius">2dp</item> <item name="cardBackgroundColor">@color/background_dialer_call_log_list_item</item> </style> + + <style name="PromoCardActionStyle"> + <item name="android:layout_width">wrap_content</item> + <item name="android:layout_height">@dimen/call_log_action_height</item> + <item name="android:gravity">end|center_vertical</item> + <item name="android:paddingStart">@dimen/call_log_action_horizontal_padding</item> + <item name="android:paddingEnd">@dimen/call_log_action_horizontal_padding</item> + <item name="android:textColor">@color/promo_card_text</item> + <item name="android:textSize">@dimen/call_log_list_item_actions_text_size</item> + <item name="android:fontFamily">"sans-serif-medium"</item> + <item name="android:focusable">true</item> + <item name="android:singleLine">true</item> + <item name="android:textAllCaps">true</item> + </style> </resources> diff --git a/src/com/android/dialer/calllog/CallLogAdapter.java b/src/com/android/dialer/calllog/CallLogAdapter.java index 921ec506c..cc3c5bad8 100644 --- a/src/com/android/dialer/calllog/CallLogAdapter.java +++ b/src/com/android/dialer/calllog/CallLogAdapter.java @@ -18,16 +18,20 @@ package com.android.dialer.calllog; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.content.res.Resources; import android.database.Cursor; import android.net.Uri; import android.support.v7.widget.RecyclerView; import android.os.Bundle; import android.os.Trace; +import android.preference.PreferenceActivity; +import android.preference.PreferenceManager; import android.provider.CallLog; import android.support.v7.widget.RecyclerView.ViewHolder; import android.telecom.PhoneAccountHandle; import android.telephony.PhoneNumberUtils; +import android.telephony.TelephonyManager; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; @@ -62,6 +66,21 @@ public class CallLogAdapter extends GroupingListAdapter private static final int VIEW_TYPE_SHOW_CALL_HISTORY_LIST_ITEM = 10; private static final int NO_EXPANDED_LIST_ITEM = -1; + private static final int VOICEMAIL_PROMO_CARD_POSITION = 0; + /** + * View type for voicemail promo card. Note: Numbering starts at 20 to avoid collision + * with {@link com.android.common.widget.GroupingListAdapter#ITEM_TYPE_IN_GROUP}, and + * {@link CallLogAdapter#VIEW_TYPE_SHOW_CALL_HISTORY_LIST_ITEM}. + */ + private static final int VIEW_TYPE_VOICEMAIL_PROMO_CARD = 20; + + /** + * The key for the show voicemail promo card preference which will determine whether the promo + * card was permanently dismissed or not. + */ + private static final String SHOW_VOICEMAIL_PROMO_CARD = "show_voicemail_promo_card"; + private static final boolean SHOW_VOICEMAIL_PROMO_CARD_DEFAULT = true; + protected final Context mContext; private final ContactInfoHelper mContactInfoHelper; private final VoicemailPlaybackPresenter mVoicemailPlaybackPresenter; @@ -97,6 +116,10 @@ public class CallLogAdapter extends GroupingListAdapter private boolean mLoading = true; + private SharedPreferences mPrefs; + + private boolean mShowPromoCard = false; + /** Instance of helper class for managing views. */ private final CallLogListItemHelper mCallLogViewsHelper; @@ -135,6 +158,30 @@ public class CallLogAdapter extends GroupingListAdapter } }; + /** + * Click handler used to dismiss the promo card when the user taps the "ok" button. + */ + private final View.OnClickListener mOkActionListener = new View.OnClickListener() { + @Override + public void onClick(View view) { + dismissVoicemailPromoCard(); + } + }; + + /** + * Click handler used to send the user to the voicemail settings screen and then dismiss the + * promo card. + */ + private final View.OnClickListener mVoicemailSettingsActionListener = + new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(TelephonyManager.ACTION_CONFIGURE_VOICEMAIL); + mContext.startActivity(intent); + dismissVoicemailPromoCard(); + } + }; + private void expandViewHolderActions(CallLogListItemViewHolder viewHolder) { // If another item is expanded, notify it that it has changed. Its actions will be // hidden when it is re-binded because we change mCurrentlyExpandedPosition below. @@ -212,6 +259,8 @@ public class CallLogAdapter extends GroupingListAdapter new PhoneCallDetailsHelper(mContext, resources, mPhoneNumberUtilsWrapper); mCallLogViewsHelper = new CallLogListItemHelper(phoneCallDetailsHelper, resources); mCallLogGroupBuilder = new CallLogGroupBuilder(this); + mPrefs = PreferenceManager.getDefaultSharedPreferences(context); + maybeShowVoicemailPromoCard(); } public void onSaveInstanceState(Bundle outState) { @@ -279,6 +328,8 @@ public class CallLogAdapter extends GroupingListAdapter public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == VIEW_TYPE_SHOW_CALL_HISTORY_LIST_ITEM) { return ShowCallHistoryViewHolder.create(mContext, parent); + } else if (viewType == VIEW_TYPE_VOICEMAIL_PROMO_CARD) { + return createVoicemailPromoCardViewHolder(parent); } return createCallLogEntryViewHolder(parent); } @@ -313,19 +364,52 @@ public class CallLogAdapter extends GroupingListAdapter * TODO: This gets called 20-30 times when Dialer starts up for a single call log entry and * should not. It invokes cross-process methods and the repeat execution can get costly. * - * @param callLogItemView the view corresponding to this entry - * @param count the number of entries in the current item, greater than 1 if it is a group + * @param ViewHolder The view corresponding to this entry. + * @param position The position of the entry. */ public void onBindViewHolder(ViewHolder viewHolder, int position) { - if (getItemViewType(position) == VIEW_TYPE_SHOW_CALL_HISTORY_LIST_ITEM) { - return; - } Trace.beginSection("onBindViewHolder: " + position); + + switch (getItemViewType(position)) { + case VIEW_TYPE_SHOW_CALL_HISTORY_LIST_ITEM: + break; + case VIEW_TYPE_VOICEMAIL_PROMO_CARD: + bindVoicemailPromoCardViewHolder(viewHolder); + break; + default: + bindCallLogListViewHolder(viewHolder, position); + break; + } + + Trace.endSection(); + } + + /** + * Binds the promo card view holder. + * + * @param viewHolder The promo card view holder. + */ + protected void bindVoicemailPromoCardViewHolder(ViewHolder viewHolder) { + PromoCardViewHolder promoCardViewHolder = (PromoCardViewHolder) viewHolder; + + promoCardViewHolder.getSettingsTextView().setOnClickListener( + mVoicemailSettingsActionListener); + promoCardViewHolder.getOkTextView().setOnClickListener(mOkActionListener); + } + + /** + * Binds the view holder for the call log list item view. + * + * @param viewHolder The call log list item view holder. + * @param position The position of the list item. + */ + + private void bindCallLogListViewHolder(ViewHolder viewHolder, int position) { Cursor c = (Cursor) getItem(position); if (c == null) { - Trace.endSection(); return; } + int count = getGroupSize(position); final String number = c.getString(CallLogQuery.NUMBER); @@ -428,22 +512,35 @@ public class CallLogAdapter extends GroupingListAdapter mViewTreeObserver = views.rootView.getViewTreeObserver(); mViewTreeObserver.addOnPreDrawListener(this); } - Trace.endSection(); } @Override public int getItemCount() { - return super.getItemCount() + (isShowingRecentsTab() ? 1 : 0); + return super.getItemCount() + ((isShowingRecentsTab() || mShowPromoCard) ? 1 : 0); } @Override public int getItemViewType(int position) { if (position == getItemCount() - 1 && isShowingRecentsTab()) { return VIEW_TYPE_SHOW_CALL_HISTORY_LIST_ITEM; + } else if (position == VOICEMAIL_PROMO_CARD_POSITION && mShowPromoCard) { + return VIEW_TYPE_VOICEMAIL_PROMO_CARD; } return super.getItemViewType(position); } + /** + * Retrieves an item at the specified position, taking into account the presence of a promo + * card. + * + * @param position The position to retrieve. + * @return The item at that position. + */ + @Override + public Object getItem(int position) { + return super.getItem(position - (mShowPromoCard ? 1 : 0)); + } + protected boolean isShowingRecentsTab() { return mIsShowingRecentsTab; } @@ -597,4 +694,37 @@ public class CallLogAdapter extends GroupingListAdapter return mContext.getResources().getString(R.string.call_log_header_other); } } + + /** + * Determines if the voicemail promo card should be shown or not. The voicemail promo card will + * be shown as the first item in the voicemail tab. + */ + private void maybeShowVoicemailPromoCard() { + boolean showPromoCard = mPrefs.getBoolean(SHOW_VOICEMAIL_PROMO_CARD, + SHOW_VOICEMAIL_PROMO_CARD_DEFAULT); + mShowPromoCard = (mVoicemailPlaybackPresenter != null) && showPromoCard; + } + + /** + * Dismisses the voicemail promo card and refreshes the call log. + */ + private void dismissVoicemailPromoCard() { + mPrefs.edit().putBoolean(SHOW_VOICEMAIL_PROMO_CARD, false).apply(); + mShowPromoCard = false; + notifyItemRemoved(VOICEMAIL_PROMO_CARD_POSITION); + } + + /** + * Creates the view holder for the voicemail promo card. + * + * @param parent The parent view. + * @return The {@link ViewHolder}. + */ + protected ViewHolder createVoicemailPromoCardViewHolder(ViewGroup parent) { + LayoutInflater inflater = LayoutInflater.from(mContext); + View view = inflater.inflate(R.layout.voicemail_promo_card, parent, false); + + PromoCardViewHolder viewHolder = PromoCardViewHolder.create(view); + return viewHolder; + } } diff --git a/src/com/android/dialer/calllog/PromoCardViewHolder.java b/src/com/android/dialer/calllog/PromoCardViewHolder.java new file mode 100644 index 000000000..4c9602759 --- /dev/null +++ b/src/com/android/dialer/calllog/PromoCardViewHolder.java @@ -0,0 +1,71 @@ +/* + * 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. + */ +package com.android.dialer.calllog; + +import com.android.dialer.R; + +import android.support.v7.widget.CardView; +import android.support.v7.widget.RecyclerView; +import android.view.View; + +/** + * View holder class for a promo card which will appear in the voicemail tab. + */ +public class PromoCardViewHolder extends RecyclerView.ViewHolder { + public static PromoCardViewHolder create(View rootView) { + return new PromoCardViewHolder(rootView); + } + + /** + * The "Settings" button view. + */ + private View mSettingsTextView; + + /** + * The "Ok" button view. + */ + private View mOkTextView; + + /** + * Creates an instance of the {@link ViewHolder}. + * + * @param rootView The root view. + */ + private PromoCardViewHolder(View rootView) { + super(rootView); + + mSettingsTextView = rootView.findViewById(R.id.settings_action); + mOkTextView = rootView.findViewById(R.id.ok_action); + } + + /** + * Retrieves the "Settings" button. + * + * @return The view. + */ + public View getSettingsTextView() { + return mSettingsTextView; + } + + /** + * Retrieves the "Ok" button. + * + * @return The view. + */ + public View getOkTextView() { + return mOkTextView; + } +} |