drawer: improve layout
Remove the account spinner. The account list is directly displayed in
the drawer. The 'Add account' action is also available from the drawer.
Tuleap: #1218
Change-Id: Idf6fcaeef8202b26ac0c406e46fee2d8c9f1eb90
diff --git a/ring-android/app/src/main/java/cx/ring/adapters/AccountSelectionAdapter.java b/ring-android/app/src/main/java/cx/ring/adapters/AccountSelectionAdapter.java
deleted file mode 100644
index 2020943..0000000
--- a/ring-android/app/src/main/java/cx/ring/adapters/AccountSelectionAdapter.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) 2004-2016 Savoir-faire Linux Inc.
- *
- * Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
- * Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-package cx.ring.adapters;
-
-import android.content.Context;
-import android.support.v4.content.ContextCompat;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import cx.ring.R;
-import cx.ring.model.Account;
-
-public class AccountSelectionAdapter extends BaseAdapter {
-
- private static final String TAG = AccountSelectionAdapter.class.getSimpleName();
-
- private final List<Account> all_accounts = new ArrayList<>();
- private final List<Account> accounts = new ArrayList<>();
- private final Context mContext;
- private int selectedAccount = -1;
-
- public AccountSelectionAdapter(Context cont, List<Account> newList) {
- super();
- mContext = cont;
- setAccounts(newList);
- }
-
- @Override
- public int getCount() {
- return accounts.size();
- }
-
- @Override
- public Account getItem(int pos) {
- return accounts.get(pos);
- }
-
- @Override
- public long getItemId(int pos) {
- return 0;
- }
-
- @Override
- public View getView(int pos, View convertView, ViewGroup parent) {
- View rowView = convertView;
- AccountView entryView = null;
-
- if (rowView == null) {
- LayoutInflater inflater = LayoutInflater.from(mContext);
- rowView = inflater.inflate(R.layout.item_account_selected, parent, false);
-
- entryView = new AccountView();
- entryView.alias = (TextView) rowView.findViewById(R.id.account_alias);
- entryView.host = (TextView) rowView.findViewById(R.id.account_host);
- entryView.error = (ImageView) rowView.findViewById(R.id.error_indicator);
- rowView.setTag(entryView);
- } else {
- entryView = (AccountView) rowView.getTag();
- }
- entryView.error.setColorFilter(ContextCompat.getColor(mContext, R.color.error_red));
-
-/*
- entryView.alias.setText(accounts.get(pos).getAlias());
-
- entryView.host.setText(accounts.get(pos).getHost() + " - " + accounts.get(pos).getRegistrationState());
- // accManager.displayAccountDetails(accounts.get(pos), entryView);
- entryView.error.setVisibility(View.GONE);
-*/
- updateAccountView(entryView, accounts.get(pos));
-
- return rowView;
- }
-
- @Override
- public View getDropDownView(int pos, View convertView, ViewGroup parent) {
- View rowView = convertView;
- AccountView entryView = null;
-
- if (rowView == null) {
- LayoutInflater inflater = LayoutInflater.from(mContext);
- rowView = inflater.inflate(R.layout.item_account, parent, false);
-
- entryView = new AccountView();
- entryView.alias = (TextView) rowView.findViewById(R.id.account_alias);
- entryView.host = (TextView) rowView.findViewById(R.id.account_host);
- entryView.error = (ImageView) rowView.findViewById(R.id.error_indicator);
- rowView.setTag(entryView);
- } else {
- entryView = (AccountView) rowView.getTag();
- }
- entryView.error.setColorFilter(ContextCompat.getColor(mContext, R.color.error_red));
-
- updateAccountView(entryView, accounts.get(pos));
- return rowView;
- }
-
- private void updateAccountView(AccountView entryView, Account acc) {
- entryView.alias.setText(acc.getAlias());
- if (acc.isRing()) {
- entryView.host.setText(acc.getUsername());
- } else {
- entryView.host.setText(acc.getUsername() + "@" + acc.getHost());
- }
- entryView.error.setVisibility(acc.isRegistered() ? View.GONE : View.VISIBLE);
- }
-
- public Account getAccount(String accountID) {
- for(Account acc : accounts) {
- if(acc.getAccountID().contentEquals(accountID))
- return acc;
- }
- return null;
- }
-
- /*********************
- * ViewHolder Pattern
- *********************/
- public class AccountView {
- public TextView alias;
- public TextView host;
- public ImageView error;
- }
-
- public void setSelectedAccount(int pos) {
- selectedAccount = pos;
- }
-
- public Account getSelectedAccount() {
- return getAccount(selectedAccount);
- }
-
- public void replaceAll(List<Account> results) {
- setAccounts(results);
- notifyDataSetChanged();
- }
-
- private void setAccounts(List<Account> results) {
- all_accounts.clear();
- accounts.clear();
- all_accounts.addAll(results);
- for (Account acc : results)
- if (acc.isEnabled())
- accounts.add(acc);
- setSelectedAccount(accounts.isEmpty() ? -1 : 0);
- }
-
- public Account getAccount(int pos) {
- if (pos < 0 || pos >= accounts.size())
- return null;
- return accounts.get(pos);
- }
-
- public List<String> getAccountOrder() {
- List<String> result = new ArrayList<>(accounts.size());
- String selectedID = accounts.get(selectedAccount).getAccountID();
- result.add(selectedID);
- for (Account a : all_accounts) {
- if (a.getAccountID().contentEquals(selectedID))
- continue;
- result.add(a.getAccountID());
- }
- return result;
- }
-
-}
diff --git a/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java b/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java
index 46c1c6a..9821199 100644
--- a/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java
+++ b/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java
@@ -180,6 +180,9 @@
@Override
public void onDrawerClosed(View view) {
invalidateOptionsMenu();
+ if (fNavigation != null) {
+ fNavigation.displayNavigation();
+ }
}
@Override
@@ -486,8 +489,6 @@
if (fContent == null) {
fContent = new SmartListFragment();
fragmentManager.beginTransaction().replace(R.id.main_frame, fContent, HOME_TAG).addToBackStack(HOME_TAG).commit();
-
-
} else if (fContent instanceof Refreshable) {
fragmentManager.beginTransaction().replace(R.id.main_frame, fContent).addToBackStack(HOME_TAG).commit();
((Refreshable) fContent).refresh();
@@ -499,7 +500,6 @@
public void onServiceDisconnected(ComponentName className) {
Log.d(TAG, "onServiceDisconnected " + className.getClassName());
if (fNavigation != null) {
- fNavigation.setCallbacks(null);
fNavigation = null;
}
mBound = false;
@@ -509,7 +509,10 @@
// TODO: Remove this when low level services are ready
public void onNavigationViewReady() {
if (fNavigation != null) {
- fNavigation.setCallbacks(service);
+ if (service != null) {
+ fNavigation.updateAccounts(service.getAccounts());
+ }
+ fNavigation.setCallback(service);
fNavigation.setNavigationSectionSelectedListener(HomeActivity.this);
fNavigation.registerAccountSelectionListener((RingNavigationFragment.MenuHeaderAccountSelectionListener) fContent);
}
@@ -608,6 +611,17 @@
}
}
+ @Override
+ public void onAccountSelected() {
+ mNavigationDrawer.closeDrawers();
+ }
+
+ @Override
+ public void onAddAccountSelected() {
+ mNavigationDrawer.closeDrawers();
+ startActivityForResult(new Intent(HomeActivity.this, AccountWizard.class), AccountsManagementFragment.ACCOUNT_CREATE_REQUEST);
+ }
+
private void goToShare() {
if (fContent instanceof ShareFragment) {
return;
diff --git a/ring-android/app/src/main/java/cx/ring/navigation/AccountAdapter.java b/ring-android/app/src/main/java/cx/ring/navigation/AccountAdapter.java
new file mode 100644
index 0000000..41e983a
--- /dev/null
+++ b/ring-android/app/src/main/java/cx/ring/navigation/AccountAdapter.java
@@ -0,0 +1,193 @@
+/**
+ * Copyright (C) 2016 by Savoir-faire Linux
+ * Author : Alexandre Lision <alexandre.lision@savoirfairelinux.com>
+ * <p>
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * <p>
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ * *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package cx.ring.navigation;
+
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import java.util.List;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import cx.ring.R;
+import cx.ring.model.Account;
+
+class AccountAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
+ private List<Account> mDataset;
+
+ private static final int TYPE_ACCOUNT = 0;
+ private static final int TYPE_ADD_RING_ACCOUNT = 1;
+ private static final int TYPE_ADD_SIP_ACCOUNT = 2;
+ private OnAccountActionClicked mListener;
+
+ public List<Account> getAccounts() {
+ return mDataset;
+ }
+
+ interface OnAccountActionClicked {
+ void onAccountSelected(Account account);
+
+ void onAddAccountSelected();
+ }
+
+ AccountAdapter(List<Account> accounts) {
+ mDataset = accounts;
+ }
+
+ void setOnAccountActionClickedListener(OnAccountActionClicked listener) {
+ mListener = listener;
+ }
+
+ public void replaceAll(List<Account> results) {
+ setAccounts(results);
+ notifyDataSetChanged();
+ }
+
+ private void setAccounts(List<Account> results) {
+ mDataset.clear();
+ for (Account account : results) {
+ mDataset.add(account);
+ }
+ }
+
+ class AccountView extends RecyclerView.ViewHolder implements View.OnClickListener {
+
+ @BindView(R.id.account_alias)
+ TextView alias;
+
+ @BindView(R.id.account_host)
+ TextView host;
+
+ @BindView(R.id.error_indicator)
+ ImageView error;
+
+ AccountView(View view) {
+ super(view);
+ ButterKnife.bind(this, view);
+ view.setOnClickListener(this);
+ }
+ @Override
+ public void onClick(View v) {
+ if (mListener != null) {
+ mListener.onAccountSelected(mDataset.get(getAdapterPosition()));
+ }
+ }
+
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ if (position == mDataset.size()) {
+ return TYPE_ADD_RING_ACCOUNT;
+ }
+ if (position == mDataset.size() + 1) {
+ return TYPE_ADD_SIP_ACCOUNT;
+ }
+ return TYPE_ACCOUNT;
+ }
+
+ public class AddAccountView extends RecyclerView.ViewHolder implements View.OnClickListener {
+ private final int viewtype;
+
+ @BindView(R.id.navigation_item_title)
+ TextView title;
+
+ @BindView(R.id.navigation_item_icon)
+ ImageView icon;
+
+ AddAccountView(View view, int type) {
+ super(view);
+ viewtype = type;
+ ButterKnife.bind(this, view);
+ view.setOnClickListener(this);
+ }
+ @Override
+ public void onClick(View v) {
+ if (mListener == null) {
+ return;
+ }
+ if (viewtype == TYPE_ADD_RING_ACCOUNT || viewtype == TYPE_ADD_SIP_ACCOUNT) {
+ mListener.onAddAccountSelected();
+ }
+ }
+
+ }
+
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent,
+ int viewType) {
+ RecyclerView.ViewHolder viewHolder;
+ View holderView;
+ switch (viewType) {
+ case TYPE_ACCOUNT:
+ holderView = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.item_account, parent, false);
+ viewHolder = new AccountView(holderView);
+
+ break;
+ case TYPE_ADD_SIP_ACCOUNT:
+ case TYPE_ADD_RING_ACCOUNT:
+ holderView = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.item_menu, parent, false);
+ viewHolder = new AddAccountView(holderView, viewType);
+ break;
+ default:
+ return null;
+ }
+
+ return viewHolder;
+ }
+
+ @Override
+ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+
+ switch (getItemViewType(position)) {
+ case TYPE_ACCOUNT:
+ Account account = mDataset.get(position);
+ ((AccountView) holder).alias.setText(account.getAlias());
+ if (account.isRing()) {
+ ((AccountView) holder).host.setText(account.getUsername());
+ } else if (account.isSip() && !account.isIP2IP()) {
+ ((AccountView) holder).host.setText(account.getUsername() + "@" + account.getHost());
+ } else {
+ ((AccountView) holder).host.setText(R.string.account_type_ip2ip);
+ }
+
+ ((AccountView) holder).error.setVisibility(account.isRegistered() ? View.GONE : View.VISIBLE);
+ break;
+ case TYPE_ADD_SIP_ACCOUNT:
+ case TYPE_ADD_RING_ACCOUNT:
+ ((AddAccountView) holder).icon.setImageResource(R.drawable.ic_add_black_24dp);
+ ((AddAccountView) holder).title.setText(R.string.add_account_title);
+ break;
+ default:
+ break;
+ }
+ }
+
+ // Return the size of your dataset (invoked by the layout manager)
+ @Override
+ public int getItemCount() {
+ // Add two entries for account creation
+ return mDataset.size() + 1;
+ }
+}
\ No newline at end of file
diff --git a/ring-android/app/src/main/java/cx/ring/navigation/RingNavigationFragment.java b/ring-android/app/src/main/java/cx/ring/navigation/RingNavigationFragment.java
index 2ccebd5..6d338a8 100644
--- a/ring-android/app/src/main/java/cx/ring/navigation/RingNavigationFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/navigation/RingNavigationFragment.java
@@ -33,25 +33,26 @@
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.res.ResourcesCompat;
+import android.support.v7.widget.AppCompatImageView;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
-import android.widget.Spinner;
+import android.widget.RelativeLayout;
import android.widget.TextView;
import java.io.ByteArrayOutputStream;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
+import java.util.Observable;
+import java.util.Observer;
import javax.inject.Inject;
@@ -59,7 +60,6 @@
import butterknife.ButterKnife;
import butterknife.OnClick;
import cx.ring.R;
-import cx.ring.adapters.AccountSelectionAdapter;
import cx.ring.adapters.ContactDetailsTask;
import cx.ring.application.RingApplication;
import cx.ring.client.AccountWizard;
@@ -75,10 +75,11 @@
import ezvcard.property.Photo;
import ezvcard.property.RawProperty;
-public class RingNavigationFragment extends Fragment implements NavigationAdapter.OnNavigationItemClicked {
+public class RingNavigationFragment extends Fragment implements NavigationAdapter.OnNavigationItemClicked,
+ AccountAdapter.OnAccountActionClicked, Observer {
private static final String TAG = RingNavigationFragment.class.getSimpleName();
- private AccountSelectionAdapter mAccountAdapter;
+ private AccountAdapter mAccountAdapter;
@Inject
StateService mStateService;
@@ -88,7 +89,7 @@
***************/
@BindView(R.id.account_selection)
- Spinner mSpinnerAccounts;
+ RelativeLayout mSelectedAccountLayout;
@BindView(R.id.addaccount_btn)
Button mNewAccountBtn;
@@ -102,6 +103,18 @@
private ImageView mProfilePhoto;
private VCard mVCardProfile;
+ @BindView(R.id.account_alias)
+ TextView mSelectedAccountAlias;
+
+ @BindView(R.id.account_host)
+ TextView mSelectedAccountHost;
+
+ @BindView(R.id.account_selected_error_indicator)
+ AppCompatImageView mSelectedAccountError;
+
+ @BindView(R.id.account_selected_arrow)
+ AppCompatImageView mSelectedAccountArrow;
+
/**************
* Menu views
**************/
@@ -109,18 +122,87 @@
@BindView(R.id.drawer_menu)
RecyclerView mMenuView;
+ @BindView(R.id.drawer_accounts)
+ RecyclerView mAccountsView;
+
private NavigationAdapter mMenuAdapter;
private OnNavigationSectionSelected mSectionListener;
private List<WeakReference<MenuHeaderAccountSelectionListener>> mListeners;
+ private LocalService mLocalService;
+
+ @Override
+ public void onAccountSelected(Account selectedAccount) {
+
+ toggleAccountList();
+ // modify the state of the app
+ // State observers will be notified
+ mStateService.setCurrentAccount(selectedAccount);
+
+ //TODO: remove this when low level services are ready
+ List<String> orderedAccountIdList = new ArrayList<>();
+ String selectedID = selectedAccount.getAccountID();
+ orderedAccountIdList.add(selectedID);
+ for (Account account : mAccountAdapter.getAccounts()) {
+ if (account.getAccountID().contentEquals(selectedID)) {
+ continue;
+ }
+ orderedAccountIdList.add(account.getAccountID());
+ }
+
+ mLocalService.setAccountOrder(orderedAccountIdList);
+
+ for (WeakReference<MenuHeaderAccountSelectionListener> weakListener : mListeners) {
+ MenuHeaderAccountSelectionListener listener = weakListener.get();
+ if (listener != null) {
+ listener.accountSelected(mStateService.getCurrentAccount());
+ }
+ }
+
+ if (mSectionListener != null) {
+ mSectionListener.onAccountSelected();
+ }
+ }
+
+ @Override
+ public void onAddAccountSelected() {
+ toggleAccountList();
+ if (mSectionListener != null) {
+ mSectionListener.onAddAccountSelected();
+ }
+ }
+
+ @Override
+ public void update(Observable o, Object arg) {
+ updateSelectedAccountView();
+ }
+
+ public void setCallback(LocalService callback) {
+ mLocalService = callback;
+ }
public interface OnNavigationSectionSelected {
void onNavigationSectionSelected(Section position);
+ void onAccountSelected();
+ void onAddAccountSelected();
}
public interface MenuHeaderAccountSelectionListener {
void accountSelected(Account account);
}
+ @Override
+ public void onResume() {
+ super.onResume();
+ mStateService.addObserver(this);
+ updateSelectedAccountView();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ mStateService.deleteObserver(this);
+ }
+
/**
* Exposed enumeration listing app sections
*/
@@ -172,8 +254,6 @@
// dependency injection
((RingApplication) getActivity().getApplication()).getRingInjectionComponent().inject(this);
- mAccountAdapter = new AccountSelectionAdapter(getActivity(), new ArrayList<Account>());
- mSpinnerAccounts.setAdapter(mAccountAdapter);
mVCardProfile = VCardUtils.loadLocalProfileFromDisk(getActivity());
updateUserView();
@@ -181,9 +261,21 @@
mListeners = new ArrayList<>();
setupNavigationMenu();
+ setupAccountList();
+
return inflatedView;
}
+ private void setupAccountList() {
+ mAccountAdapter = new AccountAdapter(new ArrayList<Account>());
+ mAccountsView.setHasFixedSize(true);
+ mAccountAdapter.setOnAccountActionClickedListener(this);
+ LinearLayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
+ mAccountsView.setLayoutManager(mLayoutManager);
+ mAccountsView.setAdapter(mAccountAdapter);
+ mAccountsView.setVisibility(View.GONE);
+ }
+
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
@@ -191,10 +283,33 @@
((HomeActivity) getActivity()).onNavigationViewReady();
}
+ /**
+ * Can be called to reset the UI to the initial state, displaying the navigation items
+ */
+ public void displayNavigation() {
+ mMenuView.setVisibility(View.VISIBLE);
+ mAccountsView.setVisibility(View.GONE);
+ mSelectedAccountArrow.setImageResource(R.drawable.ic_arrow_drop_down_black_24dp);
+ }
+
public void selectSection(Section manage) {
mMenuAdapter.setSelection(manage.position);
}
+ @OnClick(R.id.account_selection)
+ public void toggleAccountList() {
+ boolean navigationIsDisplaying = mMenuView.getVisibility() == View.VISIBLE;
+ if (navigationIsDisplaying) {
+ mMenuView.setVisibility(View.GONE);
+ mAccountsView.setVisibility(View.VISIBLE);
+ mSelectedAccountArrow.setImageResource(R.drawable.ic_arrow_drop_up_black_24dp);
+ } else {
+ mMenuView.setVisibility(View.VISIBLE);
+ mAccountsView.setVisibility(View.GONE);
+ mSelectedAccountArrow.setImageResource(R.drawable.ic_arrow_drop_down_black_24dp);
+ }
+ }
+
@Override
public void onNavigationItemClicked(int position) {
if (mSectionListener != null) {
@@ -202,41 +317,9 @@
}
}
-
- public void setCallbacks(final LocalService service) {
- if (service != null) {
- mSpinnerAccounts.setOnItemSelectedListener(new OnItemSelectedListener() {
- @Override
- public void onItemSelected(AdapterView<?> arg0, View view, int pos, long arg3) {
- if (mAccountAdapter.getAccount(pos) != mAccountAdapter.getSelectedAccount()) {
- mAccountAdapter.setSelectedAccount(pos);
- service.setAccountOrder(mAccountAdapter.getAccountOrder());
- }
-
- // modify the state of the app
- // State observers will be notified
- mStateService.setCurrentAccount(getSelectedAccount());
-
- for (WeakReference<MenuHeaderAccountSelectionListener> weakListener : mListeners) {
- MenuHeaderAccountSelectionListener listener = weakListener.get();
- if (listener != null) {
- listener.accountSelected(getSelectedAccount());
- }
- }
- }
-
- @Override
- public void onNothingSelected(AdapterView<?> arg0) {
- mAccountAdapter.setSelectedAccount(-1);
- }
- });
- updateAccounts(service.getAccounts());
- }
- }
-
public void registerAccountSelectionListener(MenuHeaderAccountSelectionListener listener) {
mListeners.add(new WeakReference<>(listener));
- listener.accountSelected(getSelectedAccount());
+ listener.accountSelected(mStateService.getCurrentAccount());
}
public void updateUserView() {
@@ -250,7 +333,6 @@
}
mUserName.setText(mVCardProfile.getFormattedName().getValue());
Log.d(TAG, "User did change, updating user view.");
-
}
public void updatePhoto(Uri uriImage) {
@@ -371,28 +453,36 @@
builder.show();
}
- public Account getSelectedAccount() {
- return mAccountAdapter.getSelectedAccount();
- }
-
public void updateAccounts(List<Account> accounts) {
-
+ mAccountAdapter.replaceAll(accounts);
if (accounts.isEmpty()) {
mNewAccountBtn.setVisibility(View.VISIBLE);
- mSpinnerAccounts.setVisibility(View.GONE);
+ mSelectedAccountLayout.setVisibility(View.GONE);
// modify the state of the app
// State observers will be notified
mStateService.setCurrentAccount(null);
} else {
mNewAccountBtn.setVisibility(View.GONE);
- mSpinnerAccounts.setVisibility(View.VISIBLE);
- mAccountAdapter.replaceAll(accounts);
- mSpinnerAccounts.setSelection(0);
-
- // modify the state of the app
- // State observers will be notified
- mStateService.setCurrentAccount(getSelectedAccount());
+ mSelectedAccountLayout.setVisibility(View.VISIBLE);
+ Account selected = accounts.get(0);
+ mStateService.setCurrentAccount(selected);
}
}
+
+ private void updateSelectedAccountView() {
+ Account selectedAccount = mStateService.getCurrentAccount();
+ if (selectedAccount == null) {
+ return;
+ }
+ mSelectedAccountAlias.setText(selectedAccount.getAlias());
+ if (selectedAccount.isRing()) {
+ mSelectedAccountHost.setText(selectedAccount.getUsername());
+ } else if (selectedAccount.isSip() && !selectedAccount.isIP2IP()) {
+ mSelectedAccountHost.setText(selectedAccount.getUsername() + "@" + selectedAccount.getHost());
+ } else {
+ mSelectedAccountHost.setText(R.string.account_type_ip2ip);
+ }
+ mSelectedAccountError.setVisibility(selectedAccount.isRegistered() ? View.GONE : View.VISIBLE);
+ }
}
diff --git a/ring-android/app/src/main/res/drawable/ic_add_black_24dp.xml b/ring-android/app/src/main/res/drawable/ic_add_black_24dp.xml
new file mode 100644
index 0000000..0258249
--- /dev/null
+++ b/ring-android/app/src/main/res/drawable/ic_add_black_24dp.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
+</vector>
diff --git a/ring-android/app/src/main/res/drawable/ic_arrow_drop_down_black_24dp.xml b/ring-android/app/src/main/res/drawable/ic_arrow_drop_down_black_24dp.xml
new file mode 100644
index 0000000..62b27ef
--- /dev/null
+++ b/ring-android/app/src/main/res/drawable/ic_arrow_drop_down_black_24dp.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M7,10l5,5 5,-5z"/>
+</vector>
diff --git a/ring-android/app/src/main/res/drawable/ic_arrow_drop_up_black_24dp.xml b/ring-android/app/src/main/res/drawable/ic_arrow_drop_up_black_24dp.xml
new file mode 100644
index 0000000..b1442ce
--- /dev/null
+++ b/ring-android/app/src/main/res/drawable/ic_arrow_drop_up_black_24dp.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M7,14l5,-5 5,5z"/>
+</vector>
diff --git a/ring-android/app/src/main/res/layout/frag_navigation.xml b/ring-android/app/src/main/res/layout/frag_navigation.xml
index d894b9c..2eb3dbb 100644
--- a/ring-android/app/src/main/res/layout/frag_navigation.xml
+++ b/ring-android/app/src/main/res/layout/frag_navigation.xml
@@ -16,8 +16,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/color_primary_dark"
- android:paddingLeft="16dp"
- android:paddingRight="16dp"
+
android:paddingTop="30dp"
android:theme="@style/MenuHeader">
@@ -68,9 +67,10 @@
</RelativeLayout>
- <Spinner
+
+ <RelativeLayout
android:id="@+id/account_selection"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentLeft="true"
@@ -79,10 +79,14 @@
android:layout_below="@+id/profile_container"
android:layout_toEndOf="@+id/profile_container"
android:layout_toRightOf="@+id/profile_container"
- android:visibility="visible"
- tools:listitem="@layout/item_account_selected" />
+ android:background="?attr/selectableItemBackground"
+ android:clickable="true">
- <Button
+ <include layout="@layout/item_account_selected" />
+
+ </RelativeLayout>
+
+ <android.support.v7.widget.AppCompatButton
android:id="@+id/addaccount_btn"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="wrap_content"
@@ -92,8 +96,12 @@
android:layout_alignParentRight="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/profile_container"
+ android:layout_toEndOf="@+id/profile_container"
+ android:layout_toRightOf="@+id/profile_container"
+ android:gravity="center"
android:text="@string/action_create"
android:visibility="gone" />
+
</RelativeLayout>
<FrameLayout
@@ -108,6 +116,13 @@
android:nestedScrollingEnabled="false"
tools:targetApi="lollipop" />
+ <android.support.v7.widget.RecyclerView
+ android:id="@+id/drawer_accounts"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:nestedScrollingEnabled="false"
+ tools:targetApi="lollipop" />
+
</FrameLayout>
</LinearLayout>
diff --git a/ring-android/app/src/main/res/layout/item_account.xml b/ring-android/app/src/main/res/layout/item_account.xml
index 68c6cc2..871ca8f 100644
--- a/ring-android/app/src/main/res/layout/item_account.xml
+++ b/ring-android/app/src/main/res/layout/item_account.xml
@@ -19,9 +19,10 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:background="?android:attr/selectableItemBackground"
android:padding="16dp">
- <TextView
+ <android.support.v7.widget.AppCompatTextView
android:id="@+id/account_alias"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -30,7 +31,7 @@
android:layout_alignParentTop="true"
android:textAppearance="@style/ListPrimary" />
- <TextView
+ <android.support.v7.widget.AppCompatTextView
android:id="@+id/account_host"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -39,11 +40,12 @@
android:layout_below="@+id/account_alias"
android:layout_toLeftOf="@+id/error_indicator"
android:layout_toStartOf="@+id/error_indicator"
- android:ellipsize="middle"
+ android:ellipsize="end"
+ android:maxLines="1"
android:singleLine="true"
android:textAppearance="@style/ListSecondary" />
- <ImageView
+ <android.support.v7.widget.AppCompatImageView
android:id="@+id/error_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/ring-android/app/src/main/res/layout/item_account_selected.xml b/ring-android/app/src/main/res/layout/item_account_selected.xml
index 66390dc..a78778b 100644
--- a/ring-android/app/src/main/res/layout/item_account_selected.xml
+++ b/ring-android/app/src/main/res/layout/item_account_selected.xml
@@ -1,47 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="72dp"
- android:paddingBottom="16dp"
- android:paddingRight="16dp"
- android:paddingStart="16dp"
- android:paddingTop="16dp">
+ android:padding="16dp">
- <TextView
+ <android.support.v7.widget.AppCompatTextView
android:id="@+id/account_alias"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignParentLeft="false"
+ android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
+ android:layout_toLeftOf="@+id/account_selected_error_indicator"
+ android:layout_toStartOf="@+id/account_selected_error_indicator"
+ android:fontFamily="sans-serif-medium"
android:textAppearance="?android:attr/textAppearanceMedium"
- android:textColor="@color/white" />
+ android:textColor="@color/white"
+ tools:text="Alias" />
- <TextView
+ <android.support.v7.widget.AppCompatTextView
android:id="@+id/account_host"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignParentLeft="false"
+ android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/account_alias"
- android:layout_toLeftOf="@+id/error_indicator"
- android:layout_toStartOf="@+id/error_indicator"
- android:ellipsize="middle"
+ android:layout_toLeftOf="@+id/account_selected_arrow"
+ android:layout_toStartOf="@+id/account_selected_arrow"
+ android:ellipsize="end"
+ android:maxLines="1"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="@color/secondary_text_default_material_dark" />
+ android:textColor="@color/white"
+ tools:text="ring:762db5e2ff4c8fc8d2316b38f1c6d1a2a923620b" />
- <ImageView
- android:id="@+id/error_indicator"
+ <android.support.v7.widget.AppCompatImageView
+ android:id="@+id/account_selected_error_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
- android:layout_alignParentRight="false"
- android:layout_centerVertical="true"
+ android:layout_alignParentRight="true"
+ android:layout_alignParentTop="true"
+ android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
android:clickable="false"
android:focusable="false"
android:src="@drawable/ic_error_white" />
+ <android.support.v7.widget.AppCompatImageView
+ android:id="@+id/account_selected_arrow"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentEnd="true"
+ android:layout_alignParentRight="true"
+ android:alpha="0.54"
+ android:clickable="false"
+ android:focusable="false"
+ android:src="@drawable/ic_arrow_drop_down_black_24dp"
+ android:tint="@color/white" />
+
</RelativeLayout>
\ No newline at end of file
diff --git a/ring-android/app/src/main/res/values/strings_account.xml b/ring-android/app/src/main/res/values/strings_account.xml
index 1d3e7cd..2fac77a 100644
--- a/ring-android/app/src/main/res/values/strings_account.xml
+++ b/ring-android/app/src/main/res/values/strings_account.xml
@@ -25,6 +25,7 @@
<string name="ic_advanced_menu">Advanced settings</string>
<!-- Strings related to account creation -->
+ <string name="add_account_title">Add account</string>
<string name="prompt_alias">Alias</string>
<string name="prompt_hostname">Hostname</string>
<string name="prompt_username">Username</string>
@@ -46,6 +47,7 @@
<item>RING</item>
<item>SIP</item>
</string-array>
+ <string name="account_type_ip2ip">IP account</string>
<string name="help_ring_title">Create a Ring account</string>
<string name="help_ring">A Ring account allows you to reach people securely in peer to peer through a fully distributed network.</string>