blob: 0dbc8dfe9b25f47efba17d0a192c139ef8fe7573 [file] [log] [blame]
Daniel Lehmann4cd94412010-04-08 16:44:36 -07001/*
Daniel Lehmannef3f8f02010-07-26 18:55:25 -07002 * Copyright (C) 2010 The Android Open Source Project
Daniel Lehmann4cd94412010-04-08 16:44:36 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.contacts.activities;
18
Katherine Kuan79700882011-06-14 17:40:33 -070019import com.android.contacts.ContactLoader;
Dmitri Plotnikov18ffaa22010-12-03 14:28:00 -080020import com.android.contacts.ContactSaveService;
Dmitri Plotnikov6f667b52011-01-09 12:53:13 -080021import com.android.contacts.ContactsActivity;
Daniel Lehmann4cd94412010-04-08 16:44:36 -070022import com.android.contacts.ContactsSearchManager;
23import com.android.contacts.R;
Katherine Kuan79700882011-06-14 17:40:33 -070024import com.android.contacts.detail.ContactDetailAboutFragment;
Dmitri Plotnikov18ffaa22010-12-03 14:28:00 -080025import com.android.contacts.detail.ContactDetailFragment;
Katherine Kuan79700882011-06-14 17:40:33 -070026import com.android.contacts.detail.ContactDetailHeaderView;
27import com.android.contacts.detail.ContactDetailTabCarousel;
28import com.android.contacts.detail.ContactDetailUpdatesFragment;
Daniel Lehmann69e7fec2010-07-20 14:14:56 -070029import com.android.contacts.interactions.ContactDeletionInteraction;
Katherine Kuan79700882011-06-14 17:40:33 -070030import com.android.contacts.list.ContactBrowseListFragment;
Daniel Lehmannc90c7052011-03-16 18:42:34 -070031import com.android.contacts.util.PhoneCapabilityTester;
Daniel Lehmann4cd94412010-04-08 16:44:36 -070032
Dmitri Plotnikovcaf0bc72010-09-03 15:16:21 -070033import android.accounts.Account;
Katherine Kuan79700882011-06-14 17:40:33 -070034import android.app.Fragment;
35import android.app.FragmentManager;
Daniel Lehmann60be1a12010-08-05 18:37:21 -070036import android.content.ActivityNotFoundException;
Dmitri Plotnikovcaf0bc72010-09-03 15:16:21 -070037import android.content.ContentValues;
Daniel Lehmann18f104f2010-05-07 15:41:11 -070038import android.content.Intent;
Daniel Lehmannc2687c32010-04-19 18:20:44 -070039import android.net.Uri;
Daniel Lehmann4cd94412010-04-08 16:44:36 -070040import android.os.Bundle;
Katherine Kuan79700882011-06-14 17:40:33 -070041import android.support.v13.app.FragmentPagerAdapter;
42import android.support.v4.view.ViewPager;
43import android.support.v4.view.ViewPager.OnPageChangeListener;
Daniel Lehmann4cd94412010-04-08 16:44:36 -070044import android.util.Log;
45import android.view.KeyEvent;
Katherine Kuan79700882011-06-14 17:40:33 -070046import android.view.MotionEvent;
47import android.view.View;
48import android.view.View.OnTouchListener;
Dmitri Plotnikovcaf0bc72010-09-03 15:16:21 -070049import android.widget.Toast;
50
51import java.util.ArrayList;
Daniel Lehmann4cd94412010-04-08 16:44:36 -070052
Dmitri Plotnikov6f667b52011-01-09 12:53:13 -080053public class ContactDetailActivity extends ContactsActivity {
Daniel Lehmann4cd94412010-04-08 16:44:36 -070054 private static final String TAG = "ContactDetailActivity";
55
Katherine Kuan79700882011-06-14 17:40:33 -070056 public static final int FRAGMENT_COUNT = 2;
57
58 private ContactDetailAboutFragment mAboutFragment;
59 private ContactDetailUpdatesFragment mUpdatesFragment;
60
61 private ContactDetailTabCarousel mTabCarousel;
62 private ViewPager mViewPager;
63
64 private Uri mUri;
Daniel Lehmann25a02822010-05-11 15:52:43 -070065
Daniel Lehmann4cd94412010-04-08 16:44:36 -070066 @Override
67 public void onCreate(Bundle savedState) {
68 super.onCreate(savedState);
69
Daniel Lehmannc90c7052011-03-16 18:42:34 -070070 if (PhoneCapabilityTester.isUsingTwoPanes(this)) {
71 // This activity must not be shown. We have to select the contact in the
Dave Santoro5e684a42011-06-10 13:23:35 -070072 // PeopleActivity instead ==> Create a forward intent and finish
Daniel Lehmannc90c7052011-03-16 18:42:34 -070073 final Intent originalIntent = getIntent();
74 Intent intent = new Intent();
75 intent.setAction(originalIntent.getAction());
76 intent.setDataAndType(originalIntent.getData(), originalIntent.getType());
77 intent.setFlags(
78 Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_FORWARD_RESULT
79 | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
80
Katherine Kuan9856fce2011-06-01 10:24:09 -070081 intent.setClass(this, PeopleActivity.class);
Daniel Lehmannc90c7052011-03-16 18:42:34 -070082 startActivity(intent);
83 finish();
84 return;
85 }
86
Daniel Lehmann25a02822010-05-11 15:52:43 -070087 setContentView(R.layout.contact_detail_activity);
Daniel Lehmann4cd94412010-04-08 16:44:36 -070088
Katherine Kuan79700882011-06-14 17:40:33 -070089 mViewPager = (ViewPager) findViewById(R.id.pager);
90 mViewPager.setAdapter(new ViewPagerAdapter(getFragmentManager()));
91 mViewPager.setOnPageChangeListener(mOnPageChangeListener);
Daniel Lehmanncdef2b62010-06-06 18:25:49 -070092
Katherine Kuan79700882011-06-14 17:40:33 -070093 mTabCarousel = (ContactDetailTabCarousel) findViewById(R.id.tab_carousel);
94 mTabCarousel.setListener(mTabCarouselListener);
95
96 mUri = getIntent().getData();
Daniel Lehmanncdef2b62010-06-06 18:25:49 -070097 Log.i(TAG, getIntent().getData().toString());
Daniel Lehmann4cd94412010-04-08 16:44:36 -070098 }
99
Katherine Kuan79700882011-06-14 17:40:33 -0700100
101 @Override
102 public void onAttachFragment(Fragment fragment) {
103 if (fragment instanceof ContactDetailAboutFragment) {
104 mAboutFragment = (ContactDetailAboutFragment) fragment;
105 mAboutFragment.setListener(mFragmentListener);
106 mAboutFragment.loadUri(mUri);
107 } else if (fragment instanceof ContactDetailUpdatesFragment) {
108 mUpdatesFragment = (ContactDetailUpdatesFragment) fragment;
109 }
110 }
111
Daniel Lehmann4cd94412010-04-08 16:44:36 -0700112 @Override
Daniel Lehmann4cd94412010-04-08 16:44:36 -0700113 public void startSearch(String initialQuery, boolean selectInitialQuery, Bundle appSearchData,
114 boolean globalSearch) {
115 if (globalSearch) {
116 super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
117 } else {
118 ContactsSearchManager.startSearch(this, initialQuery);
119 }
120 }
121
122 @Override
123 public boolean onKeyDown(int keyCode, KeyEvent event) {
Katherine Kuan79700882011-06-14 17:40:33 -0700124 FragmentKeyListener mCurrentFragment;
125 switch (mViewPager.getCurrentItem()) {
126 case 0:
127 mCurrentFragment = (FragmentKeyListener) mAboutFragment;
128 break;
129 case 1:
130 mCurrentFragment = (FragmentKeyListener) mUpdatesFragment;
131 break;
132 default:
133 throw new IllegalStateException("Invalid current item for ViewPager");
134 }
135 if (mCurrentFragment.handleKeyDown(keyCode)) return true;
Daniel Lehmann4cd94412010-04-08 16:44:36 -0700136
137 return super.onKeyDown(keyCode, event);
138 }
Daniel Lehmann18f104f2010-05-07 15:41:11 -0700139
Daniel Lehmanncdef2b62010-06-06 18:25:49 -0700140 private final ContactDetailFragment.Listener mFragmentListener =
141 new ContactDetailFragment.Listener() {
Daniel Lehmann69e7fec2010-07-20 14:14:56 -0700142 @Override
Daniel Lehmanncdef2b62010-06-06 18:25:49 -0700143 public void onContactNotFound() {
Daniel Lehmann18f104f2010-05-07 15:41:11 -0700144 finish();
145 }
146
Daniel Lehmann69e7fec2010-07-20 14:14:56 -0700147 @Override
Katherine Kuan79700882011-06-14 17:40:33 -0700148 public void onDetailsLoaded(ContactLoader.Result result) {
149 mTabCarousel.loadData(result);
150 }
151
152 @Override
Daniel Lehmann825cb622010-08-27 11:44:29 -0700153 public void onEditRequested(Uri contactLookupUri) {
154 startActivity(new Intent(Intent.ACTION_EDIT, contactLookupUri));
Daniel Lehmann18f104f2010-05-07 15:41:11 -0700155 }
156
Daniel Lehmann69e7fec2010-07-20 14:14:56 -0700157 @Override
Daniel Lehmanncdef2b62010-06-06 18:25:49 -0700158 public void onItemClicked(Intent intent) {
Daniel Lehmann60be1a12010-08-05 18:37:21 -0700159 try {
160 startActivity(intent);
161 } catch (ActivityNotFoundException e) {
162 Log.e(TAG, "No activity found for intent: " + intent);
163 }
Daniel Lehmann18f104f2010-05-07 15:41:11 -0700164 }
Daniel Lehmanncdef2b62010-06-06 18:25:49 -0700165
Daniel Lehmann69e7fec2010-07-20 14:14:56 -0700166 @Override
Dmitri Plotnikov66bca8f2010-11-24 16:59:24 -0800167 public void onDeleteRequested(Uri contactUri) {
Dmitri Plotnikovc9eda372011-02-23 08:58:13 -0800168 ContactDeletionInteraction.start(ContactDetailActivity.this, contactUri, true);
Daniel Lehmanncdef2b62010-06-06 18:25:49 -0700169 }
Dmitri Plotnikovcaf0bc72010-09-03 15:16:21 -0700170
171 @Override
172 public void onCreateRawContactRequested(
173 ArrayList<ContentValues> values, Account account) {
174 Toast.makeText(ContactDetailActivity.this, R.string.toast_making_personal_copy,
175 Toast.LENGTH_LONG).show();
176 Intent serviceIntent = ContactSaveService.createNewRawContactIntent(
Dmitri Plotnikov9d730dd2010-11-24 13:22:23 -0800177 ContactDetailActivity.this, values, account,
178 ContactDetailActivity.class, Intent.ACTION_VIEW);
Dmitri Plotnikovcaf0bc72010-09-03 15:16:21 -0700179 startService(serviceIntent);
180
181 }
Daniel Lehmanncdef2b62010-06-06 18:25:49 -0700182 };
Katherine Kuan79700882011-06-14 17:40:33 -0700183
184 public class ViewPagerAdapter extends FragmentPagerAdapter{
185
186 public ViewPagerAdapter(FragmentManager fm) {
187 super(fm);
188 }
189
190 @Override
191 public Fragment getItem(int position) {
192 switch (position) {
193 case 0:
194 return new ContactDetailAboutFragment();
195 case 1:
196 return new ContactDetailUpdatesFragment();
197 }
198 throw new IllegalStateException("No fragment at position " + position);
199 }
200
201 @Override
202 public int getCount() {
203 return FRAGMENT_COUNT;
204 }
205 }
206
207 private OnPageChangeListener mOnPageChangeListener = new OnPageChangeListener() {
208
209 @Override
210 public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
211 // The user is horizontally dragging the {@link ViewPager}, so send
212 // these scroll changes to the tab carousel. Ignore these events though if the carousel
213 // is actually controlling the {@link ViewPager} scrolls because it will already be
214 // in the correct position.
215 if (mViewPager.isFakeDragging()) {
216 return;
217 }
218 int x = (int) ((position + positionOffset) * mTabCarousel.getAllowedScrollLength());
219 mTabCarousel.scrollTo(x, 0);
220 }
221
222 @Override
223 public void onPageSelected(int position) {
224 // Since a new page has been selected by the {@link ViewPager},
225 // update the tab selection in the carousel.
226 mTabCarousel.setCurrentTab(position);
227 }
228
229 @Override
230 public void onPageScrollStateChanged(int state) {}
231
232 };
233
234 private ContactDetailTabCarousel.Listener mTabCarouselListener =
235 new ContactDetailTabCarousel.Listener() {
236
237 @Override
238 public void onTouchDown() {
239 // The user just started scrolling the carousel, so begin "fake dragging" the
240 // {@link ViewPager} if it's not already doing so.
241 if (mViewPager.isFakeDragging()) {
242 return;
243 }
244 mViewPager.beginFakeDrag();
245 }
246
247 @Override
248 public void onTouchUp() {
249 // The user just stopped scrolling the carousel, so stop "fake dragging" the
250 // {@link ViewPager} if was doing so before.
251 if (mViewPager.isFakeDragging()) {
252 mViewPager.endFakeDrag();
253 }
254 }
255
256 @Override
257 public void onScrollChanged(int l, int t, int oldl, int oldt) {
258 // The user is scrolling the carousel, so send the scroll deltas to the
259 // {@link ViewPager} so it can move in sync.
260 if (mViewPager.isFakeDragging()) {
261 mViewPager.fakeDragBy(oldl-l);
262 }
263 }
264
265 @Override
266 public void onTabSelected(int position) {
267 // The user selected a tab, so update the {@link ViewPager}
268 mViewPager.setCurrentItem(position);
269 }
270 };
271
272 /**
273 * This interface should be implemented by {@link Fragment}s within this
274 * activity so that the activity can determine whether the currently
275 * displayed view is handling the key event or not.
276 */
277 public interface FragmentKeyListener {
278 /**
279 * Returns true if the key down event will be handled by the implementing class, or false
280 * otherwise.
281 */
282 public boolean handleKeyDown(int keyCode);
283 }
Daniel Lehmann4cd94412010-04-08 16:44:36 -0700284}