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>