Merge "Remove use of private style"
diff --git a/res/layout/contact_tile_row_regular.xml b/res/layout/contact_tile_row_regular.xml
new file mode 100644
index 0000000..79b670a
--- /dev/null
+++ b/res/layout/contact_tile_row_regular.xml
@@ -0,0 +1,38 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/contactTile_row_regular"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <RelativeLayout android:id="@+id/contactTile_row_left"
+ style="@style/ContactTileRegularLayout">
+ <ImageView android:id="@+id/contactTile_left_image"
+ style="@style/ContactTileRegularImage" />
+ <TextView android:id="@+id/contactTile_left_name"
+ style="@style/ContactTileRegularText" />
+ </RelativeLayout>
+
+ <RelativeLayout android:id="@+id/contactTile_row_right"
+ style="@style/ContactTileRegularLayout">
+ <ImageView android:id="@+id/contactTile_right_image"
+ style="@style/ContactTileRegularImage" />
+ <TextView android:id="@+id/contactTile_right_name"
+ style="@style/ContactTileRegularText" />
+ </RelativeLayout>
+
+</LinearLayout>
diff --git a/res/layout/strequent_fragment.xml b/res/layout/strequent_fragment.xml
new file mode 100644
index 0000000..348fd0c
--- /dev/null
+++ b/res/layout/strequent_fragment.xml
@@ -0,0 +1,22 @@
+<?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.
+-->
+
+<ListView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/strequent_list"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:divider="@null"
+/>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index ace8869..9a60815 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -48,4 +48,8 @@
<!-- Color of the text indicating the type of entry (e.g. Home, Work etc) -->
<color name="detail_header_view_text_color">#FFFFFF</color>
+
+ <!-- Color of the text foreground and background of Regular Sized ContactTile -->
+ <color name="contact_tile_regular_text">#2B1B17</color>
+ <color name="contact_tile_regular_text_background">#FFFFFF</color>
</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 5ade9f6..f539a6d 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -271,4 +271,52 @@
<item name="android:gravity">center_vertical</item>
<item name="android:paddingTop">5dip</item>
</style>
+
+ <style name="ContactTileRegularText">
+ <item name="android:layout_width">fill_parent</item>
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:layout_alignParentBottom">true</item>
+ <item name="android:background">@color/contact_tile_regular_text</item>
+ <item name="android:textColor">@color/contact_tile_regular_text_background</item>
+ <item name="android:textSize">17sp</item>
+ <item name="android:alpha">0.7</item>
+ <item name="android:gravity">center_horizontal</item>
+ </style>
+
+ <style name="ContactTileRegularImage">
+ <item name="android:layout_width">160dip</item>
+ <item name="android:layout_height">160dip</item>
+ <item name="android:layout_alignParentTop">true</item>
+ <item name="android:layout_alignParentLeft">true</item>
+ <item name="android:scaleType">centerCrop</item>
+ </style>
+
+ <style name="ContactTileRegularLayout">
+ <item name="android:layout_width">155dip</item>
+ <item name="android:layout_height">160dip</item>
+ <item name="android:focusable">true</item>
+ <item name="android:padding">5dip</item>
+ <item name="android:background">@drawable/list_selector</item>
+ </style>
+
+ <style name="ContactTileSmallText">
+ <item name="android:layout_width">80dip</item>
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:paddingTop">8dip</item>
+ <item name="android:paddingLeft">4dip</item>
+ </style>
+
+ <style name="ContactTileSmallImage">
+ <item name="android:layout_width">80dip</item>
+ <item name="android:layout_height">80dip</item>
+ <item name="android:scaleType">centerCrop</item>
+ </style>
+
+ <style name="ContactTileSmallLayout">
+ <item name="android:layout_width">160dip</item>
+ <item name="android:layout_height">80dip</item>
+ <item name="android:focusable">true</item>
+ <item name="android:padding">5dip</item>
+ <item name="android:background">@drawable/list_selector</item>
+ </style>
</resources>
diff --git a/src/com/android/contacts/StrequentMetaDataLoader.java b/src/com/android/contacts/StrequentMetaDataLoader.java
new file mode 100644
index 0000000..203b25f
--- /dev/null
+++ b/src/com/android/contacts/StrequentMetaDataLoader.java
@@ -0,0 +1,44 @@
+/*
+ * 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
+ */
+package com.android.contacts;
+
+import android.content.Context;
+import android.content.CursorLoader;
+import android.provider.ContactsContract.Contacts;
+
+/**
+ * Strequent meta-data loader. Loads all starred and frequent contacts from the database.
+ */
+public final class StrequentMetaDataLoader extends CursorLoader {
+
+ public final static int CONTACT_ID = 0;
+ public final static int DISPLAY_NAME = 1;
+ public final static int STARRED = 2;
+ public final static int PHOTO_URI = 3;
+ public final static int PHOTO_ID = 4;
+
+ private static final String[] COLUMNS = new String[] {
+ Contacts._ID,
+ Contacts.DISPLAY_NAME,
+ Contacts.STARRED,
+ Contacts.PHOTO_URI,
+ Contacts.PHOTO_ID
+ };
+
+ public StrequentMetaDataLoader(Context context) {
+ super(context, Contacts.CONTENT_STREQUENT_URI, COLUMNS, null, null, null);
+ }
+}
diff --git a/src/com/android/contacts/activities/DialtactsActivity.java b/src/com/android/contacts/activities/DialtactsActivity.java
index 52a2539..3766e47 100644
--- a/src/com/android/contacts/activities/DialtactsActivity.java
+++ b/src/com/android/contacts/activities/DialtactsActivity.java
@@ -225,24 +225,7 @@
tab.setIcon(R.drawable.ic_tab_starred);
tab.setTabListener(new TabChangeListener(mStrequentFragment));
getActionBar().addTab(tab);
-
- // TODO: We should not artificially create Intents and put them into the Fragment.
- // It would be nicer to directly pass in the UI constant
- Intent intent = new Intent(UI.LIST_STREQUENT_ACTION);
- intent.setClass(this, PeopleActivity.class);
-
- ContactsIntentResolver resolver = new ContactsIntentResolver(this);
- ContactsRequest request = resolver.resolveIntent(intent);
- final ContactListFilter filter = ContactListFilter.createFilterWithType(
- ContactListFilter.FILTER_TYPE_STARRED);
- mStrequentFragment.setFilter(filter, false);
- mStrequentFragment.setSearchMode(request.isSearchMode());
- mStrequentFragment.setQueryString(request.getQueryString(), false);
- mStrequentFragment.setContactsRequest(request);
- mStrequentFragment.setDirectorySearchMode(request.isDirectorySearchEnabled()
- ? DirectoryListLoader.SEARCH_MODE_DEFAULT
- : DirectoryListLoader.SEARCH_MODE_NONE);
- mStrequentFragment.setOnContactListActionListener(mListFragmentListener);
+ mStrequentFragment.setListener(mStrequentListener);
}
/**
@@ -505,6 +488,14 @@
}
};
+ private StrequentContactListFragment.Listener mStrequentListener =
+ new StrequentContactListFragment.Listener() {
+ @Override
+ public void onContactSelected(Uri contactUri) {
+ getPhoneNumberCallInteraction().startInteraction(contactUri);
+ }
+ };
+
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// For now, create the menu in here. It would be nice to do this in the Fragment,
diff --git a/src/com/android/contacts/list/StrequentAdapter.java b/src/com/android/contacts/list/StrequentAdapter.java
new file mode 100644
index 0000000..4c6109a
--- /dev/null
+++ b/src/com/android/contacts/list/StrequentAdapter.java
@@ -0,0 +1,232 @@
+/*
+ * 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.
+ */
+package com.android.contacts.list;
+
+import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.R;
+import com.android.contacts.StrequentMetaDataLoader;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.ContactsContract.Contacts;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+
+/**
+ * Arranges contacts in {@link StrequentFragment} (aka favorites) according to if the contact
+ * is starred or not. Also shows two contacts per row.
+ */
+public class StrequentAdapter extends BaseAdapter implements OnClickListener {
+
+ private LayoutInflater mInflater;
+ private ArrayList<StrequentEntry> mAllEntries;
+ private ContactPhotoManager mPhotoManager;
+ private Listener mListener;
+ private int mMostFrequentCount;
+ private int mStarredCount;
+ private static final int NUMCOLS = 2;
+
+ public StrequentAdapter(Context context, Listener listener) {
+ mInflater = LayoutInflater.from(context);
+ mPhotoManager = ContactPhotoManager.createContactPhotoManager(context);
+ mListener = listener;
+ }
+
+ public void setCursor(Cursor cursor){
+ populateStrequentEntries(cursor);
+ }
+
+ private void populateStrequentEntries(Cursor cursor) {
+ mAllEntries = new ArrayList<StrequentEntry>();
+ mMostFrequentCount = mStarredCount = 0;
+
+ while (cursor.moveToNext()) {
+ StrequentEntry contact = new StrequentEntry();
+
+ contact.id = cursor.getLong(StrequentMetaDataLoader.CONTACT_ID);
+ contact.photoId = cursor.getLong(StrequentMetaDataLoader.PHOTO_ID);
+ contact.name = cursor.getString(StrequentMetaDataLoader.DISPLAY_NAME);
+
+ // Adding Starred Contact
+ if (cursor.getInt(StrequentMetaDataLoader.STARRED) == 1) {
+ mStarredCount++;
+ } else {
+ mMostFrequentCount++;
+ }
+ mAllEntries.add(contact);
+ }
+ this.notifyDataSetChanged();
+ }
+
+ @Override
+ public int getCount() {
+ return mAllEntries.size() / NUMCOLS;
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return mAllEntries.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return mAllEntries.get(position).id;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ ViewHolder holder;
+ // Note: For now, every row except for the last row will have 2 columns
+ int index = position * NUMCOLS;
+
+ // Try to recycle convertView
+ if (convertView != null) {
+ holder = (ViewHolder) convertView.getTag();
+ } else {
+ // Must create new View
+ convertView = mInflater.inflate(R.layout.contact_tile_row_regular, null);
+ holder = new ViewHolder(convertView);
+
+ holder.getLayoutLeft().setOnClickListener(this);
+ holder.getLayoutRight().setOnClickListener(this);
+
+ convertView.setTag(holder);
+ }
+
+ holder.getTextLeft().setText(mAllEntries.get(index).name);
+ mPhotoManager.loadPhoto(holder.getImageLeft(), mAllEntries.get(index).photoId);
+ holder.getLayoutLeft().setTag(mAllEntries.get(index));
+
+ if (++index < mAllEntries.size()) {
+ holder.getTextRight().setText(mAllEntries.get(index).name);
+ mPhotoManager.loadPhoto(holder.mImageRight, mAllEntries.get(index).photoId);
+ holder.getLayoutRight().setTag(mAllEntries.get(index));
+ } else {
+ holder.getTextRight().setText(null);
+ holder.getImageRight().setImageBitmap(null);
+ holder.getLayoutRight().setOnClickListener(null);
+ }
+
+ return convertView;
+ }
+
+ @Override
+ public int getViewTypeCount() {
+ return 1;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return 1;
+ }
+
+ /**
+ * Class it hold views for layout to help make wonderful listview faster
+ */
+ private static class ViewHolder {
+ private TextView mTextLeft, mTextRight;
+ private ImageView mImageLeft, mImageRight;
+ private View mLayoutLeft, mLayoutRight;
+
+ public ViewHolder(View convertView){
+ // Left Column
+ mTextLeft = (TextView) convertView.findViewById(R.id.contactTile_left_name);
+ mImageLeft = (ImageView) convertView.findViewById(R.id.contactTile_left_image);
+ mLayoutLeft = convertView.findViewById(R.id.contactTile_row_left);
+
+ // Right Column
+ mTextRight = (TextView) convertView.findViewById(R.id.contactTile_right_name);
+ mImageRight = (ImageView) convertView.findViewById(R.id.contactTile_right_image);
+ mLayoutRight = convertView.findViewById(R.id.contactTile_row_right);
+ }
+
+ public TextView getTextLeft() {
+ return mTextLeft;
+ }
+
+ public void setTextLeft(TextView textLeft) {
+ this.mTextLeft = textLeft;
+ }
+
+ public TextView getTextRight() {
+ return mTextRight;
+ }
+
+ public void setTextRight(TextView textRight) {
+ this.mTextRight = textRight;
+ }
+
+ public ImageView getImageLeft() {
+ return mImageLeft;
+ }
+
+ public void setImageLeft(ImageView imageLeft) {
+ this.mImageLeft = imageLeft;
+ }
+
+ public ImageView getImageRight() {
+ return mImageRight;
+ }
+
+ public void setImageRight(ImageView imageRight) {
+ this.mImageRight = imageRight;
+ }
+
+ public View getLayoutLeft() {
+ return mLayoutLeft;
+ }
+
+ public void setLayoutLeft(View layoutLeft) {
+ this.mLayoutLeft = layoutLeft;
+ }
+
+ public View getLayoutRight() {
+ return mLayoutRight;
+ }
+
+ public void setLayoutRight(View layoutRight) {
+ this.mLayoutRight = layoutRight;
+ }
+ }
+
+ /**
+ * Class to hold contact information
+ */
+ private static class StrequentEntry {
+ public long id;
+ public long photoId;
+ public String name;
+ }
+
+ @Override
+ public void onClick(View v) {
+ StrequentEntry entry = (StrequentEntry)v.getTag();
+ Uri data = Uri.withAppendedPath(Contacts.CONTENT_URI, String.valueOf(entry.id));
+ mListener.onContactSelected(data);
+ }
+
+ public interface Listener {
+ public void onContactSelected(Uri contactUri);
+ }
+}
diff --git a/src/com/android/contacts/list/StrequentContactListFragment.java b/src/com/android/contacts/list/StrequentContactListFragment.java
index 393e698..47cc7be 100644
--- a/src/com/android/contacts/list/StrequentContactListFragment.java
+++ b/src/com/android/contacts/list/StrequentContactListFragment.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 The Android Open Source Project
+ * 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.
@@ -16,94 +16,94 @@
package com.android.contacts.list;
import com.android.contacts.R;
+import com.android.contacts.StrequentMetaDataLoader;
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.LoaderManager;
+import android.app.LoaderManager.LoaderCallbacks;
+import android.content.Context;
+import android.content.CursorLoader;
+import android.content.Loader;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.view.View.OnClickListener;
+import android.widget.ListView;
/**
* Fragment containing a list of starred contacts followed by a list of frequently contacted.
*/
-public class StrequentContactListFragment extends ContactBrowseListFragment
- implements OnClickListener {
+public class StrequentContactListFragment extends Fragment {
+ public interface Listener {
+ public void onContactSelected(Uri contactUri);
+ }
- private static final int CALL_BUTTON_ID = android.R.id.button1;
+ private static int LOADER_STREQUENT = 1;
- private boolean mStarredContactsIncluded = true;
- private boolean mFrequentlyContactedContactsIncluded = true;
+ private Listener mListener;
+ private StrequentAdapter mAdapter;
+ private ListView mListView;
+ private Context mContext;
- public StrequentContactListFragment() {
- setSectionHeaderDisplayEnabled(false);
- setPhotoLoaderEnabled(true);
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ mAdapter = new StrequentAdapter(getActivity(), mAdapterListener);
+ mContext = activity;
}
@Override
- protected boolean isNameHighlighingEnabled() {
- // Since the list is not ordered alphabetically, we don't need to highlight the part
- // that is used for sorting.
- return false;
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ View v = inflater.inflate(R.layout.strequent_fragment, container, false);
+ mListView = (ListView) v.findViewById(R.id.strequent_list);
+ mListView.setItemsCanFocus(true);
+ return v;
}
- public void setStarredContactsIncluded(boolean flag) {
- mStarredContactsIncluded = flag;
- configureAdapter();
- }
-
- public void setFrequentlyContactedContactsIncluded(boolean flag) {
- mFrequentlyContactedContactsIncluded = flag;
- configureAdapter();
+ public void setListener(Listener listener) {
+ mListener = listener;
}
@Override
- protected void onItemClick(int position, long id) {
- ContactListAdapter adapter = getAdapter();
- viewContact(adapter.getContactUri(position));
+ public void onStart(){
+ super.onStart();
+ getLoaderManager().restartLoader(LOADER_STREQUENT, null, mStrequentLoaderListener);
}
- @Override
- protected ContactListAdapter createListAdapter() {
- StrequentContactListAdapter adapter =
- new StrequentContactListAdapter(getActivity(), CALL_BUTTON_ID);
- adapter.setSectionHeaderDisplayEnabled(false);
- adapter.setDisplayPhotos(true);
- adapter.setQuickContactEnabled(true);
- adapter.setCallButtonListener(this);
+ /**
+ * The listener for the strequent meta data loader.
+ */
+ private final LoaderManager.LoaderCallbacks<Cursor> mStrequentLoaderListener =
+ new LoaderCallbacks<Cursor>() {
- return adapter;
- }
-
- @Override
- protected void configureAdapter() {
- super.configureAdapter();
-
- StrequentContactListAdapter adapter = (StrequentContactListAdapter)getAdapter();
- if (adapter != null) {
- adapter.setStarredContactsIncluded(mStarredContactsIncluded);
- adapter.setFrequentlyContactedContactsIncluded(mFrequentlyContactedContactsIncluded);
+ @Override
+ public CursorLoader onCreateLoader(int id, Bundle args) {
+ return new StrequentMetaDataLoader(mContext);
}
- }
- @Override
- protected View inflateView(LayoutInflater inflater, ViewGroup container) {
- return inflater.inflate(R.layout.contacts_list_content, null);
- }
+ @Override
+ public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+ mAdapter.setCursor(data);
+ mListView.setAdapter(mAdapter);
+ }
- @Override
- protected void prepareEmptyView() {
- setEmptyText(R.string.noFavoritesHelpText);
- }
+ @Override
+ public void onLoaderReset(Loader<Cursor> loader) {
+ mAdapter.setCursor(null);
+ }
+ };
- @Override
- public void onClick(View v) {
- int id = v.getId();
- switch (id) {
- case CALL_BUTTON_ID: {
- final int position = (Integer)v.getTag();
- ContactListAdapter adapter = getAdapter();
- callContact(adapter.getContactUri(position));
- break;
+ private StrequentAdapter.Listener mAdapterListener =
+ new StrequentAdapter.Listener() {
+ @Override
+ public void onContactSelected(Uri contactUri) {
+ if (mListener != null) {
+ mListener.onContactSelected(contactUri);
}
}
- }
+ };
}