Search delay fixes.
- adds a loading state to search so the user isn't left with a blank screen for several seconds - adds a timeout so that a warning message is shown for results that take over 10 seconds - use default loading/no message views in ListFragment so we don't have to manager our own stuff Bug: 5014107 Bug: 5037618 Change-Id: I8b03fa0967055989156c7777901affc777c4fae7
This commit is contained in:
parent
786285b3a6
commit
391b9d4abd
@ -24,16 +24,8 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
>
|
||||
<TextView
|
||||
android:id="@+id/no_messages_panel"
|
||||
android:text="@string/message_list_no_messages"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dip"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
|
||||
<!-- Search header is dynamically inserted here for search results -->
|
||||
|
||||
<include
|
||||
layout="@android:layout/list_content"
|
||||
@ -42,4 +34,7 @@
|
||||
android:layout_height="0dip"
|
||||
android:layout_weight="1"
|
||||
/>
|
||||
|
||||
<!-- Message list error overlays are dynamically inserted here -->
|
||||
|
||||
</LinearLayout>
|
||||
|
54
res/layout/message_list_warning.xml
Normal file
54
res/layout/message_list_warning.xml
Normal file
@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2011 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.
|
||||
-->
|
||||
|
||||
<!--
|
||||
The default ListFragment layout (include) + the "send outgoing message" button.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dip"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center"
|
||||
>
|
||||
|
||||
<ProgressBar style="?android:attr/progressBarStyleLarge"
|
||||
android:id="@+id/spinner"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/message_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dip"
|
||||
android:layout_marginRight="16dip"
|
||||
android:layout_marginTop="4dip"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/message_warning"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="32dip"
|
||||
android:layout_marginRight="32dip"
|
||||
android:layout_marginTop="4dip"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
@ -1215,6 +1215,14 @@ save attachment.</string>
|
||||
<string name="search_header_text_fmt"
|
||||
>Search results for \"<xliff:g example="search query">%1$s</xliff:g>\"</string>
|
||||
|
||||
<!-- A warning title to show to the user when search results are taking a long
|
||||
time. [CHAR LIMIT=NONE] -->
|
||||
<string name="search_slow_warning_title">Waiting for results</string>
|
||||
|
||||
<!-- A warning message to show to the user when search results are taking a long
|
||||
time. [CHAR LIMIT=NONE] -->
|
||||
<string name="search_slow_warning_message">Some servers may take a long time.</string>
|
||||
|
||||
<!-- Title shown on the action bar on the mailbox list screen. [CHAR LIMIT=16] -->
|
||||
<string name="action_bar_mailbox_list_title">Folders</string>
|
||||
|
||||
|
@ -102,11 +102,12 @@ public class MessageListFragment extends ListFragment
|
||||
private Callback mCallback = EmptyCallback.INSTANCE;
|
||||
private boolean mIsViewCreated;
|
||||
|
||||
private View mListPanel;
|
||||
private View mListFooterView;
|
||||
private TextView mListFooterText;
|
||||
private View mListFooterProgress;
|
||||
private View mNoMessagesPanel;
|
||||
private ViewGroup mSearchHeader;
|
||||
private ViewGroup mWarningContainer;
|
||||
private TextView mSearchHeaderText;
|
||||
private TextView mSearchHeaderCount;
|
||||
|
||||
@ -335,7 +336,6 @@ public class MessageListFragment extends ListFragment
|
||||
mRefreshManager = RefreshManager.getInstance(mActivity);
|
||||
|
||||
mListAdapter = new MessagesAdapter(mActivity, this);
|
||||
setListAdapter(mListAdapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -346,8 +346,8 @@ public class MessageListFragment extends ListFragment
|
||||
}
|
||||
// Use a custom layout, which includes the original layout with "send messages" panel.
|
||||
View root = inflater.inflate(R.layout.message_list_fragment,null);
|
||||
mNoMessagesPanel = UiUtilities.getView(root, R.id.no_messages_panel);
|
||||
mIsViewCreated = true;
|
||||
mListPanel = UiUtilities.getView(root, R.id.list_panel);
|
||||
return root;
|
||||
}
|
||||
|
||||
@ -392,6 +392,7 @@ public class MessageListFragment extends ListFragment
|
||||
|
||||
mListFooterView = getActivity().getLayoutInflater().inflate(
|
||||
R.layout.message_list_item_footer, lv, false);
|
||||
setEmptyText(getString(R.string.message_list_no_messages));
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
// Fragment doesn't have this method. Call it manually.
|
||||
@ -543,10 +544,6 @@ public class MessageListFragment extends ListFragment
|
||||
}
|
||||
}
|
||||
|
||||
/* package */MessagesAdapter getAdapterForTest() {
|
||||
return mListAdapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the mailbox is refreshable. false otherwise, or unknown yet.
|
||||
*/
|
||||
@ -1144,11 +1141,6 @@ public class MessageListFragment extends ListFragment
|
||||
&& (mMailbox == null || mMailbox.canHaveMessagesMoved());
|
||||
}
|
||||
|
||||
private void showNoMessageText(boolean visible) {
|
||||
mNoMessagesPanel.setVisibility(visible ? View.VISIBLE : View.GONE);
|
||||
getListView().setVisibility(visible ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts message notification depending upon the state of the fragment and the currently
|
||||
* viewed mailbox. If the fragment is resumed, notifications for the current mailbox may
|
||||
@ -1176,7 +1168,6 @@ public class MessageListFragment extends ListFragment
|
||||
Log.d(Logging.LOG_TAG, this + " startLoading");
|
||||
}
|
||||
// Clear the list. (ListFragment will show the "Loading" animation)
|
||||
showNoMessageText(false);
|
||||
showSendCommand(false);
|
||||
updateSearchHeader(null);
|
||||
|
||||
@ -1185,6 +1176,26 @@ public class MessageListFragment extends ListFragment
|
||||
lm.initLoader(LOADER_ID_MESSAGES_LOADER, null, new MessagesLoaderCallback());
|
||||
}
|
||||
|
||||
/** Timeout to show a warning, since some IMAP searches could take a long time. */
|
||||
private final int SEARCH_WARNING_DELAY_MS = 10000;
|
||||
|
||||
private void onSearchLoadTimeout() {
|
||||
// Search is taking too long. Show an error message.
|
||||
ViewGroup root = (ViewGroup) getView();
|
||||
Activity host = getActivity();
|
||||
if (root != null && host != null) {
|
||||
mListPanel.setVisibility(View.GONE);
|
||||
mWarningContainer = (ViewGroup) LayoutInflater.from(host).inflate(
|
||||
R.layout.message_list_warning, root, false);
|
||||
TextView title = UiUtilities.getView(mWarningContainer, R.id.message_title);
|
||||
TextView message = UiUtilities.getView(mWarningContainer, R.id.message_warning);
|
||||
title.setText(R.string.search_slow_warning_title);
|
||||
message.setText(R.string.search_slow_warning_message);
|
||||
root.addView(mWarningContainer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Loader callbacks for message list.
|
||||
*/
|
||||
@ -1198,6 +1209,29 @@ public class MessageListFragment extends ListFragment
|
||||
Log.d(Logging.LOG_TAG, MessageListFragment.this
|
||||
+ " onCreateLoader(messages) listContext=" + listContext);
|
||||
}
|
||||
|
||||
if (mListContext.isSearch()) {
|
||||
final MessageListContext searchInfo = mListContext;
|
||||
|
||||
// Search results are not primed with local data, and so will usually be slow.
|
||||
// In some cases, they could take a long time to return, so we need to be robust.
|
||||
setListShownNoAnimation(false);
|
||||
Utility.getMainThreadHandler().postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mListContext != searchInfo) {
|
||||
// Different list is being shown now.
|
||||
return;
|
||||
}
|
||||
if (!mIsFirstLoad) {
|
||||
// Something already returned. No need to do anything.
|
||||
return;
|
||||
}
|
||||
onSearchLoadTimeout();
|
||||
}
|
||||
}, SEARCH_WARNING_DELAY_MS);
|
||||
}
|
||||
|
||||
mIsFirstLoad = true;
|
||||
return MessagesAdapter.createLoader(getActivity(), listContext);
|
||||
}
|
||||
@ -1258,8 +1292,6 @@ public class MessageListFragment extends ListFragment
|
||||
autoRefreshStaleMailbox();
|
||||
addFooterView();
|
||||
updateSelectionMode();
|
||||
showNoMessageText((cursor.getCount() == 0)
|
||||
&& (getListContext().isSearch() || (mListFooterMode == LIST_FOOTER_MODE_NONE)));
|
||||
|
||||
// We want to make visible the selection only for the first load.
|
||||
// Re-load caused by content changed events shouldn't scroll the list.
|
||||
@ -1269,7 +1301,12 @@ public class MessageListFragment extends ListFragment
|
||||
// "post processing" seems to reset the scroll position.
|
||||
lv.onRestoreInstanceState(listState);
|
||||
|
||||
// Clear this for next reload triggered by content changed events.
|
||||
if (mIsFirstLoad) {
|
||||
setListShownNoAnimation(true);
|
||||
UiUtilities.setVisibilitySafe(mWarningContainer, View.GONE);
|
||||
mListPanel.setVisibility(View.VISIBLE);
|
||||
setListAdapter(mListAdapter);
|
||||
}
|
||||
mIsFirstLoad = false;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user