Merge "Don't use deprecated PagerAdapter methods"
diff --git a/res/layout-sw580dp/join_contact_picker.xml b/res/layout-sw580dp/join_contact_picker.xml
new file mode 100644
index 0000000..3d9127b
--- /dev/null
+++ b/res/layout-sw580dp/join_contact_picker.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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.
+-->
+
+<view xmlns:android="http://schemas.android.com/apk/res/android"
+ class="com.android.contacts.widget.FullHeightLinearLayout"
+ style="@style/ContactPickerLayout"
+ android:orientation="vertical">
+ <!-- See also comments in contact_picker.xml -->
+ <view
+ class="android.widget.SearchView"
+ android:id="@+id/search_view"
+ android:layout_width="match_parent"
+ android:maxWidth="@dimen/contact_picker_search_view_max_width"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="0dip"
+ android:layout_marginRight="@dimen/list_visible_scrollbar_padding"
+ android:paddingRight="0dip"
+ android:iconifiedByDefault="false" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1"
+ android:id="@+id/list_container" />
+</view>
diff --git a/res/layout/join_contact_picker.xml b/res/layout/join_contact_picker.xml
index ea0deaf..ee30525 100644
--- a/res/layout/join_contact_picker.xml
+++ b/res/layout/join_contact_picker.xml
@@ -14,23 +14,13 @@
limitations under the License.
-->
-<view
- xmlns:android="http://schemas.android.com/apk/res/android"
+<view xmlns:android="http://schemas.android.com/apk/res/android"
class="com.android.contacts.widget.FullHeightLinearLayout"
style="@style/ContactPickerLayout"
android:orientation="vertical">
-
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:id="@+id/list_container" />
-
- <View
- android:id="@+id/divider"
- android:layout_width="match_parent"
- android:layout_height="1dip"
- android:layout_marginLeft="?attr/contact_browser_list_padding_left"
- android:layout_marginRight="?attr/contact_browser_list_padding_right"
- android:background="?android:attr/dividerHorizontal" />
</view>
diff --git a/res/values-sw580dp/styles.xml b/res/values-sw580dp/styles.xml
index bf5b137..70e2a3b 100644
--- a/res/values-sw580dp/styles.xml
+++ b/res/values-sw580dp/styles.xml
@@ -95,6 +95,8 @@
<style name="JoinContactActivityTheme" parent="ContactPickerTheme" >
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">match_parent</item>
+ <!-- In the contact picker screen we're using adjustResize but we don't want it here. -->
+ <item name="android:windowSoftInputMode">adjustUnspecified</item>
</style>
<style name="ContactListFilterTheme" parent="@android:Theme.Holo.Light.Dialog">
diff --git a/src/com/android/contacts/activities/ContactSelectionActivity.java b/src/com/android/contacts/activities/ContactSelectionActivity.java
index b5b6c1d..4b59d34 100644
--- a/src/com/android/contacts/activities/ContactSelectionActivity.java
+++ b/src/com/android/contacts/activities/ContactSelectionActivity.java
@@ -107,7 +107,7 @@
if (savedState != null) {
mActionCode = savedState.getInt(KEY_ACTION_CODE);
}
-
+
// Extract relevant information from the intent
mRequest = mIntentResolver.resolveIntent(getIntent());
if (!mRequest.isValid()) {
diff --git a/src/com/android/contacts/activities/JoinContactActivity.java b/src/com/android/contacts/activities/JoinContactActivity.java
index 75a13d0..4a277cb 100644
--- a/src/com/android/contacts/activities/JoinContactActivity.java
+++ b/src/com/android/contacts/activities/JoinContactActivity.java
@@ -24,18 +24,29 @@
import com.android.contacts.list.OnContactPickerActionListener;
import android.app.ActionBar;
+import android.app.ActionBar.LayoutParams;
import android.app.Fragment;
+import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
+import android.text.TextUtils;
import android.util.Log;
+import android.view.LayoutInflater;
import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnFocusChangeListener;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.SearchView;
+import android.widget.SearchView.OnCloseListener;
+import android.widget.SearchView.OnQueryTextListener;
/**
* An activity that shows a list of contacts that can be joined with the target contact.
*/
-public class JoinContactActivity extends ContactsActivity {
+public class JoinContactActivity extends ContactsActivity
+ implements OnQueryTextListener, OnCloseListener, OnFocusChangeListener {
private static final String TAG = "JoinContactActivity";
@@ -59,6 +70,7 @@
private long mTargetContactId;
private JoinContactListFragment mListFragment;
+ private SearchView mSearchView;
@Override
public void onAttachFragment(Fragment fragment) {
@@ -93,12 +105,7 @@
.commitAllowingStateLoss();
}
- final ActionBar actionBar = getActionBar();
- if (actionBar != null) {
- actionBar.setDisplayShowHomeEnabled(true);
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowTitleEnabled(true);
- }
+ prepareSearchViewAndActionBar();
}
private void setupActionListener() {
@@ -125,6 +132,74 @@
});
}
+ private void prepareSearchViewAndActionBar() {
+ final ActionBar actionBar = getActionBar();
+ if (actionBar != null) {
+ final View searchViewOnLayout = findViewById(R.id.search_view);
+ if (searchViewOnLayout != null) {
+ searchViewOnLayout.setVisibility(View.GONE);
+ }
+
+ final View searchViewLayout = LayoutInflater.from(actionBar.getThemedContext())
+ .inflate(R.layout.custom_action_bar, null);
+ mSearchView = (SearchView) searchViewLayout.findViewById(R.id.search_view);
+
+ // In order to make the SearchView look like "shown via search menu", we need to
+ // manually setup its state. See also DialtactsActivity.java and ActionBarAdapter.java.
+ mSearchView.setIconifiedByDefault(true);
+ mSearchView.setQueryHint(getString(R.string.hint_findContacts));
+ mSearchView.setIconified(false);
+
+ mSearchView.setOnQueryTextListener(this);
+ mSearchView.setOnCloseListener(this);
+ mSearchView.setOnQueryTextFocusChangeListener(this);
+
+ actionBar.setCustomView(searchViewLayout,
+ new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
+ actionBar.setDisplayShowCustomEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ } else {
+ mSearchView = (SearchView) findViewById(R.id.search_view);
+ mSearchView.setQueryHint(getString(R.string.hint_findContacts));
+ mSearchView.setOnQueryTextListener(this);
+ mSearchView.setOnQueryTextFocusChangeListener(this);
+ }
+
+ // Clear focus and suppress keyboard show-up.
+ mSearchView.clearFocus();
+ }
+
+ @Override
+ public boolean onQueryTextChange(String newText) {
+ mListFragment.setQueryString(newText, true);
+ return false;
+ }
+
+ @Override
+ public boolean onQueryTextSubmit(String query) {
+ return false;
+ }
+
+ @Override
+ public boolean onClose() {
+ if (!TextUtils.isEmpty(mSearchView.getQuery())) {
+ mSearchView.setQuery(null, true);
+ }
+ return true;
+ }
+
+ @Override
+ public void onFocusChange(View view, boolean hasFocus) {
+ switch (view.getId()) {
+ case R.id.search_view: {
+ if (hasFocus) {
+ showInputMethod(mSearchView.findFocus());
+ }
+ }
+ }
+ }
+
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
@@ -156,4 +231,14 @@
mListFragment.onPickerResult(data);
}
}
+
+ private void showInputMethod(View view) {
+ final InputMethodManager imm = (InputMethodManager)
+ getSystemService(Context.INPUT_METHOD_SERVICE);
+ if (imm != null) {
+ if (!imm.showSoftInput(view, 0)) {
+ Log.w(TAG, "Failed to show soft input method.");
+ }
+ }
+ }
}
diff --git a/src/com/android/contacts/list/ContactEntryListAdapter.java b/src/com/android/contacts/list/ContactEntryListAdapter.java
index cf86dc9..d95a1bc 100644
--- a/src/com/android/contacts/list/ContactEntryListAdapter.java
+++ b/src/com/android/contacts/list/ContactEntryListAdapter.java
@@ -131,6 +131,28 @@
return partition;
}
+ /**
+ * Remove all directories after the default directory. This is typically used when contacts
+ * list screens are asked to exit the search mode and thus need to remove all remote directory
+ * results for the search.
+ *
+ * This code assumes that the default directory and directories before that should not be
+ * deleted (e.g. Join screen has "suggested contacts" directory before the default director,
+ * and we should not remove the directory).
+ */
+ /* package */ void removeDirectoriesAfterDefault() {
+ final int partitionCount = getPartitionCount();
+ for (int i = partitionCount - 1; i >= 0; i--) {
+ final Partition partition = getPartition(i);
+ if ((partition instanceof DirectoryPartition)
+ && ((DirectoryPartition) partition).getDirectoryId() == Directory.DEFAULT) {
+ break;
+ } else {
+ removePartition(i);
+ }
+ }
+ }
+
private int getPartitionByDirectoryId(long id) {
int count = getPartitionCount();
for (int i = 0; i < count; i++) {
diff --git a/src/com/android/contacts/list/ContactEntryListFragment.java b/src/com/android/contacts/list/ContactEntryListFragment.java
index 8db477e..5ee25a2 100644
--- a/src/com/android/contacts/list/ContactEntryListFragment.java
+++ b/src/com/android/contacts/list/ContactEntryListFragment.java
@@ -613,12 +613,10 @@
mAdapter.clearPartitions();
if (!flag) {
- // If we are switching from search to regular display,
- // remove all directory partitions (except the default one).
- int count = mAdapter.getPartitionCount();
- for (int i = count; --i >= 1;) {
- mAdapter.removePartition(i);
- }
+ // If we are switching from search to regular display, remove all directory
+ // partitions after default one, assuming they are remote directories which
+ // should be cleaned up on exiting the search mode.
+ mAdapter.removeDirectoriesAfterDefault();
}
mAdapter.configureDefaultPartition(false, flag);
}
diff --git a/src/com/android/contacts/list/JoinContactListAdapter.java b/src/com/android/contacts/list/JoinContactListAdapter.java
index bfe8c53..80ddc83 100644
--- a/src/com/android/contacts/list/JoinContactListAdapter.java
+++ b/src/com/android/contacts/list/JoinContactListAdapter.java
@@ -20,7 +20,6 @@
import android.content.Context;
import android.content.CursorLoader;
import android.database.Cursor;
-import android.database.MatrixCursor;
import android.net.Uri;
import android.net.Uri.Builder;
import android.provider.ContactsContract;
@@ -53,7 +52,6 @@
@Override
protected void addPartitions() {
-
// Partition 0: suggestions
addPartition(false, true);
@@ -69,11 +67,11 @@
public void configureLoader(CursorLoader cursorLoader, long directoryId) {
JoinContactLoader loader = (JoinContactLoader) cursorLoader;
- Builder builder = Contacts.CONTENT_URI.buildUpon();
+ final Builder builder = Contacts.CONTENT_URI.buildUpon();
builder.appendEncodedPath(String.valueOf(mTargetContactId));
builder.appendEncodedPath(AggregationSuggestions.CONTENT_DIRECTORY);
- String filter = getQueryString();
+ final String filter = getQueryString();
if (!TextUtils.isEmpty(filter)) {
builder.appendEncodedPath(Uri.encode(filter));
}
@@ -84,13 +82,22 @@
// TODO simplify projection
loader.setProjection(getProjection(false));
- Uri allContactsUri = buildSectionIndexerUri(Contacts.CONTENT_URI).buildUpon()
+ final Uri allContactsUri;
+ if (!TextUtils.isEmpty(filter)) {
+ allContactsUri = buildSectionIndexerUri(Contacts.CONTENT_FILTER_URI).buildUpon()
+ .appendEncodedPath(Uri.encode(filter))
.appendQueryParameter(
ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(Directory.DEFAULT))
.build();
+ } else {
+ allContactsUri = buildSectionIndexerUri(Contacts.CONTENT_URI).buildUpon()
+ .appendQueryParameter(
+ ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(Directory.DEFAULT))
+ .build();
+ }
loader.setUri(allContactsUri);
loader.setSelection(Contacts._ID + "!=?");
- loader.setSelectionArgs(new String[]{String.valueOf(mTargetContactId)});
+ loader.setSelectionArgs(new String[]{ String.valueOf(mTargetContactId) });
if (getSortOrder() == ContactsContract.Preferences.SORT_ORDER_PRIMARY) {
loader.setSortOrder(Contacts.SORT_KEY_PRIMARY);
} else {
@@ -120,7 +127,7 @@
@Override
public int getViewTypeCount() {
- return super.getViewTypeCount() + 1;
+ return super.getViewTypeCount();
}
@Override
@@ -173,14 +180,14 @@
protected void bindView(View itemView, int partition, Cursor cursor, int position) {
switch (partition) {
case PARTITION_SUGGESTIONS: {
- final ContactListItemView view = (ContactListItemView)itemView;
+ final ContactListItemView view = (ContactListItemView) itemView;
view.setSectionHeader(null);
bindPhoto(view, partition, cursor);
bindName(view, cursor);
break;
}
case PARTITION_ALL_CONTACTS: {
- final ContactListItemView view = (ContactListItemView)itemView;
+ final ContactListItemView view = (ContactListItemView) itemView;
bindSectionHeaderAndDivider(view, position, cursor);
bindPhoto(view, partition, cursor);
bindName(view, cursor);
diff --git a/src/com/android/contacts/list/JoinContactListFragment.java b/src/com/android/contacts/list/JoinContactListFragment.java
index 5b27bdf..7c6767b 100644
--- a/src/com/android/contacts/list/JoinContactListFragment.java
+++ b/src/com/android/contacts/list/JoinContactListFragment.java
@@ -26,6 +26,7 @@
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract.Contacts;
+import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -103,7 +104,10 @@
configureAdapter();
getLoaderManager().initLoader(DISPLAY_NAME_LOADER, null, mLoaderCallbacks);
- getLoaderManager().initLoader(JoinContactListAdapter.PARTITION_ALL_CONTACTS,
+
+ // When this method is called, Uri to be used may be changed. We should use restartLoader()
+ // to load the parameter again.
+ getLoaderManager().restartLoader(JoinContactListAdapter.PARTITION_ALL_CONTACTS,
null, mLoaderCallbacks);
}
@@ -167,4 +171,11 @@
mTargetContactId = savedState.getLong(KEY_TARGET_CONTACT_ID);
}
}
+
+ @Override
+ public void setQueryString(String queryString, boolean delaySelection) {
+ super.setQueryString(queryString, delaySelection);
+
+ setSearchMode(!TextUtils.isEmpty(queryString));
+ }
}
diff --git a/src/com/android/contacts/list/JoinContactLoader.java b/src/com/android/contacts/list/JoinContactLoader.java
index 2f1f9b0..c43560e 100644
--- a/src/com/android/contacts/list/JoinContactLoader.java
+++ b/src/com/android/contacts/list/JoinContactLoader.java
@@ -20,6 +20,7 @@
import android.database.Cursor;
import android.database.MatrixCursor;
import android.net.Uri;
+import android.util.Log;
/**
* A specialized loader for the Join Contacts UI. It executes two queries:
@@ -29,7 +30,7 @@
private String[] mProjection;
private Uri mSuggestionUri;
- private MatrixCursor mSuggestionsCursor;
+ private Cursor mSuggestionsCursor;
public JoinContactLoader(Context context) {
super(context, null, null, null, null, null);
@@ -53,28 +54,8 @@
public Cursor loadInBackground() {
// First execute the suggestions query, then call super.loadInBackground
// to load the entire list
- mSuggestionsCursor = loadSuggestions();
+ mSuggestionsCursor = getContext().getContentResolver()
+ .query(mSuggestionUri, mProjection, null, null, null);
return super.loadInBackground();
}
-
- /**
- * Loads join suggestions into a MatrixCursor.
- */
- private MatrixCursor loadSuggestions() {
- Cursor cursor = getContext().getContentResolver().query(mSuggestionUri, mProjection,
- null, null, null);
- try {
- MatrixCursor matrix = new MatrixCursor(mProjection);
- Object[] row = new Object[mProjection.length];
- while (cursor.moveToNext()) {
- for (int i = 0; i < row.length; i++) {
- row[i] = cursor.getString(i);
- }
- matrix.addRow(row);
- }
- return matrix;
- } finally {
- cursor.close();
- }
- }
}
\ No newline at end of file