summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--res/drawable-hdpi/ic_drawer_feedback.pngbin607 -> 0 bytes
-rw-r--r--res/drawable-hdpi/ic_drawer_help.pngbin1106 -> 0 bytes
-rw-r--r--res/drawable-hdpi/ic_menu_feedback.pngbin0 -> 1886 bytes
-rw-r--r--res/drawable-hdpi/ic_menu_help.pngbin0 -> 2189 bytes
-rw-r--r--res/drawable-hdpi/ic_menu_settings.pngbin0 -> 2182 bytes
-rw-r--r--res/drawable-mdpi/ic_drawer_feedback.pngbin537 -> 0 bytes
-rw-r--r--res/drawable-mdpi/ic_drawer_help.pngbin726 -> 0 bytes
-rw-r--r--res/drawable-mdpi/ic_menu_feedback.pngbin0 -> 1617 bytes
-rw-r--r--res/drawable-mdpi/ic_menu_help.pngbin0 -> 1804 bytes
-rw-r--r--res/drawable-mdpi/ic_menu_settings.pngbin0 -> 1799 bytes
-rw-r--r--res/drawable-xhdpi/ic_drawer_feedback.pngbin673 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/ic_drawer_help.pngbin1543 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/ic_menu_feedback.pngbin0 -> 1997 bytes
-rw-r--r--res/drawable-xhdpi/ic_menu_help.pngbin0 -> 2688 bytes
-rw-r--r--res/drawable-xhdpi/ic_menu_settings.pngbin0 -> 2432 bytes
-rw-r--r--res/drawable-xxhdpi/ic_drawer_feedback.pngbin1121 -> 0 bytes
-rw-r--r--res/drawable-xxhdpi/ic_drawer_help.pngbin2376 -> 0 bytes
-rw-r--r--res/drawable-xxhdpi/ic_menu_feedback.pngbin0 -> 2541 bytes
-rw-r--r--res/drawable-xxhdpi/ic_menu_help.pngbin0 -> 3605 bytes
-rw-r--r--res/drawable-xxhdpi/ic_menu_settings.pngbin0 -> 3213 bytes
-rw-r--r--res/drawable/shadow_top.xml24
-rw-r--r--res/layout/drawer_footer_item.xml61
-rw-r--r--res/layout/folder_list.xml40
-rw-r--r--res/values-h480dp/constants.xml20
-rw-r--r--res/values-ldrtl/styles-ldrtl.xml2
-rw-r--r--res/values/colors.xml4
-rw-r--r--res/values/constants.xml3
-rw-r--r--res/values/dimen.xml5
-rw-r--r--res/values/styles.xml2
-rw-r--r--src/com/android/mail/browse/ScrollIndicatorsView.java17
-rw-r--r--src/com/android/mail/providers/DrawerClosedObserver.java5
-rw-r--r--src/com/android/mail/ui/AbstractActivityController.java63
-rw-r--r--src/com/android/mail/ui/ActivityController.java2
-rw-r--r--src/com/android/mail/ui/ControllableActivity.java2
-rw-r--r--src/com/android/mail/ui/DrawerController.java32
-rw-r--r--src/com/android/mail/ui/FolderListFragment.java296
-rw-r--r--src/com/android/mail/ui/FolderSelectionActivity.java10
-rw-r--r--src/com/android/mail/ui/MailActionBarView.java5
-rw-r--r--src/com/android/mail/ui/MailActivity.java5
-rw-r--r--src/com/android/mail/ui/ScrollNotifyingListView.java100
-rw-r--r--src/com/android/mail/utils/MailObservable.java (renamed from src/com/android/mail/utils/Observable.java)4
41 files changed, 620 insertions, 82 deletions
diff --git a/res/drawable-hdpi/ic_drawer_feedback.png b/res/drawable-hdpi/ic_drawer_feedback.png
deleted file mode 100644
index c2221e9c3..000000000
--- a/res/drawable-hdpi/ic_drawer_feedback.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_drawer_help.png b/res/drawable-hdpi/ic_drawer_help.png
deleted file mode 100644
index 47d0e2636..000000000
--- a/res/drawable-hdpi/ic_drawer_help.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_feedback.png b/res/drawable-hdpi/ic_menu_feedback.png
new file mode 100644
index 000000000..9ba3c59ee
--- /dev/null
+++ b/res/drawable-hdpi/ic_menu_feedback.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_help.png b/res/drawable-hdpi/ic_menu_help.png
new file mode 100644
index 000000000..88691a247
--- /dev/null
+++ b/res/drawable-hdpi/ic_menu_help.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_settings.png b/res/drawable-hdpi/ic_menu_settings.png
new file mode 100644
index 000000000..5ab4391dd
--- /dev/null
+++ b/res/drawable-hdpi/ic_menu_settings.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_drawer_feedback.png b/res/drawable-mdpi/ic_drawer_feedback.png
deleted file mode 100644
index 371c40942..000000000
--- a/res/drawable-mdpi/ic_drawer_feedback.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_drawer_help.png b/res/drawable-mdpi/ic_drawer_help.png
deleted file mode 100644
index c98e7c5d0..000000000
--- a/res/drawable-mdpi/ic_drawer_help.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_feedback.png b/res/drawable-mdpi/ic_menu_feedback.png
new file mode 100644
index 000000000..9db3a62f0
--- /dev/null
+++ b/res/drawable-mdpi/ic_menu_feedback.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_help.png b/res/drawable-mdpi/ic_menu_help.png
new file mode 100644
index 000000000..787fddcf7
--- /dev/null
+++ b/res/drawable-mdpi/ic_menu_help.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_settings.png b/res/drawable-mdpi/ic_menu_settings.png
new file mode 100644
index 000000000..c4f723a80
--- /dev/null
+++ b/res/drawable-mdpi/ic_menu_settings.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_drawer_feedback.png b/res/drawable-xhdpi/ic_drawer_feedback.png
deleted file mode 100644
index 25abb5715..000000000
--- a/res/drawable-xhdpi/ic_drawer_feedback.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_drawer_help.png b/res/drawable-xhdpi/ic_drawer_help.png
deleted file mode 100644
index 0db695820..000000000
--- a/res/drawable-xhdpi/ic_drawer_help.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_feedback.png b/res/drawable-xhdpi/ic_menu_feedback.png
new file mode 100644
index 000000000..76f511bfa
--- /dev/null
+++ b/res/drawable-xhdpi/ic_menu_feedback.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_help.png b/res/drawable-xhdpi/ic_menu_help.png
new file mode 100644
index 000000000..24e913e02
--- /dev/null
+++ b/res/drawable-xhdpi/ic_menu_help.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_settings.png b/res/drawable-xhdpi/ic_menu_settings.png
new file mode 100644
index 000000000..13cbb9260
--- /dev/null
+++ b/res/drawable-xhdpi/ic_menu_settings.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_drawer_feedback.png b/res/drawable-xxhdpi/ic_drawer_feedback.png
deleted file mode 100644
index c447252e0..000000000
--- a/res/drawable-xxhdpi/ic_drawer_feedback.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_drawer_help.png b/res/drawable-xxhdpi/ic_drawer_help.png
deleted file mode 100644
index 8a7ebac64..000000000
--- a/res/drawable-xxhdpi/ic_drawer_help.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_menu_feedback.png b/res/drawable-xxhdpi/ic_menu_feedback.png
new file mode 100644
index 000000000..f996c118e
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_menu_feedback.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_menu_help.png b/res/drawable-xxhdpi/ic_menu_help.png
new file mode 100644
index 000000000..2b2252149
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_menu_help.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_menu_settings.png b/res/drawable-xxhdpi/ic_menu_settings.png
new file mode 100644
index 000000000..95a310f53
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_menu_settings.png
Binary files differ
diff --git a/res/drawable/shadow_top.xml b/res/drawable/shadow_top.xml
new file mode 100644
index 000000000..1863ec6ed
--- /dev/null
+++ b/res/drawable/shadow_top.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 Google Inc.
+ Licensed to 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">
+ <gradient
+ android:angle="90"
+ android:startColor="#22000000"
+ android:endColor="@android:color/transparent" />
+</shape>
diff --git a/res/layout/drawer_footer_item.xml b/res/layout/drawer_footer_item.xml
index 69bd4a8f9..d890bcfff 100644
--- a/res/layout/drawer_footer_item.xml
+++ b/res/layout/drawer_footer_item.xml
@@ -17,30 +17,43 @@
-->
<!-- Item in the drawer that launches the Help or Feedback activities. -->
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/drawer_footer_view"
- android:layout_height="wrap_content"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:paddingLeft="@dimen/drawer_footer_item_padding"
- android:paddingRight="@dimen/drawer_footer_item_padding"
- android:minHeight="@dimen/drawer_footer_item_minimum_height"
- android:gravity="center_vertical"
- android:background="@drawable/nonfolder_item">
-
- <ImageView
- android:id="@+id/drawer_footer_image"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:duplicateParentState="true"/>
+ android:layout_height="wrap_content"
+ android:background="@color/footer_background_color">
- <TextView
- android:id="@+id/drawer_footer_text"
+ <LinearLayout
android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:ellipsize="end"
- android:textColor="@color/dark_gray_text_color"
- android:textAllCaps="true"
- android:textAppearance="?android:attr/textAppearanceMedium"
- style="@style/DrawerFooterListItemStyle"/>
-</LinearLayout>
+ android:layout_width="match_parent"
+ android:paddingLeft="@dimen/drawer_footer_item_padding"
+ android:paddingRight="@dimen/drawer_footer_item_padding"
+ android:minHeight="@dimen/drawer_footer_item_minimum_height"
+ android:gravity="center_vertical"
+ android:background="@drawable/nonfolder_item">
+
+ <ImageView
+ android:id="@+id/drawer_footer_image"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <TextView
+ android:id="@+id/drawer_footer_text"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:ellipsize="end"
+ android:textColor="@color/dark_gray_text_color"
+ android:textAllCaps="true"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ style="@style/DrawerFooterListItemStyle"/>
+ </LinearLayout>
+
+ <!-- This top "border" is deliberately inset into the item to prevent it from interfering -->
+ <!-- visually with its floaty counterpart. This is also why it isn't just its own list item. -->
+ <View
+ android:id="@+id/top_border"
+ android:layout_width="match_parent"
+ android:layout_height="2dp"
+ android:background="@color/separator_color"
+ android:visibility="gone" />
+
+</FrameLayout>
diff --git a/res/layout/folder_list.xml b/res/layout/folder_list.xml
index 59c294aeb..c5afea0f1 100644
--- a/res/layout/folder_list.xml
+++ b/res/layout/folder_list.xml
@@ -20,10 +20,44 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
- <ListView
+ <com.android.mail.ui.ScrollNotifyingListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:drawSelectorOnTop="false"
- android:fadingEdge="none"/>
+ android:fadingEdge="none"
+ android:scrollbars="none" />
+
+ <LinearLayout
+ android:id="@+id/floaty_footer"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom"
+ android:orientation="vertical">
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="8dp"
+ android:background="@drawable/shadow_top" />
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="@color/separator_color" />
+
+ <LinearLayout
+ android:id="@+id/floaty_footer_items"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:background="@color/list_background_color">
+ </LinearLayout>
+
+ </LinearLayout>
+
+ <com.android.mail.browse.ScrollIndicatorsView
+ android:id="@+id/scroll_indicators"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scrollbars="vertical" />
+
</com.android.mail.ui.FolderListLayout>
diff --git a/res/values-h480dp/constants.xml b/res/values-h480dp/constants.xml
new file mode 100644
index 000000000..07d306609
--- /dev/null
+++ b/res/values-h480dp/constants.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 Google Inc.
+ Licensed to 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.
+-->
+<resources>
+ <bool name="show_drawer_floaty_footer">true</bool>
+</resources>
diff --git a/res/values-ldrtl/styles-ldrtl.xml b/res/values-ldrtl/styles-ldrtl.xml
index 760e2b5fa..6d7162c20 100644
--- a/res/values-ldrtl/styles-ldrtl.xml
+++ b/res/values-ldrtl/styles-ldrtl.xml
@@ -91,7 +91,7 @@
</style>
<style name="DrawerFooterListItemStyle">
- <item name="android:paddingStart">@dimen/drawer_footer_item_padding</item>
+ <item name="android:paddingStart">@dimen/drawer_footer_text_padding_start</item>
</style>
<style name="DismissSeparatorStyle">
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 875b16ec5..0ee3d0a6c 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -45,7 +45,9 @@
<!-- Folder List/Drawer colors -->
<color name="account_item_selected_text_color">@color/mail_app_blue</color>
<color name="folder_list_heading_text_color">@color/dark_gray_text_color</color>
- <color name="list_background_color">#eeeeee</color>
+ <color name="list_background_color">@android:color/white</color>
+ <color name="footer_background_color">#eeeeee</color>
+ <color name="separator_color">#bebebe</color>
<!-- Compose colors -->
<color name="compose_label_text">#aaaaaa</color>
diff --git a/res/values/constants.xml b/res/values/constants.xml
index f52c3560f..1606aa1d9 100644
--- a/res/values/constants.xml
+++ b/res/values/constants.xml
@@ -61,6 +61,9 @@
<!-- Whether to show single or 2 pane search results -->
<bool name="show_two_pane_search_results">false</bool>
+ <!-- this is off for shortish devices. values-h480dp enables this for anything tallish -->
+ <bool name="show_drawer_floaty_footer">false</bool>
+
<!-- Whether to show the archive item as disabled rather than hiding it entirely -->
<bool name="show_disabled_archive_menu_item">false</bool>
diff --git a/res/values/dimen.xml b/res/values/dimen.xml
index 3e96c2d5f..c34b31fdf 100644
--- a/res/values/dimen.xml
+++ b/res/values/dimen.xml
@@ -91,8 +91,9 @@
<dimen name="account_item_minimum_height">48dip</dimen>
<dimen name="account_item_swatch_height">8dip</dimen>
<dimen name="account_item_folder_color_width">36dip</dimen>
- <dimen name="drawer_footer_item_padding">9dp</dimen>
- <dimen name="drawer_footer_item_minimum_height">48dp</dimen>
+ <dimen name="drawer_footer_item_padding">6dp</dimen>
+ <dimen name="drawer_footer_text_padding_start">8dp</dimen>
+ <dimen name="drawer_footer_item_minimum_height">40dp</dimen>
<dimen name="widget_subject_font_size">13sp</dimen>
<dimen name="widget_date_font_size">12sp</dimen>
<dimen name="widget_margin_top">0dip</dimen>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index a6565f9e7..7340a8bf5 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -578,7 +578,7 @@
</style>
<style name="DrawerFooterListItemStyle">
- <item name="android:paddingLeft">@dimen/drawer_footer_item_padding</item>
+ <item name="android:paddingLeft">@dimen/drawer_footer_text_padding_start</item>
</style>
<style name="DismissSeparatorStyle">
diff --git a/src/com/android/mail/browse/ScrollIndicatorsView.java b/src/com/android/mail/browse/ScrollIndicatorsView.java
index b5562c578..3a3055b13 100644
--- a/src/com/android/mail/browse/ScrollIndicatorsView.java
+++ b/src/com/android/mail/browse/ScrollIndicatorsView.java
@@ -1,4 +1,19 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
+/*
+ * Copyright (C) 2011 Google Inc.
+ * Licensed to 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.mail.browse;
diff --git a/src/com/android/mail/providers/DrawerClosedObserver.java b/src/com/android/mail/providers/DrawerClosedObserver.java
index 55d76fb8f..1ab805924 100644
--- a/src/com/android/mail/providers/DrawerClosedObserver.java
+++ b/src/com/android/mail/providers/DrawerClosedObserver.java
@@ -18,14 +18,19 @@
package com.android.mail.providers;
import android.database.DataSetObserver;
+import android.support.v4.widget.DrawerLayout.DrawerListener;
import com.android.mail.ui.AccountController;
+import com.android.mail.ui.DrawerController;
import com.android.mail.ui.RecentFolderController;
/**
* Observes when the drawer is closed for the purpose of computing after the drawer is,
* potentially, off-screen.
+ *
+ * @deprecated TODO: switch this over to {@link DrawerController} and regular {@link DrawerListener}
*/
+@Deprecated
public abstract class DrawerClosedObserver extends DataSetObserver {
private AccountController mController;
diff --git a/src/com/android/mail/ui/AbstractActivityController.java b/src/com/android/mail/ui/AbstractActivityController.java
index 2b8cfefa9..83c3a13d3 100644
--- a/src/com/android/mail/ui/AbstractActivityController.java
+++ b/src/com/android/mail/ui/AbstractActivityController.java
@@ -41,6 +41,7 @@ import android.content.res.Resources;
import android.database.Cursor;
import android.database.DataSetObservable;
import android.database.DataSetObserver;
+import android.database.Observable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
@@ -100,8 +101,8 @@ import com.android.mail.utils.ContentProviderTask;
import com.android.mail.utils.DrawIdler;
import com.android.mail.utils.LogTag;
import com.android.mail.utils.LogUtils;
+import com.android.mail.utils.MailObservable;
import com.android.mail.utils.NotificationActionUtils;
-import com.android.mail.utils.Observable;
import com.android.mail.utils.Utils;
import com.android.mail.utils.VeiledAddressMatcher;
import com.google.common.base.Objects;
@@ -230,7 +231,7 @@ public abstract class AbstractActivityController implements ActivityController,
private final Set<Uri> mCurrentAccountUris = Sets.newHashSet();
protected ConversationCursor mConversationListCursor;
- private final DataSetObservable mConversationListObservable = new Observable("List");
+ private final DataSetObservable mConversationListObservable = new MailObservable("List");
/** Runnable that checks the logging level to enable/disable the logging service. */
private Runnable mLogServiceChecker = null;
@@ -255,15 +256,15 @@ public abstract class AbstractActivityController implements ActivityController,
private RefreshTimerTask mConversationListRefreshTask;
/** Listeners that are interested in changes to the current account. */
- private final DataSetObservable mAccountObservers = new Observable("Account");
+ private final DataSetObservable mAccountObservers = new MailObservable("Account");
/** Listeners that are interested in changes to the recent folders. */
- private final DataSetObservable mRecentFolderObservers = new Observable("RecentFolder");
+ private final DataSetObservable mRecentFolderObservers = new MailObservable("RecentFolder");
/** Listeners that are interested in changes to the list of all accounts. */
- private final DataSetObservable mAllAccountObservers = new Observable("AllAccounts");
+ private final DataSetObservable mAllAccountObservers = new MailObservable("AllAccounts");
/** Listeners that are interested in changes to the current folder. */
- private final DataSetObservable mFolderObservable = new Observable("CurrentFolder");
+ private final DataSetObservable mFolderObservable = new MailObservable("CurrentFolder");
/** Listeners that are interested in changes to the drawer state. */
- private final DataSetObservable mDrawerObservers = new Observable("Drawer");
+ private final DataSetObservable mDrawerObservers = new MailObservable("Drawer");
/**
* Selected conversations, if any.
@@ -470,7 +471,7 @@ public abstract class AbstractActivityController implements ActivityController,
protected ListView mListViewForAnimating;
protected boolean mHasNewAccountOrFolder;
private boolean mConversationListLoadFinishedIgnored;
- protected MailDrawerListener mDrawerListener;
+ private final MailDrawerListener mDrawerListener = new MailDrawerListener();
private boolean mHideMenuItems;
private final DrawIdler mDrawIdler = new DrawIdler();
@@ -1255,7 +1256,6 @@ public abstract class AbstractActivityController implements ActivityController,
mDrawerToggle = new ActionBarDrawerToggle((Activity) mActivity, mDrawerContainer,
R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close);
- mDrawerListener = new MailDrawerListener();
mDrawerContainer.setDrawerListener(mDrawerListener);
mDrawerContainer.setDrawerShadow(
mContext.getResources().getDrawable(R.drawable.drawer_shadow), Gravity.START);
@@ -4144,7 +4144,13 @@ public abstract class AbstractActivityController implements ActivityController,
mDetachedConvUri = null;
}
- private class MailDrawerListener implements DrawerLayout.DrawerListener {
+ @Override
+ public DrawerController getDrawerController() {
+ return mDrawerListener;
+ }
+
+ private class MailDrawerListener extends Observable<DrawerLayout.DrawerListener>
+ implements DrawerLayout.DrawerListener, DrawerController {
private int mDrawerState;
private float mOldSlideOffset;
@@ -4154,8 +4160,32 @@ public abstract class AbstractActivityController implements ActivityController,
}
@Override
+ public void registerDrawerListener(DrawerLayout.DrawerListener l) {
+ registerObserver(l);
+ }
+
+ @Override
+ public void unregisterDrawerListener(DrawerLayout.DrawerListener l) {
+ unregisterObserver(l);
+ }
+
+ @Override
+ public boolean isDrawerOpen() {
+ return isDrawerEnabled() && mDrawerContainer.isDrawerOpen(mDrawerPullout);
+ }
+
+ @Override
+ public boolean isDrawerVisible() {
+ return isDrawerEnabled() && mDrawerContainer.isDrawerVisible(mDrawerPullout);
+ }
+
+ @Override
public void onDrawerOpened(View drawerView) {
mDrawerToggle.onDrawerOpened(drawerView);
+
+ for (DrawerLayout.DrawerListener l : mObservers) {
+ l.onDrawerOpened(drawerView);
+ }
}
@Override
@@ -4169,6 +4199,10 @@ public abstract class AbstractActivityController implements ActivityController,
final int mode = mViewMode.getMode();
final boolean isTopLevel = (mFolder == null) || (mFolder.parent == Uri.EMPTY);
mDrawerToggle.setDrawerIndicatorEnabled(getShouldShowDrawerIndicator(mode, isTopLevel));
+
+ for (DrawerLayout.DrawerListener l : mObservers) {
+ l.onDrawerClosed(drawerView);
+ }
}
/**
@@ -4220,6 +4254,10 @@ public abstract class AbstractActivityController implements ActivityController,
// If we're sliding, we always want to show the burger
mDrawerToggle.setDrawerIndicatorEnabled(true /* enable */);
+
+ for (DrawerLayout.DrawerListener l : mObservers) {
+ l.onDrawerSlide(drawerView, slideOffset);
+ }
}
/**
@@ -4232,6 +4270,11 @@ public abstract class AbstractActivityController implements ActivityController,
LogUtils.d(LOG_TAG, "AAC onDrawerStateChanged %d", newState);
mDrawerState = newState;
mDrawerToggle.onDrawerStateChanged(mDrawerState);
+
+ for (DrawerLayout.DrawerListener l : mObservers) {
+ l.onDrawerStateChanged(newState);
+ }
+
if (mViewMode.isSearchMode()) {
return;
}
diff --git a/src/com/android/mail/ui/ActivityController.java b/src/com/android/mail/ui/ActivityController.java
index b8ec206cf..93d6699d1 100644
--- a/src/com/android/mail/ui/ActivityController.java
+++ b/src/com/android/mail/ui/ActivityController.java
@@ -326,4 +326,6 @@ public interface ActivityController extends LayoutListener,
* items that are not applicable while the drawer is open.
*/
public boolean shouldHideMenuItems();
+
+ DrawerController getDrawerController();
}
diff --git a/src/com/android/mail/ui/ControllableActivity.java b/src/com/android/mail/ui/ControllableActivity.java
index 72c113c4c..b85eec06e 100644
--- a/src/com/android/mail/ui/ControllableActivity.java
+++ b/src/com/android/mail/ui/ControllableActivity.java
@@ -96,6 +96,8 @@ public interface ControllableActivity extends HelpCallback, RestrictedActivity,
UpOrBackController getUpOrBackController();
+ DrawerController getDrawerController();
+
void startDragMode();
void stopDragMode();
diff --git a/src/com/android/mail/ui/DrawerController.java b/src/com/android/mail/ui/DrawerController.java
new file mode 100644
index 000000000..4ab0becf8
--- /dev/null
+++ b/src/com/android/mail/ui/DrawerController.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2014 Google Inc.
+ * Licensed to 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.mail.ui;
+
+import android.support.v4.widget.DrawerLayout;
+
+/**
+ * Drawer-related functionality.
+ */
+public interface DrawerController {
+
+ void registerDrawerListener(DrawerLayout.DrawerListener l);
+ void unregisterDrawerListener(DrawerLayout.DrawerListener l);
+ boolean isDrawerOpen();
+ boolean isDrawerVisible();
+
+}
diff --git a/src/com/android/mail/ui/FolderListFragment.java b/src/com/android/mail/ui/FolderListFragment.java
index b6bff1937..bf703edfc 100644
--- a/src/com/android/mail/ui/FolderListFragment.java
+++ b/src/com/android/mail/ui/FolderListFragment.java
@@ -17,15 +17,21 @@
package com.android.mail.ui;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
import android.app.Activity;
import android.app.ListFragment;
import android.app.LoaderManager;
import android.content.Loader;
import android.net.Uri;
import android.os.Bundle;
+import android.support.v4.widget.DrawerLayout;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.Interpolator;
+import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.ImageView;
@@ -37,6 +43,7 @@ import com.android.mail.R;
import com.android.mail.adapter.DrawerItem;
import com.android.mail.analytics.Analytics;
import com.android.mail.browse.MergedAdapter;
+import com.android.mail.browse.ScrollIndicatorsView;
import com.android.mail.content.ObjectCursor;
import com.android.mail.content.ObjectCursorLoader;
import com.android.mail.providers.Account;
@@ -97,6 +104,7 @@ public class FolderListFragment extends ListFragment implements
private ControllableActivity mActivity;
/** The underlying list view */
private ListView mListView;
+ private ViewGroup mFloatyFooter;
/** URI that points to the list of folders for the current account. */
private Uri mFolderListUri;
/**
@@ -176,6 +184,15 @@ public class FolderListFragment extends ListFragment implements
private FolderWatcher mFolderWatcher = null;
private boolean mRegistered = false;
+ private final DrawerStateListener mDrawerListener = new DrawerStateListener();
+
+ private boolean mShowFooter;
+
+ private boolean mFooterIsAnimating = false;
+
+ private static final Interpolator INTERPOLATOR_SHOW_FLOATY = new DecelerateInterpolator(2.0f);
+ private static final Interpolator INTERPOLATOR_HIDE_FLOATY = new DecelerateInterpolator();
+
/**
* Constructor needs to be public to handle orientation changes and activity lifecycle events.
*/
@@ -256,7 +273,7 @@ public class FolderListFragment extends ListFragment implements
// activity is creating ConversationListFragments. This activity must be of type
// ControllableActivity.
final Activity activity = getActivity();
- if (! (activity instanceof ControllableActivity)){
+ if (!(activity instanceof ControllableActivity)) {
LogUtils.wtf(LOG_TAG, "FolderListFragment expects only a ControllableActivity to" +
"create it. Cannot proceed.");
return;
@@ -292,6 +309,7 @@ public class FolderListFragment extends ListFragment implements
mAccountsAdapter = newAccountsAdapter();
mFooterAdapter = new FooterAdapter();
+ updateFloatyFooter();
// Is the selected folder fresher than the one we have restored from a bundle?
if (selectedFolder != null
@@ -344,6 +362,8 @@ public class FolderListFragment extends ListFragment implements
}
};
mDrawerObserver.initialize(accountController);
+
+ mActivity.getDrawerController().registerDrawerListener(mDrawerListener);
}
if (mActivity.isFinishing()) {
@@ -384,7 +404,9 @@ public class FolderListFragment extends ListFragment implements
setInstanceFromBundle(getArguments());
final View rootView = inflater.inflate(R.layout.folder_list, null);
- mListView = (ListView) rootView.findViewById(android.R.id.list);
+ final ScrollNotifyingListView lv = (ScrollNotifyingListView) rootView.findViewById(
+ android.R.id.list);
+ mListView = lv;
mListView.setEmptyView(null);
mListView.setDivider(null);
if (savedState != null && savedState.containsKey(BUNDLE_LIST_STATE)) {
@@ -400,6 +422,49 @@ public class FolderListFragment extends ListFragment implements
// No selected folder type required for hierarchical lists.
}
+ mShowFooter = getResources().getBoolean(R.bool.show_help_and_feedback_in_drawer);
+
+ final boolean floatyFooterEnabled = mShowFooter && getResources().getBoolean(
+ R.bool.show_drawer_floaty_footer);
+ final ViewGroup ff = (ViewGroup) rootView.findViewById(R.id.floaty_footer);
+ ff.setVisibility(floatyFooterEnabled ? View.VISIBLE : View.GONE);
+ if (floatyFooterEnabled) {
+ mFloatyFooter = ff;
+ }
+
+ final ScrollIndicatorsView scrollbars =
+ (ScrollIndicatorsView) rootView.findViewById(R.id.scroll_indicators);
+ scrollbars.setSourceView(lv);
+
+ mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
+
+ private int mLastState = AbsListView.OnScrollListener.SCROLL_STATE_IDLE;
+
+ @Override
+ public void onScrollStateChanged(AbsListView view, int scrollState) {
+ mLastState = scrollState;
+ }
+
+ @Override
+ public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
+ int totalItemCount) {
+ // have the floaty footer react only after some non-zero scroll movement
+ if (mLastState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
+ // ignore onScrolls that are generated as the list data is updated
+ return;
+ }
+
+ if (mListView.canScrollVertically(-1)) {
+ // typically we want scroll motion to hide the floaty footer
+ hideFloatyFooter();
+ } else {
+ // except at the top, when we should show it
+ showFloatyFooter(false /* onlyWhenClosed */);
+ }
+ }
+
+ });
+
return rootView;
}
@@ -455,6 +520,10 @@ public class FolderListFragment extends ListFragment implements
mDrawerObserver = null;
}
super.onDestroyView();
+
+ if (mActivity != null) {
+ mActivity.getDrawerController().unregisterDrawerListener(mDrawerListener);
+ }
}
@Override
@@ -520,7 +589,7 @@ public class FolderListFragment extends ListFragment implements
folder = (Folder) item;
} else if (item instanceof FooterItem) {
folder = null;
- ((FooterItem) item).onFolderItemClicked();
+ ((FooterItem) item).onClick(null /* unused */);
} else {
// Don't know how we got here.
LogUtils.wtf(LOG_TAG, "viewFolderOrChangeAccount(): invalid item");
@@ -588,6 +657,9 @@ public class FolderListFragment extends ListFragment implements
} else if (loader.getId() == ALL_FOLDER_LIST_LOADER_ID) {
mFolderAdapter.setAllFolderListCursor(data);
}
+ // new data means drawer list length may have changed, and the floaty footer visibility
+ // may need to be updated
+ showFloatyFooter(true /* onlyWhenClosed */);
}
}
@@ -1122,6 +1194,9 @@ public class FolderListFragment extends ListFragment implements
final FooterItem item = (FooterItem) getItem(position);
+ footerItemView.findViewById(R.id.top_border).setVisibility(
+ item.shouldShowTopBorder() ? View.VISIBLE : View.GONE);
+
// adjust the text of the footer item
final TextView textView = (TextView) footerItemView.
findViewById(R.id.drawer_footer_text);
@@ -1139,23 +1214,30 @@ public class FolderListFragment extends ListFragment implements
* is populated with URIs that navigate to appropriate destinations.
*/
private void update() {
+ // if the parent activity shows a drawer, these items should participate in that drawer
+ // (if it shows a *pane* they should *not* participate in that pane)
+ if (!mShowFooter) {
+ return;
+ }
+
mFooterItems.clear();
- final boolean showHelpAndFeedback = getResources()
- .getBoolean(R.bool.show_help_and_feedback_in_drawer);
+ if (mCurrentAccount != null) {
+ mFooterItems.add(new SettingsItem());
+ }
- // if the parent activity shows a drawer, these items should participate in that drawer
- // (if it shows a *pane* they should *not* participate in that pane)
- if (showHelpAndFeedback) {
- if (mCurrentAccount != null && !Utils.isEmpty(mCurrentAccount.helpIntentUri)) {
- mFooterItems.add(new HelpFooterItem());
- }
+ if (mCurrentAccount != null && !Utils.isEmpty(mCurrentAccount.helpIntentUri)) {
+ mFooterItems.add(new HelpItem());
+ }
- // if a feedback Uri exists, show the Feedback drawer item
- if (mCurrentAccount != null &&
- !Utils.isEmpty(mCurrentAccount.sendFeedbackIntentUri)) {
- mFooterItems.add(new FeedbackFooterItem());
- }
+ // if a feedback Uri exists, show the Feedback drawer item
+ if (mCurrentAccount != null &&
+ !Utils.isEmpty(mCurrentAccount.sendFeedbackIntentUri)) {
+ mFooterItems.add(new FeedbackItem());
+ }
+
+ if (!mFooterItems.isEmpty()) {
+ mFooterItems.get(0).setShowTopBorder(true);
}
notifyDataSetChanged();
@@ -1202,13 +1284,13 @@ public class FolderListFragment extends ListFragment implements
* Sets the current account to the one provided here.
* @param account the current account to set to.
*/
- private void setSelectedAccount(Account account){
+ private void setSelectedAccount(Account account) {
final boolean changed = (account != null) && (mCurrentAccount == null
|| !mCurrentAccount.uri.equals(account.uri));
mCurrentAccount = account;
if (changed) {
// Verify that the new account supports sending application feedback
- mFooterAdapter.update();
+ updateFooterItems();
// We no longer have proper folder objects. Let the new ones come in
mFolderAdapter.setCursor(null);
// If currentAccount is different from the one we set, restart the loader. Look at the
@@ -1234,6 +1316,33 @@ public class FolderListFragment extends ListFragment implements
}
}
+ private void updateFooterItems() {
+ mFooterAdapter.update();
+ updateFloatyFooter();
+ }
+
+ private void updateFloatyFooter() {
+ if (mFloatyFooter == null) {
+ return;
+ }
+
+ // assuming this isn't often (the caller is debounced), just remake the floaty footer
+ // from scratch
+ final ViewGroup container = (ViewGroup) mFloatyFooter.findViewById(
+ R.id.floaty_footer_items);
+ container.removeAllViews();
+
+ for (int i = 0; i < mFooterAdapter.getCount(); i++) {
+ final View v = mFooterAdapter.getView(i, null /* convertView */, mFloatyFooter);
+ // the floaty version has its own top border, so remove the list version's border
+ if (i == 0) {
+ v.findViewById(R.id.top_border).setVisibility(View.GONE);
+ }
+ v.setOnClickListener((FooterItem) mFooterAdapter.getItem(i));
+ container.addView(v);
+ }
+ }
+
/**
* Checks if the specified {@link Folder} is a type that we want to exclude from displaying.
*/
@@ -1258,15 +1367,72 @@ public class FolderListFragment extends ListFragment implements
return mAccountController.getFolderListViewChoiceMode();
}
+ private void showFloatyFooter(boolean onlyWhenClosed) {
+ // don't ever show if the footer is disabled (in onCreateView)
+ if (mFloatyFooter == null) {
+ return;
+ }
+
+ // don't show when onLoadFinished is the reason to show it, and the drawer is open
+ // (minimize user-visible changes; that case is basically only relevant when closed)
+ final boolean drawerIsOpen = mActivity.getDrawerController().isDrawerOpen();
+ if (onlyWhenClosed && drawerIsOpen) {
+ return;
+ }
+
+ // show the footer, unless if we're already at the very bottom
+ final int vis = getListView().canScrollVertically(+1) ? View.VISIBLE : View.GONE;
+
+ mFloatyFooter.animate().cancel();
+ if (drawerIsOpen && vis == View.VISIBLE) {
+ mFloatyFooter.animate()
+ .translationY(0f)
+ .setDuration(150)
+ .setInterpolator(INTERPOLATOR_SHOW_FLOATY)
+ .setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mFloatyFooter.setVisibility(vis);
+ }
+ });
+ } else {
+ mFloatyFooter.setTranslationY(0f);
+ mFloatyFooter.setVisibility(vis);
+ }
+
+ }
+
+ private void hideFloatyFooter() {
+ if (mFloatyFooter == null || mFloatyFooter.getVisibility() == View.GONE
+ || mFooterIsAnimating) {
+ return;
+ }
+ mFooterIsAnimating = true;
+ mFloatyFooter.animate().cancel();
+ mFloatyFooter.animate()
+ .translationY(mFloatyFooter.getHeight())
+ .setDuration(200)
+ .setInterpolator(INTERPOLATOR_HIDE_FLOATY)
+ .setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mFooterIsAnimating = false;
+ mFloatyFooter.setVisibility(View.GONE);
+ }
+ });
+ }
+
/**
* The base class of all footer items. Subclasses must fill in the logic of
- * {@link #onFolderItemClicked()} which contains the behavior when the item is selected.
+ * {@link #doFooterAction()} which contains the behavior when the item is selected.
*/
- private abstract class FooterItem {
+ private abstract class FooterItem implements View.OnClickListener {
private final int mImageResourceID;
private final int mTextResourceID;
+ private boolean mShowTopBorder;
+
private FooterItem(final int imageResourceID, final int textResourceID) {
mImageResourceID = imageResourceID;
mTextResourceID = textResourceID;
@@ -1281,34 +1447,94 @@ public class FolderListFragment extends ListFragment implements
}
/**
- * Executes the behavior associated with this footer item.
+ * Executes the behavior associated with this footer item.<br>
+ * <br>
+ * WARNING: you probably don't want to call this directly; use
+ * {@link #onClick(View)} instead. This method actually performs the action, and its
+ * execution is deferred from when the 'click' happens so we can smoothly close the drawer
+ * beforehand.
*/
- abstract void onFolderItemClicked();
+ abstract void doFooterAction();
+
+ @Override
+ public final void onClick(View v) {
+ // close the drawer and defer handling the click until onDrawerClosed
+ mAccountController.closeDrawer(false /* hasNewFolderOrAccount */,
+ null /* nextAccount */, null /* nextFolder */);
+ mDrawerListener.setPendingFooterClick(this);
+ }
+
+ public boolean shouldShowTopBorder() {
+ return mShowTopBorder;
+ }
+
+ public void setShowTopBorder(boolean show) {
+ mShowTopBorder = show;
+ }
+
}
- /**
- * The 'Help" footer item.
- */
- private class HelpFooterItem extends FooterItem {
- protected HelpFooterItem() {
- super(R.drawable.ic_drawer_help, R.string.help_and_info);
+ private class HelpItem extends FooterItem {
+ protected HelpItem() {
+ super(R.drawable.ic_menu_help, R.string.help_and_info);
}
- void onFolderItemClicked() {
+ @Override
+ void doFooterAction() {
Utils.showHelp(getActivity(), mCurrentAccount, mActivity.getHelpContext());
}
}
+ private class FeedbackItem extends FooterItem {
+ protected FeedbackItem() {
+ super(R.drawable.ic_menu_feedback, R.string.feedback);
+ }
+
+ @Override
+ void doFooterAction() {
+ Utils.sendFeedback(getActivity(), mCurrentAccount, false);
+ }
+ }
+
+ private class SettingsItem extends FooterItem {
+ protected SettingsItem() {
+ super(R.drawable.ic_menu_settings, R.string.menu_settings);
+ }
+
+ @Override
+ void doFooterAction() {
+ Utils.showSettings(mActivity.getActivityContext(), mCurrentAccount);
+ }
+ }
+
/**
- * The 'Send Feedback" footer item.
+ * Drawer listener for footer functionality to react to drawer state.
*/
- private class FeedbackFooterItem extends FooterItem {
- protected FeedbackFooterItem() {
- super(R.drawable.ic_drawer_feedback, R.string.feedback);
+ private class DrawerStateListener implements DrawerLayout.DrawerListener {
+
+ private FooterItem mPendingFooterClick;
+
+ public void setPendingFooterClick(FooterItem itemClicked) {
+ mPendingFooterClick = itemClicked;
}
- void onFolderItemClicked() {
- Utils.sendFeedback(getActivity(), mCurrentAccount, false);
+ @Override
+ public void onDrawerSlide(View drawerView, float slideOffset) {}
+
+ @Override
+ public void onDrawerOpened(View drawerView) {}
+
+ @Override
+ public void onDrawerClosed(View drawerView) {
+ showFloatyFooter(false /* onlyWhenClosed */);
+ if (mPendingFooterClick != null) {
+ mPendingFooterClick.doFooterAction();
+ mPendingFooterClick = null;
+ }
}
+
+ @Override
+ public void onDrawerStateChanged(int newState) {}
+
}
}
diff --git a/src/com/android/mail/ui/FolderSelectionActivity.java b/src/com/android/mail/ui/FolderSelectionActivity.java
index 3573ce6e9..06bf6ab71 100644
--- a/src/com/android/mail/ui/FolderSelectionActivity.java
+++ b/src/com/android/mail/ui/FolderSelectionActivity.java
@@ -39,7 +39,7 @@ import com.android.mail.providers.Folder;
import com.android.mail.providers.FolderWatcher;
import com.android.mail.utils.LogTag;
import com.android.mail.utils.LogUtils;
-import com.android.mail.utils.Observable;
+import com.android.mail.utils.MailObservable;
import com.android.mail.utils.Utils;
import com.android.mail.utils.VeiledAddressMatcher;
import com.android.mail.widget.WidgetProvider;
@@ -67,7 +67,7 @@ public class FolderSelectionActivity extends Activity implements OnClickListener
private int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
private int mMode = -1;
/** Empty placeholder for communicating to the consumer of the drawer observer. */
- private final DataSetObservable mDrawerObservers = new Observable("Drawer");
+ private final DataSetObservable mDrawerObservers = new MailObservable("Drawer");
private final AccountController mAccountController = new AccountController() {
@Override
@@ -451,6 +451,12 @@ public class FolderSelectionActivity extends Activity implements OnClickListener
}
@Override
+ public DrawerController getDrawerController() {
+ // Unsupported
+ return null;
+ }
+
+ @Override
public boolean isAccessibilityEnabled() {
// Unsupported
return true;
diff --git a/src/com/android/mail/ui/MailActionBarView.java b/src/com/android/mail/ui/MailActionBarView.java
index e7458a0b3..2bb9bc8fd 100644
--- a/src/com/android/mail/ui/MailActionBarView.java
+++ b/src/com/android/mail/ui/MailActionBarView.java
@@ -89,6 +89,7 @@ public class MailActionBarView extends LinearLayout implements ViewMode.ModeChan
private Folder mFolder;
private SearchView mSearchWidget;
+ private MenuItem mSettingsItem;
private MenuItem mHelpItem;
private MenuItem mSendFeedbackItem;
private MenuItem mFolderSettingsItem;
@@ -241,6 +242,7 @@ public class MailActionBarView extends LinearLayout implements ViewMode.ModeChan
mSearchWidget.setIconifiedByDefault(true);
}
}
+ mSettingsItem = menu.findItem(R.id.settings);
mHelpItem = menu.findItem(R.id.help_info_menu_item);
mSendFeedbackItem = menu.findItem(R.id.feedback_menu_item);
mFolderSettingsItem = menu.findItem(R.id.folder_options);
@@ -374,6 +376,9 @@ public class MailActionBarView extends LinearLayout implements ViewMode.ModeChan
final boolean showHelpandFeedback = !getResources()
.getBoolean(R.bool.show_help_and_feedback_in_drawer);
+ if (mSettingsItem != null) {
+ mSettingsItem.setVisible(showHelpandFeedback);
+ }
if (mHelpItem != null) {
mHelpItem.setVisible(showHelpandFeedback
&& mAccount != null
diff --git a/src/com/android/mail/ui/MailActivity.java b/src/com/android/mail/ui/MailActivity.java
index 6ff05af4d..802511f52 100644
--- a/src/com/android/mail/ui/MailActivity.java
+++ b/src/com/android/mail/ui/MailActivity.java
@@ -385,6 +385,11 @@ public class MailActivity extends AbstractMailActivity implements ControllableAc
}
@Override
+ public DrawerController getDrawerController() {
+ return mController.getDrawerController();
+ }
+
+ @Override
public void onFooterViewErrorActionClick(Folder folder, int errorStatus) {
mController.onFooterViewErrorActionClick(folder, errorStatus);
}
diff --git a/src/com/android/mail/ui/ScrollNotifyingListView.java b/src/com/android/mail/ui/ScrollNotifyingListView.java
new file mode 100644
index 000000000..d4e65d18e
--- /dev/null
+++ b/src/com/android/mail/ui/ScrollNotifyingListView.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2014 Google Inc.
+ * Licensed to 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.mail.ui;
+
+import android.content.Context;
+import android.database.Observable;
+import android.util.AttributeSet;
+import android.widget.ListView;
+
+import com.android.mail.browse.ScrollNotifier;
+
+/**
+ * Ordinary list view with extra boilerplate to notify on scrollbar-related events (unrelated to
+ * {@link android.widget.AbsListView.OnScrollListener}!)
+ */
+public class ScrollNotifyingListView extends ListView implements ScrollNotifier {
+
+ private final ScrollObservable mObservable = new ScrollObservable();
+
+ public ScrollNotifyingListView(Context c) {
+ this(c, null);
+ }
+
+ public ScrollNotifyingListView(Context c, AttributeSet attrs) {
+ super(c, attrs);
+ }
+
+ @Override
+ public void addScrollListener(ScrollListener l) {
+ mObservable.registerObserver(l);
+ }
+
+ @Override
+ public void removeScrollListener(ScrollListener l) {
+ mObservable.unregisterObserver(l);
+ }
+
+ @Override
+ protected void onScrollChanged(int l, int t, int oldl, int oldt) {
+ super.onScrollChanged(l, t, oldl, oldt);
+ mObservable.onScrollChanged(l, t, oldl, oldt);
+ }
+
+ @Override
+ public int computeVerticalScrollRange() {
+ return super.computeVerticalScrollRange();
+ }
+
+ @Override
+ public int computeVerticalScrollOffset() {
+ return super.computeVerticalScrollOffset();
+ }
+
+ @Override
+ public int computeVerticalScrollExtent() {
+ return super.computeVerticalScrollExtent();
+ }
+
+ @Override
+ public int computeHorizontalScrollRange() {
+ return super.computeHorizontalScrollRange();
+ }
+
+ @Override
+ public int computeHorizontalScrollOffset() {
+ return super.computeHorizontalScrollOffset();
+ }
+
+ @Override
+ public int computeHorizontalScrollExtent() {
+ return super.computeHorizontalScrollExtent();
+ }
+
+ private static class ScrollObservable extends Observable<ScrollListener> {
+
+ @SuppressWarnings("unused")
+ public void onScrollChanged(int l, int t, int oldl, int oldt) {
+ for (ScrollListener sl : mObservers) {
+ sl.onNotifierScroll(t);
+ }
+ }
+
+ }
+
+}
diff --git a/src/com/android/mail/utils/Observable.java b/src/com/android/mail/utils/MailObservable.java
index 81e8d8321..bd67c0a39 100644
--- a/src/com/android/mail/utils/Observable.java
+++ b/src/com/android/mail/utils/MailObservable.java
@@ -23,11 +23,11 @@ import android.database.DataSetObserver;
* A Utility class to register observers and return logging and counts for the number of registered
* observers.
*/
-public class Observable extends DataSetObservable {
+public class MailObservable extends DataSetObservable {
protected static final String LOG_TAG = LogTag.getLogTag();
private final String mName;
- public Observable(String name) {
+ public MailObservable(String name) {
mName = name;
}