blob: 4e4f35a0aaf2a280757e4693781ff131adc60c6d [file] [log] [blame]
/*
* Copyright (C) 2016 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.editor;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.StringRes;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ListPopupWindow;
import android.widget.TextView;
import com.android.contacts.R;
import com.android.contacts.model.account.AccountInfo;
import com.android.contacts.model.account.AccountWithDataSet;
import com.android.contacts.util.AccountsListAdapter;
import com.android.contacts.util.UiClosables;
import java.util.List;
/**
* Controls the display of an account selector or header.
*
* TODO: This was mostly copied from {@link RawContactEditorView}. The code in that class
* should probably be modified to use this instead of leaving it duplicated.
*/
public class AccountHeaderPresenter {
private static final String KEY_SELECTED_ACCOUNT = "accountHeaderSelectedAccount";
public interface Observer {
void onChange(AccountHeaderPresenter sender);
public static final Observer NONE = new Observer() {
@Override
public void onChange(AccountHeaderPresenter sender) {
}
};
}
private final Context mContext;
private List<AccountInfo> mAccounts;
private AccountWithDataSet mCurrentAccount;
// Account header
private final View mAccountHeaderContainer;
private TextView mAccountHeaderType;
private TextView mAccountHeaderName;
private ImageView mAccountHeaderIcon;
private ImageView mAccountHeaderExpanderIcon;
// This would be different if the account was readonly
@StringRes
private int mSelectorTitle = R.string.editor_account_selector_title;
private Observer mObserver = Observer.NONE;
public AccountHeaderPresenter(View container) {
mContext = container.getContext();
mAccountHeaderContainer = container;
// mAccountHeaderType is optional and may not be in the container view in which case
// the variable will be null
mAccountHeaderType = (TextView) container.findViewById(R.id.account_type);
mAccountHeaderName = (TextView) container.findViewById(R.id.account_name);
mAccountHeaderIcon = (ImageView) container.findViewById(R.id.account_type_icon);
mAccountHeaderExpanderIcon = (ImageView) container.findViewById(R.id.account_expander_icon);
}
public void setObserver(Observer observer) {
mObserver = observer;
}
public void setCurrentAccount(@NonNull AccountWithDataSet account) {
if (mCurrentAccount != null && mCurrentAccount.equals(account)) {
return;
}
mCurrentAccount = account;
if (mObserver != null) {
mObserver.onChange(this);
}
updateDisplayedAccount();
}
public void setAccounts(List<AccountInfo> accounts) {
mAccounts = accounts;
// If the current account hasn't been set or it has been removed just use the first
// account.
if (mCurrentAccount == null || !AccountInfo.contains(mAccounts, mCurrentAccount)) {
mCurrentAccount = mAccounts.isEmpty() ? null : accounts.get(0).getAccount();
mObserver.onChange(this);
}
updateDisplayedAccount();
}
public AccountWithDataSet getCurrentAccount() {
return mCurrentAccount != null ? mCurrentAccount : null;
}
public void onSaveInstanceState(Bundle outState) {
outState.putParcelable(KEY_SELECTED_ACCOUNT, mCurrentAccount);
}
public void onRestoreInstanceState(Bundle savedInstanceState) {
if (savedInstanceState == null) return;
if (mCurrentAccount == null) {
mCurrentAccount = savedInstanceState.getParcelable(KEY_SELECTED_ACCOUNT);
}
updateDisplayedAccount();
}
private void updateDisplayedAccount() {
mAccountHeaderContainer.setVisibility(View.GONE);
if (mCurrentAccount == null) return;
if (mAccounts == null) return;
final String accountLabel = getAccountLabel(mCurrentAccount);
if (mAccounts.size() > 1) {
addAccountSelector(accountLabel);
} else {
addAccountHeader(accountLabel);
}
}
private void addAccountHeader(String accountLabel) {
mAccountHeaderContainer.setVisibility(View.VISIBLE);
// Set the account name
mAccountHeaderName.setVisibility(View.VISIBLE);
mAccountHeaderName.setText(accountLabel);
// Set the account type
final String selectorTitle = mContext.getResources().getString(mSelectorTitle);
if (mAccountHeaderType != null) {
mAccountHeaderType.setText(selectorTitle);
}
final AccountInfo accountInfo = AccountInfo.getAccount(mAccounts, mCurrentAccount);
// Set the icon
mAccountHeaderIcon.setImageDrawable(accountInfo.getIcon());
// Set the content description
mAccountHeaderContainer.setContentDescription(
EditorUiUtils.getAccountInfoContentDescription(accountLabel,
selectorTitle));
}
private void addAccountSelector(CharSequence nameLabel) {
final View.OnClickListener onClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
showPopup();
}
};
setUpAccountSelector(nameLabel.toString(), onClickListener);
}
private void showPopup() {
final ListPopupWindow popup = new ListPopupWindow(mContext);
final AccountsListAdapter adapter =
new AccountsListAdapter(mContext, mAccounts, mCurrentAccount);
popup.setWidth(mAccountHeaderContainer.getWidth());
popup.setAnchorView(mAccountHeaderContainer);
popup.setAdapter(adapter);
popup.setModal(true);
popup.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED);
popup.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
UiClosables.closeQuietly(popup);
final AccountWithDataSet newAccount = adapter.getItem(position);
setCurrentAccount(newAccount);
// Make sure the new selection will be announced once it's changed
mAccountHeaderContainer.setAccessibilityLiveRegion(
View.ACCESSIBILITY_LIVE_REGION_POLITE);
}
});
mAccountHeaderContainer.post(new Runnable() {
@Override
public void run() {
popup.show();
}
});
}
private void setUpAccountSelector(String nameLabel, View.OnClickListener listener) {
addAccountHeader(nameLabel);
// Add handlers for choosing another account to save to.
mAccountHeaderExpanderIcon.setVisibility(View.VISIBLE);
// Add the listener to the icon so that it will be announced by talkback as a clickable
// element
mAccountHeaderExpanderIcon.setOnClickListener(listener);
mAccountHeaderContainer.setOnClickListener(listener);
}
private String getAccountLabel(AccountWithDataSet account) {
final AccountInfo accountInfo = AccountInfo.getAccount(mAccounts, account);
return accountInfo != null ? accountInfo.getNameLabel().toString() : null;
}
}