move to ViewBinding

Change-Id: I1ef0835bf585654989b29879c0e2ff0eefd721c3
diff --git a/ring-android/app/build.gradle b/ring-android/app/build.gradle
index 2cb0be5..147589f 100644
--- a/ring-android/app/build.gradle
+++ b/ring-android/app/build.gradle
@@ -58,6 +58,9 @@
             universalApk true
         }
     }
+    viewBinding {
+        enabled true
+    }
     dataBinding {
         enabled true
     }
@@ -71,7 +74,6 @@
     def android_support_core_version = '1.1.0'
     def android_support_version = '1.0.0'
     def material_version = '1.1.0'
-    def butterknife_version = '10.2.1'
     def dagger_version = '2.27'
 
     implementation fileTree(include: '*.jar', dir: 'libs')
@@ -98,10 +100,6 @@
     implementation('com.journeyapps:zxing-android-embedded:4.0.2@aar') { transitive = false }
     implementation 'com.google.zxing:core:3.3.3'
 
-    // Butterknife
-    implementation "com.jakewharton:butterknife:$butterknife_version"
-    annotationProcessor "com.jakewharton:butterknife-compiler:${butterknife_version}"
-
     // RxBindings
     implementation 'com.jakewharton.rxbinding3:rxbinding:3.1.0'
 
diff --git a/ring-android/app/src/main/java/cx/ring/about/AboutFragment.java b/ring-android/app/src/main/java/cx/ring/about/AboutFragment.java
index 5a847bf..1a6d8b0 100644
--- a/ring-android/app/src/main/java/cx/ring/about/AboutFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/about/AboutFragment.java
@@ -36,43 +36,46 @@
 import android.widget.TextView;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.appcompat.widget.Toolbar;
 import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentManager;
 
-import butterknife.BindView;
-import butterknife.OnClick;
 import cx.ring.BuildConfig;
 import cx.ring.R;
 import cx.ring.client.HomeActivity;
-import cx.ring.dependencyinjection.JamiInjectionComponent;
+import cx.ring.databinding.FragAboutBinding;
 import cx.ring.mvp.BaseSupportFragment;
 import cx.ring.mvp.RootPresenter;
 import cx.ring.utils.DeviceUtils;
 
 public class AboutFragment extends BaseSupportFragment<RootPresenter> {
 
-    @BindView(R.id.release)
-    TextView mTextViewRelease;
+    private FragAboutBinding binding;
 
+    @Nullable
     @Override
-    public int getLayout() {
-        return R.layout.frag_about;
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+        binding = FragAboutBinding.inflate(inflater, container, false);
+        return binding.getRoot();
     }
 
     @Override
-    public void injectFragment(JamiInjectionComponent component) {
-    }
-
-    @Override
-    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
-        return super.onCreateView(inflater, parent, savedInstanceState);
+    public void onDestroyView() {
+        super.onDestroyView();
+        binding = null;
     }
 
     @Override
     public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
         setHasOptionsMenu(true);
-        mTextViewRelease.setText(getString(R.string.app_release, BuildConfig.VERSION_NAME));
+        binding.release.setText(getString(R.string.app_release, BuildConfig.VERSION_NAME));
+        binding.logo.setOnClickListener(v ->  startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.app_website)))));
+        binding.sflLogo.setOnClickListener(v -> startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.savoirfairelinux_website)))));
+        binding.contributeContainer.setOnClickListener(this::webSiteToView);
+        binding.licenseContainer.setOnClickListener(this::webSiteToView);
+        binding.emailReportContainer.setOnClickListener(v -> sendFeedbackEmail());
+        binding.credits.setOnClickListener(v -> creditsClicked());
     }
 
     @Override
@@ -104,7 +107,7 @@
     }
 
     @Override
-    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+    public void onCreateOptionsMenu(Menu menu, @NonNull MenuInflater inflater) {
         menu.clear();
     }
 
@@ -113,21 +116,8 @@
         menu.clear();
     }
 
-    @OnClick({R.id.logo})
-    public void onLogoClicked() {
-        startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.app_website))));
-    }
-
-    @OnClick({R.id.sfl_logo})
-    public void onSflClicked() {
-        startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.savoirfairelinux_website))));
-    }
-
-    @OnClick({R.id.contribute_container, R.id.license_container})
-    public void webSiteToView(View view) {
-
-        Uri uriToView = null;
-
+    private void webSiteToView(View view) {
+        Uri uriToView;
         switch (view.getId()) {
             case R.id.contribute_container:
                 uriToView = Uri.parse(getString(R.string.ring_contribute_website));
@@ -135,10 +125,8 @@
             case R.id.license_container:
                 uriToView = Uri.parse(getString(R.string.gnu_license_website));
                 break;
-        }
-
-        if (uriToView == null) {
-            return;
+            default:
+                return;
         }
 
         Intent webIntent = new Intent(Intent.ACTION_VIEW);
@@ -146,15 +134,13 @@
         launchSystemIntent(webIntent, getString(R.string.website_chooser_title), getString(R.string.no_browser_app_installed));
     }
 
-    @OnClick(R.id.email_report_container)
-    public void sendFeedbackEmail() {
+    private void sendFeedbackEmail() {
         Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:" + "ring@gnu.org"));
         emailIntent.putExtra(Intent.EXTRA_SUBJECT, "[" + getText(R.string.app_name) + " Android - " + BuildConfig.VERSION_NAME + "]");
         launchSystemIntent(emailIntent, getString(R.string.email_chooser_title), getString(R.string.no_email_app_installed));
     }
 
-    @OnClick(R.id.credits)
-    public void creditsClicked() {
+    private void creditsClicked() {
         BottomSheetDialogFragment dialog = new AboutBottomSheetDialogFragment();
         dialog.show(getActivity().getSupportFragmentManager(), dialog.getTag());
     }
diff --git a/ring-android/app/src/main/java/cx/ring/account/AccountEditionFragment.java b/ring-android/app/src/main/java/cx/ring/account/AccountEditionFragment.java
index 0c6c4b7..fae5be7 100644
--- a/ring-android/app/src/main/java/cx/ring/account/AccountEditionFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/account/AccountEditionFragment.java
@@ -28,10 +28,10 @@
 import android.graphics.Typeface;
 import android.os.Bundle;
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.annotation.StringRes;
 
 import com.google.android.material.dialog.MaterialAlertDialogBuilder;
-import com.google.android.material.tabs.TabLayout;
 
 import androidx.appcompat.widget.Toolbar;
 import androidx.fragment.app.Fragment;
@@ -39,13 +39,14 @@
 import androidx.fragment.app.FragmentStatePagerAdapter;
 import androidx.fragment.app.FragmentTransaction;
 import androidx.recyclerview.widget.RecyclerView;
-import androidx.viewpager.widget.ViewPager;
 import androidx.appcompat.app.AlertDialog;
 
+import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
@@ -55,10 +56,11 @@
 
 import java.util.List;
 
-import butterknife.BindView;
 import cx.ring.R;
+import cx.ring.application.JamiApplication;
 import cx.ring.client.HomeActivity;
 import cx.ring.contactrequests.BlackListFragment;
+import cx.ring.databinding.FragAccountSettingsBinding;
 import cx.ring.dependencyinjection.JamiInjectionComponent;
 import cx.ring.fragments.AdvancedAccountFragment;
 import cx.ring.fragments.GeneralAccountFragment;
@@ -80,22 +82,30 @@
 
     private static final int SCROLL_DIRECTION_UP = -1;
 
+    private FragAccountSettingsBinding binding;
+
     private boolean mIsVisible;
 
-    @BindView(R.id.pager)
-    protected ViewPager mViewPager;
-
-    @BindView(R.id.sliding_tabs)
-    protected TabLayout mSlidingTabLayout;
-
-    @BindView(R.id.fragment_container)
-    protected FrameLayout frameLayout;
-
     private MenuItem mItemAdvanced;
     private MenuItem mItemBlacklist;
 
     private String mAccountId;
 
+    @Nullable
+    @Override
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+        binding = FragAccountSettingsBinding.inflate(inflater, container, false);
+        // dependency injection
+        ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
+        return binding.getRoot();
+    }
+
+    @Override
+    public void onDestroyView() {
+        super.onDestroyView();
+        binding = null;
+    }
+
     @Override
     public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
         setHasOptionsMenu(true);
@@ -122,7 +132,7 @@
             title.setLayoutParams(params);
         }
 
-        frameLayout.getViewTreeObserver().addOnScrollChangedListener(this);
+        binding.fragmentContainer.getViewTreeObserver().addOnScrollChangedListener(this);
     }
 
     @Override
@@ -152,9 +162,9 @@
 
     @Override
     public void initViewPager(String accountId, boolean isJami) {
-        mViewPager.setOffscreenPageLimit(4);
-        mSlidingTabLayout.setupWithViewPager(mViewPager);
-        mViewPager.setAdapter(new PreferencesPagerAdapter(getFragmentManager(), getActivity(), accountId, isJami));
+        binding.pager.setOffscreenPageLimit(4);
+        binding.slidingTabs.setupWithViewPager(binding.pager);
+        binding.pager.setAdapter(new PreferencesPagerAdapter(getFragmentManager(), getActivity(), accountId, isJami));
     }
 
     @Override
@@ -182,9 +192,9 @@
                 .addToBackStack(BlackListFragment.TAG)
                 .replace(R.id.fragment_container, blackListFragment, BlackListFragment.TAG)
                 .commit();
-        mSlidingTabLayout.setVisibility(View.GONE);
-        mViewPager.setVisibility(View.GONE);
-        frameLayout.setVisibility(View.VISIBLE);
+        binding.slidingTabs.setVisibility(View.GONE);
+        binding.pager.setVisibility(View.GONE);
+        binding.fragmentContainer.setVisibility(View.VISIBLE);
     }
 
     @Override
@@ -219,7 +229,7 @@
         mIsVisible = false;
         if (getActivity() instanceof HomeActivity)
             ((HomeActivity) getActivity()).setToolbarOutlineState(true);
-        if (frameLayout.getVisibility() != View.VISIBLE) {
+        if (binding.fragmentContainer.getVisibility() != View.VISIBLE) {
             toggleView(mAccountId);
             return  true;
         }
@@ -238,9 +248,9 @@
         mAccountId = accountId;
         boolean isRing = presenter.getAccount(mAccountId).isRing();
 
-        mSlidingTabLayout.setVisibility(isRing? View.GONE : View.VISIBLE);
-        mViewPager.setVisibility(isRing? View.GONE : View.VISIBLE);
-        frameLayout.setVisibility(isRing? View.VISIBLE : View.GONE);
+        binding.slidingTabs.setVisibility(isRing? View.GONE : View.VISIBLE);
+        binding.pager.setVisibility(isRing? View.GONE : View.VISIBLE);
+        binding.fragmentContainer.setVisibility(isRing? View.VISIBLE : View.GONE);
         presenter.prepareOptionsMenu();
         setBackListenerEnabled(isRing);
 
@@ -248,7 +258,7 @@
         JamiAccountSummaryFragment fragment = (JamiAccountSummaryFragment) fragmentManager.findFragmentByTag(JamiAccountSummaryFragment.TAG);
         if (fragment != null) {
             fragment.setFragmentVisibility(isRing);
-            fragment.onScrollChanged();
+            fragment.setAccount(accountId);
         }
     }
 
@@ -264,9 +274,9 @@
                 deleteDialog.show();
                 break;
             case R.id.menuitem_advanced:
-                mSlidingTabLayout.setVisibility(View.VISIBLE);
-                mViewPager.setVisibility(View.VISIBLE);
-                frameLayout.setVisibility(View.GONE);
+                binding.slidingTabs.setVisibility(View.VISIBLE);
+                binding.pager.setVisibility(View.VISIBLE);
+                binding.fragmentContainer.setVisibility(View.GONE);
                 JamiAccountSummaryFragment fragment = (JamiAccountSummaryFragment) requireFragmentManager().findFragmentByTag(JamiAccountSummaryFragment.TAG);
                 if (fragment != null)
                     fragment.setFragmentVisibility(false);
@@ -312,16 +322,6 @@
             activity.onBackPressed();
     }
 
-    @Override
-    public int getLayout() {
-        return R.layout.frag_account_settings;
-    }
-
-    @Override
-    public void injectFragment(JamiInjectionComponent component) {
-        component.inject(this);
-    }
-
     private void setBackListenerEnabled(boolean enable) {
         if (!(getActivity() instanceof HomeActivity))
             return;
@@ -431,23 +431,23 @@
     }
 
     private void setupElevation() {
-        if (mViewPager == null || !mIsVisible) {
+        if (binding == null || !mIsVisible) {
             return;
         }
         Activity activity = getActivity();
         if (!(activity instanceof HomeActivity))
             return;
-        LinearLayout ll = (LinearLayout) mViewPager.getChildAt(mViewPager.getCurrentItem());
+        LinearLayout ll = (LinearLayout) binding.pager.getChildAt(binding.pager.getCurrentItem());
         if (ll == null) return;
         RecyclerView rv = (RecyclerView)((FrameLayout) ll.getChildAt(0)).getChildAt(0);
         if (rv == null) return;
         HomeActivity homeActivity = (HomeActivity) activity;
         if (rv.canScrollVertically(SCROLL_DIRECTION_UP)) {
-            mSlidingTabLayout.setElevation(mSlidingTabLayout.getResources().getDimension(R.dimen.toolbar_elevation));
+            binding.slidingTabs.setElevation(binding.slidingTabs.getResources().getDimension(R.dimen.toolbar_elevation));
             homeActivity.setToolbarElevation(true);
             homeActivity.setToolbarOutlineState(false);
         } else {
-            mSlidingTabLayout.setElevation(0);
+            binding.slidingTabs.setElevation(0);
             homeActivity.setToolbarElevation(false);
             homeActivity.setToolbarOutlineState(true);
         }
diff --git a/ring-android/app/src/main/java/cx/ring/account/AccountWizardActivity.java b/ring-android/app/src/main/java/cx/ring/account/AccountWizardActivity.java
index 81260de..fee2779 100644
--- a/ring-android/app/src/main/java/cx/ring/account/AccountWizardActivity.java
+++ b/ring-android/app/src/main/java/cx/ring/account/AccountWizardActivity.java
@@ -40,7 +40,6 @@
 
 import com.google.android.material.dialog.MaterialAlertDialogBuilder;
 
-import butterknife.ButterKnife;
 import cx.ring.R;
 import cx.ring.application.JamiApplication;
 import cx.ring.client.HomeActivity;
@@ -66,13 +65,11 @@
     @Override
     public void onCreate(Bundle savedInstanceState) {
         // dependency injection
-        JamiApplication.getInstance().getRingInjectionComponent().inject(this);
+        JamiApplication.getInstance().getInjectionComponent().inject(this);
         super.onCreate(savedInstanceState);
 
         JamiApplication.getInstance().startDaemon();
-
         setContentView(R.layout.activity_wizard);
-        ButterKnife.bind(this);
 
         String accountToMigrate = null;
         Intent intent = getIntent();
diff --git a/ring-android/app/src/main/java/cx/ring/account/BackupAccountDialog.java b/ring-android/app/src/main/java/cx/ring/account/BackupAccountDialog.java
index 621109c..9d80d6e 100644
--- a/ring-android/app/src/main/java/cx/ring/account/BackupAccountDialog.java
+++ b/ring-android/app/src/main/java/cx/ring/account/BackupAccountDialog.java
@@ -21,40 +21,25 @@
 
 import android.app.Dialog;
 import android.os.Bundle;
-import android.view.View;
 import android.view.WindowManager;
 import android.view.inputmethod.EditorInfo;
 import android.widget.Button;
-import android.widget.EditText;
-import android.widget.TextView;
 
 import com.google.android.material.dialog.MaterialAlertDialogBuilder;
-import com.google.android.material.textfield.TextInputLayout;
 
 import androidx.annotation.NonNull;
 import androidx.appcompat.app.AlertDialog;
 import androidx.fragment.app.DialogFragment;
-import butterknife.BindString;
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import butterknife.OnEditorAction;
 import cx.ring.R;
+import cx.ring.databinding.DialogConfirmRevocationBinding;
 
 public class BackupAccountDialog extends DialogFragment {
     static final String TAG = BackupAccountDialog.class.getSimpleName();
 
-    @BindView(R.id.password_txt_box)
-    protected TextInputLayout mPasswordTxtBox;
-
-    @BindView(R.id.password_txt)
-    protected EditText mPasswordTxt;
-
-    @BindString(R.string.enter_password)
-    protected String mPromptPassword;
-
     private String mAccountId;
 
     private UnlockAccountListener mListener = null;
+    private DialogConfirmRevocationBinding binding;
 
     public void setListener(UnlockAccountListener listener) {
         mListener = listener;
@@ -63,18 +48,28 @@
     @NonNull
     @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
-        View view = requireActivity().getLayoutInflater().inflate(R.layout.dialog_confirm_revocation, null);
-        ButterKnife.bind(this, view);
+        binding = DialogConfirmRevocationBinding.inflate(getActivity().getLayoutInflater());
 
         Bundle args = getArguments();
         if (args != null) {
             mAccountId = args.getString(AccountEditionFragment.ACCOUNT_ID_KEY);
         }
 
+        binding.passwordTxt.setOnEditorActionListener((v, actionId, event) -> {
+            if (actionId == EditorInfo.IME_ACTION_DONE) {
+                boolean validationResult = validate();
+                if (validationResult) {
+                    getDialog().dismiss();
+                }
+                return validationResult;
+            }
+            return false;
+        });
+
         final AlertDialog result = new MaterialAlertDialogBuilder(requireContext())
                 .setTitle(R.string.account_enter_password)
                 .setMessage(R.string.account_new_device_password)
-                .setView(view)
+                .setView(binding.getRoot())
                 .setPositiveButton(android.R.string.ok, null) //Set to null. We override the onclick
                 .setNegativeButton(android.R.string.cancel,
                         (dialog, whichButton) -> dismiss()
@@ -94,27 +89,12 @@
 
     private boolean validate() {
         if (mListener != null) {
-            mListener.onUnlockAccount(mAccountId, mPasswordTxt.getText().toString());
+            mListener.onUnlockAccount(mAccountId, binding.passwordTxt.getText().toString());
             return true;
         }
         return false;
     }
 
-    @OnEditorAction({R.id.password_txt})
-    public boolean onEditorAction(TextView v, int actionId) {
-        if (v == mPasswordTxt) {
-            if (actionId == EditorInfo.IME_ACTION_DONE) {
-                boolean validationResult = validate();
-                if (validationResult) {
-                    getDialog().dismiss();
-                }
-
-                return validationResult;
-            }
-        }
-        return false;
-    }
-
     public interface UnlockAccountListener {
         void onUnlockAccount(String accountId, String password);
     }
diff --git a/ring-android/app/src/main/java/cx/ring/account/ChangePasswordDialog.java b/ring-android/app/src/main/java/cx/ring/account/ChangePasswordDialog.java
index 8d14874..89a43f6 100644
--- a/ring-android/app/src/main/java/cx/ring/account/ChangePasswordDialog.java
+++ b/ring-android/app/src/main/java/cx/ring/account/ChangePasswordDialog.java
@@ -20,50 +20,25 @@
 
 import android.app.Dialog;
 import android.os.Bundle;
+import android.view.LayoutInflater;
 import android.view.View;
 import android.view.WindowManager;
 import android.view.inputmethod.EditorInfo;
 import android.widget.Button;
-import android.widget.EditText;
-import android.widget.TextView;
 
 import com.google.android.material.dialog.MaterialAlertDialogBuilder;
-import com.google.android.material.textfield.TextInputLayout;
 
 import androidx.annotation.NonNull;
 import androidx.appcompat.app.AlertDialog;
 import androidx.fragment.app.DialogFragment;
-import butterknife.BindString;
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import butterknife.OnEditorAction;
 import cx.ring.R;
+import cx.ring.databinding.DialogSetPasswordBinding;
 
 public class ChangePasswordDialog extends DialogFragment {
     static final String TAG = ChangePasswordDialog.class.getSimpleName();
 
-    @BindView(R.id.old_password_txt_box)
-    protected TextInputLayout mPasswordTxtBox;
-
-    @BindView(R.id.old_password_txt)
-    protected EditText mPasswordTxt;
-
-    @BindView(R.id.new_password_txt_box)
-    protected TextInputLayout mNewPasswordTxtBox;
-
-    @BindView(R.id.new_password_txt)
-    protected EditText mNewPasswordTxt;
-
-    @BindView(R.id.new_password_repeat_txt_box)
-    protected TextInputLayout mNewPasswordRepeatsTxtBox;
-
-    @BindView(R.id.new_password_repeat_txt)
-    protected EditText mNewPasswordRepeatsTxt;
-
-    @BindString(R.string.enter_password)
-    protected String mPromptPassword;
-
     private PasswordChangedListener mListener = null;
+    private DialogSetPasswordBinding binding;
 
     public void setListener(PasswordChangedListener listener) {
         mListener = listener;
@@ -72,8 +47,7 @@
     @NonNull
     @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
-        View view = requireActivity().getLayoutInflater().inflate(R.layout.dialog_set_password, null);
-        ButterKnife.bind(this, view);
+        binding = DialogSetPasswordBinding.inflate(getActivity().getLayoutInflater());
 
         String accountId = "";
         boolean hasPassword = true;
@@ -83,10 +57,19 @@
             hasPassword = args.getBoolean(AccountEditionFragment.ACCOUNT_HAS_PASSWORD_KEY, true);
         }
         int passwordMessage = hasPassword ? R.string.account_password_change : R.string.account_password_set;
-        mPasswordTxtBox.setVisibility(hasPassword ? View.VISIBLE : View.GONE);
+        binding.oldPasswordTxtBox.setVisibility(hasPassword ? View.VISIBLE : View.GONE);
+        binding.newPasswordRepeatTxt.setOnEditorActionListener((v, actionId, event) -> {
+            if (actionId == EditorInfo.IME_ACTION_DONE) {
+                if (validate()) {
+                    getDialog().dismiss();
+                    return true;
+                }
+            }
+            return false;
+        });
 
         final AlertDialog result = new MaterialAlertDialogBuilder(requireContext())
-                .setView(view)
+                .setView(binding.getRoot())
                 .setMessage(R.string.help_password_choose)
                 .setTitle(passwordMessage)
                 .setPositiveButton(passwordMessage, null) //Set to null. We override the onclick
@@ -104,43 +87,32 @@
         return result;
     }
 
-    public boolean checkInput() {
-        if (!mNewPasswordTxt.getText().toString().contentEquals(mNewPasswordRepeatsTxt.getText())) {
-            mNewPasswordTxtBox.setErrorEnabled(true);
-            mNewPasswordTxtBox.setError(getText(R.string.error_passwords_not_equals));
-            mNewPasswordRepeatsTxtBox.setErrorEnabled(true);
-            mNewPasswordRepeatsTxtBox.setError(getText(R.string.error_passwords_not_equals));
+    private boolean checkInput() {
+        if (!binding.newPasswordTxt.getText().toString().contentEquals(binding.newPasswordRepeatTxt.getText())) {
+            binding.newPasswordTxtBox.setErrorEnabled(true);
+            binding.newPasswordTxtBox.setError(getText(R.string.error_passwords_not_equals));
+            binding.newPasswordRepeatTxtBox.setErrorEnabled(true);
+            binding.newPasswordRepeatTxtBox.setError(getText(R.string.error_passwords_not_equals));
             return false;
         } else {
-            mNewPasswordTxtBox.setErrorEnabled(false);
-            mNewPasswordTxtBox.setError(null);
-            mNewPasswordRepeatsTxtBox.setErrorEnabled(false);
-            mNewPasswordRepeatsTxtBox.setError(null);
+            binding.newPasswordTxtBox.setErrorEnabled(false);
+            binding.newPasswordTxtBox.setError(null);
+            binding.newPasswordRepeatTxtBox.setErrorEnabled(false);
+            binding.newPasswordRepeatTxtBox.setError(null);
         }
         return true;
     }
 
     private boolean validate() {
         if (checkInput() && mListener != null) {
-            final String oldPassword = mPasswordTxt.getText().toString();
-            final String newPassword = mNewPasswordTxt.getText().toString();
+            final String oldPassword = binding.oldPasswordTxt.getText().toString();
+            final String newPassword = binding.newPasswordTxt.getText().toString();
             mListener.onPasswordChanged(oldPassword, newPassword);
             return true;
         }
         return false;
     }
 
-    @OnEditorAction({R.id.new_password_repeat_txt})
-    public boolean onEditorAction(TextView v, int actionId) {
-        if (actionId == EditorInfo.IME_ACTION_DONE) {
-            if (validate()) {
-                getDialog().dismiss();
-                return true;
-            }
-        }
-        return false;
-    }
-
     public interface PasswordChangedListener {
         void onPasswordChanged(String oldPassword, String newPassword);
     }
diff --git a/ring-android/app/src/main/java/cx/ring/account/ConfirmRevocationDialog.java b/ring-android/app/src/main/java/cx/ring/account/ConfirmRevocationDialog.java
index 70e73e2..79c7a83 100644
--- a/ring-android/app/src/main/java/cx/ring/account/ConfirmRevocationDialog.java
+++ b/ring-android/app/src/main/java/cx/ring/account/ConfirmRevocationDialog.java
@@ -23,39 +23,27 @@
 import android.os.Bundle;
 
 import com.google.android.material.dialog.MaterialAlertDialogBuilder;
-import com.google.android.material.textfield.TextInputLayout;
 
 import androidx.annotation.NonNull;
 import androidx.appcompat.app.AlertDialog;
+
 import android.view.View;
 import android.view.WindowManager;
 import android.view.inputmethod.EditorInfo;
 import android.widget.Button;
-import android.widget.EditText;
-import android.widget.TextView;
 
 import androidx.fragment.app.DialogFragment;
-import butterknife.BindString;
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import butterknife.OnEditorAction;
 import cx.ring.R;
+import cx.ring.databinding.DialogConfirmRevocationBinding;
 
 public class ConfirmRevocationDialog extends DialogFragment {
     public static final String DEVICEID_KEY = "deviceid_key";
     public static final String HAS_PASSWORD_KEY = "has_password_key";
     static final String TAG = ConfirmRevocationDialog.class.getSimpleName();
-    @BindView(R.id.password_txt_box)
-    protected TextInputLayout mPasswordTxtBox;
-    @BindView(R.id.password_txt)
-    protected EditText mPasswordTxt;
-    @BindString(R.string.enter_password)
-    protected String mPromptPassword;
-    @BindString(R.string.revoke_device_title)
-    protected String mRegisterTitle;
     private String mDeviceId;
     private Boolean mHasPassword = true;
     private ConfirmRevocationListener mListener = null;
+    private DialogConfirmRevocationBinding binding;
 
     public void setListener(ConfirmRevocationListener listener) {
         mListener = listener;
@@ -64,16 +52,15 @@
     @NonNull
     @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
-        View view = requireActivity().getLayoutInflater().inflate(R.layout.dialog_confirm_revocation, null);
-        ButterKnife.bind(this, view);
+        binding = DialogConfirmRevocationBinding.inflate(getActivity().getLayoutInflater());
 
         mDeviceId = requireArguments().getString(DEVICEID_KEY);
         mHasPassword = requireArguments().getBoolean(HAS_PASSWORD_KEY);
 
         final AlertDialog result = new MaterialAlertDialogBuilder(requireContext())
-                .setView(view)
+                .setView(binding.getRoot())
                 .setMessage(getString(R.string.revoke_device_message, mDeviceId))
-                .setTitle(mRegisterTitle)
+                .setTitle(getText(R.string.revoke_device_title))
                 .setPositiveButton(R.string.revoke_device_title, null) //Set to null. We override the onclick
                 .setNegativeButton(android.R.string.cancel,
                         (dialog, whichButton) -> dismiss()
@@ -89,50 +76,45 @@
         });
 
         if(mHasPassword) {
-            result.getWindow().setSoftInputMode(WindowManager.LayoutParams.
-                    SOFT_INPUT_STATE_VISIBLE);
+            result.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
         } else {
-            mPasswordTxtBox.setVisibility(View.GONE);
+            binding.passwordTxtBox.setVisibility(View.GONE);
         }
+
+        binding.passwordTxt.setOnEditorActionListener((v, actionId, event) -> {
+            if (actionId == EditorInfo.IME_ACTION_DONE) {
+                boolean validationResult = validate();
+                if (validationResult) {
+                    getDialog().dismiss();
+                }
+                return validationResult;
+            }
+            return false;
+        });
         return result;
     }
 
     private boolean checkInput() {
-        if (mHasPassword && mPasswordTxt.getText().toString().isEmpty()) {
-            mPasswordTxtBox.setErrorEnabled(true);
-            mPasswordTxtBox.setError(mPromptPassword);
+        if (mHasPassword && binding.passwordTxt.getText().toString().isEmpty()) {
+            binding.passwordTxtBox.setErrorEnabled(true);
+            binding.passwordTxtBox.setError(getText(R.string.enter_password));
             return false;
         } else {
-            mPasswordTxtBox.setErrorEnabled(false);
-            mPasswordTxtBox.setError(null);
+            binding.passwordTxtBox.setErrorEnabled(false);
+            binding.passwordTxtBox.setError(null);
         }
         return true;
     }
 
     private boolean validate() {
         if (checkInput() && mListener != null) {
-            final String password = mPasswordTxt.getText().toString();
+            final String password = binding.passwordTxt.getText().toString();
             mListener.onConfirmRevocation(mDeviceId, password);
             return true;
         }
         return false;
     }
 
-    @OnEditorAction({R.id.password_txt})
-    public boolean onEditorAction(TextView v, int actionId) {
-        if (v == mPasswordTxt) {
-            if (actionId == EditorInfo.IME_ACTION_DONE) {
-                boolean validationResult = validate();
-                if (validationResult) {
-                    getDialog().dismiss();
-                }
-
-                return validationResult;
-            }
-        }
-        return false;
-    }
-
     public interface ConfirmRevocationListener {
         void onConfirmRevocation(String deviceId, String password);
     }
diff --git a/ring-android/app/src/main/java/cx/ring/account/HomeAccountCreationFragment.java b/ring-android/app/src/main/java/cx/ring/account/HomeAccountCreationFragment.java
index c394ce9..293c17b 100644
--- a/ring-android/app/src/main/java/cx/ring/account/HomeAccountCreationFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/account/HomeAccountCreationFragment.java
@@ -23,18 +23,19 @@
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Bundle;
+import android.view.LayoutInflater;
 import android.view.View;
-import android.widget.Button;
+import android.view.ViewGroup;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.fragment.app.Fragment;
 
 import com.google.android.material.snackbar.Snackbar;
 
-import butterknife.BindView;
-import butterknife.OnClick;
 import cx.ring.R;
-import cx.ring.dependencyinjection.JamiInjectionComponent;
+import cx.ring.application.JamiApplication;
+import cx.ring.databinding.FragAccHomeCreateBinding;
 import cx.ring.mvp.BaseSupportFragment;
 import cx.ring.utils.AndroidFileUtils;
 import io.reactivex.android.schedulers.AndroidSchedulers;
@@ -44,41 +45,30 @@
 
     public static final String TAG = HomeAccountCreationFragment.class.getSimpleName();
 
-    @BindView(R.id.ring_add_account)
-    protected Button mLinkButton;
+    private FragAccHomeCreateBinding binding;
 
-    @BindView(R.id.ring_create_btn)
-    protected Button mCreateButton;
-
+    @Nullable
     @Override
-    public int getLayout() {
-        return R.layout.frag_acc_home_create;
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+        binding = FragAccHomeCreateBinding.inflate(inflater, container, false);
+        ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
+        return binding.getRoot();
     }
 
     @Override
-    public void injectFragment(JamiInjectionComponent component) {
-        component.inject(this);
+    public void onDestroyView() {
+        super.onDestroyView();
+        binding = null;
     }
 
     @Override
     public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
         setRetainInstance(true);
-    }
-
-    @OnClick(R.id.ring_add_account)
-    public void linkAccountClicked() {
-        presenter.clickOnLinkAccount();
-    }
-
-    @OnClick(R.id.ring_create_btn)
-    public void createAccountClicked() {
-        presenter.clickOnCreateAccount();
-    }
-
-    @OnClick(R.id.account_connect_server)
-    public void connectAccountClicked() {
-        presenter.clickOnConnectAccount();
+        binding.ringAddAccount.setOnClickListener(v -> presenter.clickOnLinkAccount());
+        binding.ringCreateBtn.setOnClickListener(v -> presenter.clickOnCreateAccount());
+        binding.accountConnectServer.setOnClickListener(v -> presenter.clickOnConnectAccount());
+        binding.ringImportAccount.setOnClickListener(v -> performFileSearch());
     }
 
     @Override
@@ -104,8 +94,7 @@
         replaceFragmentWithSlide(fragment, R.id.wizard_container);
     }
 
-    @OnClick(R.id.ring_import_account)
-    public void performFileSearch() {
+    private void performFileSearch() {
         Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
         intent.addCategory(Intent.CATEGORY_OPENABLE);
         intent.setType("*/*");
diff --git a/ring-android/app/src/main/java/cx/ring/account/JamiAccountConnectFragment.java b/ring-android/app/src/main/java/cx/ring/account/JamiAccountConnectFragment.java
index 36a6b3b..2d9c37b 100644
--- a/ring-android/app/src/main/java/cx/ring/account/JamiAccountConnectFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/account/JamiAccountConnectFragment.java
@@ -20,37 +20,27 @@
 package cx.ring.account;
 
 import android.app.Activity;
+import android.os.Bundle;
 import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
 import android.view.inputmethod.EditorInfo;
-import android.widget.Button;
-import android.widget.EditText;
 
-import butterknife.BindView;
-import butterknife.OnClick;
-import butterknife.OnEditorAction;
-import butterknife.OnTextChanged;
-import cx.ring.R;
-import cx.ring.dependencyinjection.JamiInjectionComponent;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import cx.ring.application.JamiApplication;
+import cx.ring.databinding.FragAccJamiConnectBinding;
 import cx.ring.mvp.AccountCreationModel;
 import cx.ring.mvp.BaseSupportFragment;
 
 public class JamiAccountConnectFragment extends BaseSupportFragment<JamiAccountConnectPresenter> implements JamiConnectAccountView {
-
     public static final String TAG = JamiAccountConnectFragment.class.getSimpleName();
 
-    @BindView(R.id.prompt_server)
-    protected EditText mServerTxt;
-
-    @BindView(R.id.username_txt)
-    protected EditText mUsernameTxt;
-
-    @BindView(R.id.password_txt)
-    protected EditText mPasswordTxt;
-
-    @BindView(R.id.connect_button)
-    protected Button mConnectAccountBtn;
-
     private AccountCreationModel model;
+    private FragAccJamiConnectBinding binding;
 
     public static JamiAccountConnectFragment newInstance(AccountCreationModelImpl ringAccountViewModel) {
         JamiAccountConnectFragment fragment = new JamiAccountConnectFragment();
@@ -58,14 +48,18 @@
         return fragment;
     }
 
+    @Nullable
     @Override
-    public int getLayout() {
-        return R.layout.frag_acc_jami_connect;
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+        binding = FragAccJamiConnectBinding.inflate(inflater, container, false);
+        ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
+        return binding.getRoot();
     }
 
     @Override
-    public void injectFragment(JamiInjectionComponent component) {
-        component.inject(this);
+    public void onDestroyView() {
+        super.onDestroyView();
+        binding = null;
     }
 
     @Override
@@ -73,37 +67,58 @@
         presenter.init(model);
     }
 
-    @OnClick(R.id.connect_button)
-    public void onConnectClick() {
-        presenter.connectClicked();
-    }
+    @Override
+    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+        binding.connectButton.setOnClickListener(v -> presenter.connectClicked());
+        binding.usernameTxt.addTextChangedListener(new TextWatcher() {
+            @Override
+            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
 
-    @OnTextChanged(value = R.id.username_txt, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
-    void afterUsernameChanged(Editable txt) {
-        presenter.usernameChanged(txt.toString());
-    }
+            @Override
+            public void onTextChanged(CharSequence s, int start, int before, int count) {}
 
-    @OnTextChanged(value = R.id.password_txt, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
-    void afterPasswordChanged(Editable txt) {
-        presenter.passwordChanged(txt.toString());
-    }
+            @Override
+            public void afterTextChanged(Editable s) {
+                presenter.usernameChanged(s.toString());
+            }
+        });
+        binding.passwordTxt.addTextChangedListener(new TextWatcher() {
+            @Override
+            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
 
-    @OnTextChanged(value = R.id.prompt_server, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
-    void afterServerChanged(Editable txt) {
-        presenter.serverChanged(txt.toString());
-    }
+            @Override
+            public void onTextChanged(CharSequence s, int start, int before, int count) {}
 
-    @OnEditorAction(value = R.id.password_txt)
-    public boolean onPasswordConfirmDone(int keyCode) {
-        if (keyCode == EditorInfo.IME_ACTION_DONE) {
-            presenter.connectClicked();
-        }
-        return false;
+            @Override
+            public void afterTextChanged(Editable s) {
+                presenter.passwordChanged(s.toString());
+            }
+        });
+        binding.promptServer.addTextChangedListener(new TextWatcher() {
+            @Override
+            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+            @Override
+            public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+            @Override
+            public void afterTextChanged(Editable s) {
+                presenter.serverChanged(s.toString());
+            }
+        });
+
+        binding.passwordTxt.setOnEditorActionListener((v, actionId, event) -> {
+            if (actionId == EditorInfo.IME_ACTION_DONE) {
+                presenter.connectClicked();
+            }
+            return false;
+        });
     }
 
     @Override
     public void enableConnectButton(boolean enable) {
-        mConnectAccountBtn.setEnabled(enable);
+        binding.connectButton.setEnabled(enable);
     }
 
     @Override
diff --git a/ring-android/app/src/main/java/cx/ring/account/JamiAccountCreationFragment.java b/ring-android/app/src/main/java/cx/ring/account/JamiAccountCreationFragment.java
index b9986b3..eba6b18 100644
--- a/ring-android/app/src/main/java/cx/ring/account/JamiAccountCreationFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/account/JamiAccountCreationFragment.java
@@ -24,28 +24,19 @@
 import android.os.Bundle;
 import android.text.Editable;
 import android.text.InputFilter;
+import android.text.TextWatcher;
+import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodManager;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.ImageView;
-import android.widget.ProgressBar;
-import android.widget.Switch;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 
-import com.google.android.material.textfield.TextInputLayout;
-
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import butterknife.OnCheckedChanged;
-import butterknife.OnClick;
-import butterknife.OnEditorAction;
-import butterknife.OnTextChanged;
 import cx.ring.R;
-import cx.ring.dependencyinjection.JamiInjectionComponent;
+import cx.ring.application.JamiApplication;
+import cx.ring.databinding.FragAccRingCreateBinding;
 import cx.ring.mvp.AccountCreationModel;
 import cx.ring.mvp.BaseSupportFragment;
 import cx.ring.utils.RegisteredNameFilter;
@@ -53,43 +44,8 @@
 public class JamiAccountCreationFragment extends BaseSupportFragment<JamiAccountCreationPresenter>
         implements JamiAccountCreationView {
 
-    @BindView(R.id.switch_ring_username)
-    protected Switch mUsernameSwitch;
-
-    @BindView(R.id.ring_username_txt_box)
-    protected TextInputLayout mUsernameTxtBox;
-
-    @BindView(R.id.ring_username)
-    protected EditText mUsernameTxt;
-
-    @BindView(R.id.ring_password_switch)
-    protected Switch mPasswordSwitch;
-
-    @BindView(R.id.ring_password_box)
-    protected ViewGroup mPasswordBox;
-
-    @BindView(R.id.password_txt_box)
-    protected TextInputLayout mPasswordTxtBox;
-
-    @BindView(R.id.ring_password_repeat_txt_box)
-    protected TextInputLayout mPasswordRepeatTxtBox;
-
-    @BindView(R.id.ring_username_box)
-    protected ViewGroup mUsernameBox;
-
-    @BindView(R.id.switch_ring_push)
-    protected Switch mPushSwitch;
-
-    @BindView(R.id.create_account)
-    protected Button mCreateAccountButton;
-
-    @BindView(R.id.ring_username_availability_image_view)
-    protected ImageView mUsernameAvailabilityImageView;
-
-    @BindView(R.id.ring_username_availability_spinner)
-    protected ProgressBar mUsernameAvailabilitySpinner;
-
     private AccountCreationModel model;
+    private FragAccRingCreateBinding binding;
 
     public static JamiAccountCreationFragment newInstance(AccountCreationModelImpl ringAccountViewModel) {
         JamiAccountCreationFragment fragment = new JamiAccountCreationFragment();
@@ -97,119 +53,126 @@
         return fragment;
     }
 
+    @Nullable
     @Override
-    public int getLayout() {
-        return R.layout.frag_acc_ring_create;
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+        binding = FragAccRingCreateBinding.inflate(inflater, container, false);
+        ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
+        return binding.getRoot();
     }
 
     @Override
-    public void injectFragment(JamiInjectionComponent component) {
-        component.inject(this);
+    public void onDestroyView() {
+        super.onDestroyView();
+        binding = null;
     }
 
     @Override
     public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
         setRetainInstance(true);
-        ButterKnife.bind(this, view);
-        mUsernameTxt.setFilters(new InputFilter[]{new RegisteredNameFilter()});
+        binding.ringUsername.setFilters(new InputFilter[]{new RegisteredNameFilter()});
+        binding.ringPasswordSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> binding.ringPasswordBox.setVisibility(isChecked ? View.VISIBLE : View.GONE));
+        binding.switchRingPush.setOnCheckedChangeListener((buttonView, isChecked) -> presenter.setPush(isChecked));
+        binding.switchRingUsername.setOnCheckedChangeListener((buttonView, isChecked) -> presenter.registerUsernameChanged(isChecked));
+        binding.createAccount.setOnClickListener(v -> presenter.createAccount());
+        binding.ringPassword.addTextChangedListener(new TextWatcher() {
+            @Override
+            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+            @Override
+            public void onTextChanged(CharSequence s, int start, int before, int count) {
+                presenter.passwordChanged(s.toString());
+            }
+
+            @Override
+            public void afterTextChanged(Editable s) {}
+        });
+        binding.ringPasswordRepeat.addTextChangedListener(new TextWatcher() {
+            @Override
+            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+            @Override
+            public void onTextChanged(CharSequence s, int start, int before, int count) {
+                presenter.passwordConfirmChanged(s.toString());
+            }
+
+            @Override
+            public void afterTextChanged(Editable s) {}
+        });
+        binding.ringPasswordRepeat.setOnEditorActionListener((v, actionId, event) -> {
+            if (actionId == EditorInfo.IME_ACTION_DONE) {
+                presenter.createAccount();
+            }
+            return false;
+        });
+        binding.ringUsername.addTextChangedListener(new TextWatcher() {
+            @Override
+            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+            @Override
+            public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+            @Override
+            public void afterTextChanged(Editable s) {
+                presenter.userNameChanged(s.toString());
+            }
+        });
+
         presenter.init(model);
-        presenter.setPush(mPushSwitch.isChecked());
+        presenter.setPush(binding.switchRingPush.isChecked());
     }
 
     @Override
     public void onResume() {
         super.onResume();
-        if (mUsernameBox.getVisibility() == View.VISIBLE) {
-            mUsernameTxt.requestFocus();
+        if (binding.ringUsernameBox.getVisibility() == View.VISIBLE) {
+            binding.ringUsername.requestFocus();
             InputMethodManager imm = (InputMethodManager) requireActivity().
                     getSystemService(Context.INPUT_METHOD_SERVICE);
-            imm.showSoftInput(mUsernameTxt, InputMethodManager.SHOW_IMPLICIT);
+            imm.showSoftInput(binding.ringUsername, InputMethodManager.SHOW_IMPLICIT);
         }
     }
 
-    @OnCheckedChanged(R.id.ring_password_switch)
-    public void onPasswordCheckedChanged(boolean isChecked) {
-        mPasswordBox.setVisibility(isChecked ? View.VISIBLE : View.GONE);
-    }
-
-    @OnCheckedChanged(R.id.switch_ring_push)
-    public void onPushCheckedChanged(boolean isChecked) {
-        presenter.setPush(isChecked);
-    }
-
-    @OnCheckedChanged(R.id.switch_ring_username)
-    public void onCheckedChanged(boolean isChecked) {
-        presenter.registerUsernameChanged(isChecked);
-    }
-
-    @OnClick(R.id.create_account)
-    public void onCreateAccountButtonClick() {
-        presenter.createAccount();
-    }
-
-    @OnTextChanged(value = R.id.ring_password, callback = OnTextChanged.Callback.TEXT_CHANGED)
-    public void afterPasswordChanged(Editable txt) {
-        presenter.passwordChanged(txt.toString());
-    }
-
-    @OnTextChanged(value = R.id.ring_password_repeat, callback = OnTextChanged.Callback.TEXT_CHANGED)
-    public void afterPasswordConfirmChanged(Editable txt) {
-        presenter.passwordConfirmChanged(txt.toString());
-    }
-
-    @OnEditorAction(value = R.id.ring_password_repeat)
-    public boolean onPasswordConfirmDone(int keyCode) {
-        if (keyCode == EditorInfo.IME_ACTION_DONE) {
-            presenter.createAccount();
-        }
-        return false;
-    }
-
-    @OnTextChanged(value = R.id.ring_username, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
-    public void afterUsernameChanged(Editable txt) {
-        presenter.userNameChanged(txt.toString());
-    }
-
     @Override
     public void updateUsernameAvailability(UsernameAvailabilityStatus status) {
-        mUsernameAvailabilitySpinner.setVisibility(View.GONE);
+        binding.ringUsernameAvailabilitySpinner.setVisibility(View.GONE);
         //mUsernameAvailabilityImageView.setVisibility(View.VISIBLE);
         switch (status){
             case ERROR:
-                mUsernameTxtBox.setErrorEnabled(true);
-                mUsernameTxtBox.setError(getString(R.string.unknown_error));
+                binding.ringUsernameTxtBox.setErrorEnabled(true);
+                binding.ringUsernameTxtBox.setError(getString(R.string.unknown_error));
                 //mUsernameAvailabilityImageView.setImageDrawable(getResources().getDrawable(R.drawable.ic_error_red));
-                mUsernameAvailabilityImageView.setVisibility(View.INVISIBLE);
+                binding.ringUsernameAvailabilityImageView.setVisibility(View.INVISIBLE);
                 break;
             case ERROR_USERNAME_INVALID:
-                mUsernameTxtBox.setErrorEnabled(true);
-                mUsernameTxtBox.setError(getString(R.string.invalid_username));
+                binding.ringUsernameTxtBox.setErrorEnabled(true);
+                binding.ringUsernameTxtBox.setError(getString(R.string.invalid_username));
                 //mUsernameAvailabilityImageView.setImageDrawable(getResources().getDrawable(R.drawable.ic_error_red));
-                mUsernameAvailabilityImageView.setVisibility(View.INVISIBLE);
+                binding.ringUsernameAvailabilityImageView.setVisibility(View.INVISIBLE);
                 break;
             case ERROR_USERNAME_TAKEN:
-                mUsernameTxtBox.setErrorEnabled(true);
-                mUsernameTxtBox.setError(getString(R.string.username_already_taken));
+                binding.ringUsernameTxtBox.setErrorEnabled(true);
+                binding.ringUsernameTxtBox.setError(getString(R.string.username_already_taken));
                 //mUsernameAvailabilityImageView.setImageDrawable(getResources().getDrawable(R.drawable.ic_error_red));
-                mUsernameAvailabilityImageView.setVisibility(View.INVISIBLE);
+                binding.ringUsernameAvailabilityImageView.setVisibility(View.INVISIBLE);
                 break;
             case LOADING:
-                mUsernameTxtBox.setErrorEnabled(false);
-                mUsernameAvailabilityImageView.setVisibility(View.INVISIBLE);
-                mUsernameAvailabilitySpinner.setVisibility(View.VISIBLE);
+                binding.ringUsernameTxtBox.setErrorEnabled(false);
+                binding.ringUsernameAvailabilityImageView.setVisibility(View.INVISIBLE);
+                binding.ringUsernameAvailabilitySpinner.setVisibility(View.VISIBLE);
                 break;
             case AVAILABLE:
-                mUsernameTxtBox.setErrorEnabled(false);
-                mUsernameAvailabilityImageView.setVisibility(View.VISIBLE);
-                mUsernameAvailabilityImageView.setImageDrawable(requireContext().getDrawable(R.drawable.ic_good_green));
+                binding.ringUsernameTxtBox.setErrorEnabled(false);
+                binding.ringUsernameAvailabilityImageView.setVisibility(View.VISIBLE);
+                binding.ringUsernameAvailabilityImageView.setImageDrawable(requireContext().getDrawable(R.drawable.ic_good_green));
                 break;
             case RESET:
-                mUsernameTxtBox.setErrorEnabled(false);
-                mUsernameAvailabilityImageView.setVisibility(View.INVISIBLE);
+                binding.ringUsernameTxtBox.setErrorEnabled(false);
+                binding.ringUsernameAvailabilityImageView.setVisibility(View.INVISIBLE);
                 enableNextButton(false);
             default:
-                mUsernameAvailabilityImageView.setVisibility(View.INVISIBLE);
+                binding.ringUsernameAvailabilitySpinner.setVisibility(View.INVISIBLE);
                 break;
         }
     }
@@ -217,29 +180,29 @@
     @Override
     public void showInvalidPasswordError(final boolean display) {
         if (display) {
-            mPasswordTxtBox.setError(getString(R.string.error_password_char_count));
+            binding.passwordTxtBox.setError(getString(R.string.error_password_char_count));
         } else {
-            mPasswordTxtBox.setError(null);
+            binding.passwordTxtBox.setError(null);
         }
     }
 
     @Override
     public void showNonMatchingPasswordError(final boolean display) {
         if (display) {
-            mPasswordRepeatTxtBox.setError(getString(R.string.error_passwords_not_equals));
+            binding.ringPasswordRepeatTxtBox.setError(getString(R.string.error_passwords_not_equals));
         } else {
-            mPasswordRepeatTxtBox.setError(null);
+            binding.ringPasswordRepeatTxtBox.setError(null);
         }
     }
 
     @Override
     public void displayUsernameBox(final boolean display) {
-        mUsernameBox.setVisibility(display ? View.VISIBLE : View.GONE);
+        binding.ringUsernameBox.setVisibility(display ? View.VISIBLE : View.GONE);
     }
 
     @Override
     public void enableNextButton(final boolean enabled) {
-        mCreateAccountButton.setEnabled(enabled);
+        binding.createAccount.setEnabled(enabled);
     }
 
     @Override
diff --git a/ring-android/app/src/main/java/cx/ring/account/JamiAccountSummaryFragment.java b/ring-android/app/src/main/java/cx/ring/account/JamiAccountSummaryFragment.java
index dbed761..9d0b796 100644
--- a/ring-android/app/src/main/java/cx/ring/account/JamiAccountSummaryFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/account/JamiAccountSummaryFragment.java
@@ -32,14 +32,11 @@
 import android.os.Bundle;
 
 import com.google.android.material.bottomsheet.BottomSheetBehavior;
-import com.google.android.material.card.MaterialCardView;
-import com.google.android.material.chip.Chip;
 import com.google.android.material.dialog.MaterialAlertDialogBuilder;
 import com.google.android.material.snackbar.Snackbar;
-import com.google.android.material.textfield.TextInputLayout;
 
 import androidx.annotation.NonNull;
-import androidx.appcompat.widget.SwitchCompat;
+import androidx.annotation.Nullable;
 
 import android.provider.MediaStore;
 import android.text.Layout;
@@ -55,14 +52,10 @@
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.view.inputmethod.EditorInfo;
-import android.widget.Button;
 import android.widget.EditText;
 import android.widget.ImageButton;
 import android.widget.ImageView;
-import android.widget.ListView;
-import android.widget.ScrollView;
 import android.widget.TextView;
-import android.widget.LinearLayout;
 import android.widget.Toast;
 
 import java.io.File;
@@ -73,12 +66,10 @@
 import androidx.core.content.FileProvider;
 import androidx.core.util.Pair;
 
-import butterknife.BindView;
-import butterknife.OnClick;
-import butterknife.OnEditorAction;
 import cx.ring.R;
+import cx.ring.application.JamiApplication;
 import cx.ring.client.HomeActivity;
-import cx.ring.dependencyinjection.JamiInjectionComponent;
+import cx.ring.databinding.FragAccSummaryBinding;
 import cx.ring.model.Account;
 import cx.ring.mvp.BaseSupportFragment;
 import cx.ring.services.AccountService;
@@ -110,87 +101,9 @@
     private static final String FRAGMENT_DIALOG_PASSWORD = TAG + ".dialog.changePassword";
     private static final String FRAGMENT_DIALOG_BACKUP = TAG + ".dialog.backup";
     private static final int WRITE_REQUEST_CODE = 43;
-
     private static final int SCROLL_DIRECTION_UP = -1;
 
     private boolean mIsVisible = true;
-
-    /*
-    UI Bindings
-     */
-
-    @BindView(R.id.ring_password)
-    EditText mRingPassword;
-
-    @BindView(R.id.btn_end_export)
-    Button mEndBtn;
-
-    @BindView(R.id.user_photo)
-    ImageView mUserImage;
-
-    @BindView(R.id.username)
-    TextView mUsername;
-
-    @BindView(R.id.subtitle)
-    TextView mSubtitle;
-
-    @BindView(R.id.btn_start_export)
-    Button mStartBtn;
-
-    @BindView(R.id.account_link_info)
-    TextView mExportInfos;
-
-    @BindView(R.id.account_alias_txt)
-    TextView mAccountNameTxt;
-
-    @BindView(R.id.account_id_txt)
-    TextView mAccountIdTxt;
-
-    @BindView(R.id.layout_account_options)
-    LinearLayout mAccountOptionsLayout;
-
-    @BindView(R.id.change_password_btn)
-    Button mChangePasswordBtn;
-
-    @BindView(R.id.layout_add_device)
-    MaterialCardView mAddAccountLayout;
-
-    @BindView(R.id.export_account_btn)
-    Button mExportButton;
-
-    @BindView(R.id.registered_name_txt)
-    TextView mAccountUsernameTxt;
-
-    @BindView(R.id.register_name_btn)
-    Button mRegisterNameBtn;
-
-    @BindView(R.id.group_registering_name)
-    ViewGroup registeringNameGroup;
-
-    @BindView(R.id.group_register_name)
-    ViewGroup mRegisterNameGroup;
-
-    @BindView(R.id.group_registered_name)
-    ViewGroup mRegisteredNameGroup;
-
-    @BindView(R.id.device_list)
-    ListView mDeviceList;
-
-    @BindView(R.id.password_layout)
-    TextInputLayout mPasswordLayout;
-
-    @BindView(R.id.account_switch)
-    SwitchCompat mAccountSwitch;
-
-    @BindView(R.id.account_status)
-    Chip mAccountStatus;
-
-    @BindView(R.id.scrollview)
-    ScrollView mScrollView;
-
-    /*
-    Declarations
-    */
     private DeviceAdapter mDeviceAdapter;
     private ProgressDialog mWaitDialog;
     private boolean mAccountHasPassword = true;
@@ -205,14 +118,39 @@
     private Uri tmpProfilePhotoUri;
 
     private final CompositeDisposable mDisposableBag = new CompositeDisposable();
+    private final CompositeDisposable mProfileDisposable = new CompositeDisposable();
 
     @Inject
     AccountService mAccountService;
 
+    private FragAccSummaryBinding binding;
+
+    @Nullable
+    @Override
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+        binding = FragAccSummaryBinding.inflate(inflater, container, false);
+        ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
+        mDisposableBag.add(mProfileDisposable);
+        return binding.getRoot();
+    }
+
+    @Override
+    public void onDestroyView() {
+        super.onDestroyView();
+        mDisposableBag.clear();
+        binding = null;
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        mDisposableBag.dispose();
+    }
+
     @Override
     public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
-        mSheetBehavior = BottomSheetBehavior.from(mAddAccountLayout);
+        mSheetBehavior = BottomSheetBehavior.from(binding.layoutAddDevice);
 
         hidePopWizard();
         if (getArguments() != null) {
@@ -226,40 +164,49 @@
             @Override
             public void onStateChanged(@NonNull View view, int i) {
                 if (mSheetBehavior.getState() == BottomSheetBehavior.STATE_COLLAPSED){
-                    mPasswordLayout.setVisibility(mAccountHasPassword ? View.VISIBLE : View.GONE);
-                    mEndBtn.setVisibility(View.GONE);
-                    mStartBtn.setVisibility(View.VISIBLE);
-                    mExportInfos.setText(R.string.account_link_export_info);
+                    binding.passwordLayout.setVisibility(mAccountHasPassword ? View.VISIBLE : View.GONE);
+                    binding.btnEndExport.setVisibility(View.GONE);
+                    binding.btnStartExport.setVisibility(View.VISIBLE);
+                    binding.accountLinkInfo.setText(R.string.account_link_export_info);
                 }
             }
 
             @Override
-            public void onSlide(@NonNull View view, float v) {
-
-            }
+            public void onSlide(@NonNull View view, float v) {}
         });
 
-        updateUserView();
-        mScrollView.getViewTreeObserver().addOnScrollChangedListener(this);
+        updateUserView(mAccountService.getCurrentAccount());
+        binding.scrollview.getViewTreeObserver().addOnScrollChangedListener(this);
+        binding.btnAddDevice.setOnClickListener(v -> flipForm());
+        binding.btnStartExport.setOnClickListener(v -> onClickStart());
+        binding.btnEndExport.setOnClickListener(v -> hidePopWizard());
+        binding.exportAccountBtn.setOnClickListener(v -> onClickExport());
+        binding.profileContainer.setOnClickListener(v -> profileContainerClicked());
+        binding.userProfileEdit.setOnClickListener(v -> profileContainerClicked());
+        binding.accountSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> presenter.enableAccount(isChecked));
+        binding.changePasswordBtn.setOnClickListener(v -> onPasswordChangeAsked());
+        binding.registerNameBtn.setOnClickListener(v -> showUsernameRegistrationPopup());
+        binding.ringPassword.setOnEditorActionListener(this::onPasswordEditorAction);
+    }
+
+    public void setAccount(String accountId) {
+        presenter.setAccountId(accountId);
     }
 
     @Override
-    public void updateUserView() {
-        if (getActivity() == null || mAccountService.getCurrentAccount() == null) {
-            Log.e(TAG, "Not able to update navigation view");
+    public void updateUserView(Account account) {
+        Context context = getContext();
+        if (context == null || account == null)
             return;
-        }
 
-        mDisposableBag.add(mAccountService
-                .getCurrentAccountSubject()
-                .switchMapSingle(account -> AvatarDrawable.load(getActivity(), account)
-                        .map(avatar -> new Pair<>(account, avatar)))
+        mProfileDisposable.clear();
+        mProfileDisposable.add(AvatarDrawable.load(context, account)
+                .map(avatar -> new Pair<>(account, avatar))
                 .observeOn(AndroidSchedulers.mainThread())
                 .subscribe(d -> {
-                    mUsername.setText(getAccountAlias(d.first));
-                    mSubtitle.setText(getUri(d.first,  getActivity().getString(R.string.account_type_ip2ip)));
-                    mUserImage.setImageDrawable(d.second);
-                    accountChanged(d.first);
+                    binding.username.setText(getAccountAlias(d.first));
+                    binding.subtitle.setText(getUri(d.first,  getString(R.string.account_type_ip2ip)));
+                    binding.userPhoto.setImageDrawable(d.second);
                 }, e -> Log.e(TAG, "Error loading avatar", e)));
     }
 
@@ -305,33 +252,34 @@
 
     @Override
     public void accountChanged(@NonNull final Account account) {
+        updateUserView(account);
         if (mDeviceAdapter == null) {
             mDeviceAdapter = new DeviceAdapter(requireContext(), account.getDevices(), account.getDeviceId(),
                     JamiAccountSummaryFragment.this);
-            mDeviceList.setAdapter(mDeviceAdapter);
+            binding.deviceList.setAdapter(mDeviceAdapter);
         } else {
             mDeviceAdapter.setData(account.getDevices(), account.getDeviceId());
         }
 
         int totalHeight = 0;
         for (int i = 0; i < mDeviceAdapter.getCount(); i++) {
-            View listItem = mDeviceAdapter.getView(i, null, mDeviceList);
+            View listItem = mDeviceAdapter.getView(i, null, binding.deviceList);
             listItem.measure(0, 0);
             totalHeight += listItem.getMeasuredHeight();
         }
 
-        ViewGroup.LayoutParams par = mDeviceList.getLayoutParams();
-        par.height = totalHeight + (mDeviceList.getDividerHeight() * (mDeviceAdapter.getCount() - 1));
-        mDeviceList.setLayoutParams(par);
-        mDeviceList.requestLayout();
+        ViewGroup.LayoutParams par = binding.deviceList.getLayoutParams();
+        par.height = totalHeight + (binding.deviceList.getDividerHeight() * (mDeviceAdapter.getCount() - 1));
+        binding.deviceList.setLayoutParams(par);
+        binding.deviceList.requestLayout();
         mAccountHasPassword = account.hasPassword();
         mAccountHasManager = account.hasManager();
 
-        mChangePasswordBtn.setText(mAccountHasPassword ? R.string.account_password_change : R.string.account_password_set);
+        binding.changePasswordBtn.setText(mAccountHasPassword ? R.string.account_password_change : R.string.account_password_set);
 
-        mAccountSwitch.setChecked(account.isEnabled());
-        mAccountNameTxt.setText(getString(R.string.profile));
-        mAccountIdTxt.setText(account.getUsername());
+        binding.accountSwitch.setChecked(account.isEnabled());
+        binding.accountAliasTxt.setText(getString(R.string.profile));
+        binding.accountIdTxt.setText(account.getUsername());
         mAccountId = account.getAccountID();
         mBestName = account.getRegisteredName();
         if (mBestName.isEmpty()) {
@@ -344,11 +292,11 @@
         String username = account.getRegisteredName();
         boolean currentRegisteredName = account.registeringUsername;
         boolean hasRegisteredName = !currentRegisteredName && username != null && !username.isEmpty();
-        registeringNameGroup.setVisibility(currentRegisteredName ? View.VISIBLE : View.GONE);
-        mRegisterNameGroup.setVisibility((!hasRegisteredName && !currentRegisteredName) ? View.VISIBLE : View.GONE);
-        mRegisteredNameGroup.setVisibility(hasRegisteredName ? View.VISIBLE : View.GONE);
+        binding.groupRegisteringName.setVisibility(currentRegisteredName ? View.VISIBLE : View.GONE);
+        binding.groupRegisterName.setVisibility((!hasRegisteredName && !currentRegisteredName) ? View.VISIBLE : View.GONE);
+        binding.groupRegisteredName.setVisibility(hasRegisteredName ? View.VISIBLE : View.GONE);
         if (hasRegisteredName) {
-            mAccountUsernameTxt.setText(username);
+            binding.registeredNameTxt.setText(username);
         }
 
         int color = R.color.red_400;
@@ -376,12 +324,12 @@
             status = getString(R.string.account_status_offline);
         }
 
-        mAccountStatus.setText(status);
-        mAccountStatus.setChipBackgroundColorResource(color);
+        binding.accountStatus.setText(status);
+        binding.accountStatus.setChipBackgroundColorResource(color);
 
-        mPasswordLayout.setVisibility(mAccountHasPassword ? View.VISIBLE : View.GONE);
-        mAddAccountLayout.setVisibility(mAccountHasManager ? View.GONE : View.VISIBLE);
-        mAccountOptionsLayout.setVisibility(mAccountHasManager ? View.GONE : View.VISIBLE);
+        binding.passwordLayout.setVisibility(mAccountHasPassword ? View.VISIBLE : View.GONE);
+        binding.layoutAddDevice.setVisibility(mAccountHasManager ? View.GONE : View.VISIBLE);
+        binding.layoutAccountOptions.setVisibility(mAccountHasManager ? View.GONE : View.VISIBLE);
     }
 
     public boolean onBackPressed() {
@@ -396,9 +344,7 @@
     /*
     Add a new device UI management
      */
-    @OnClick({R.id.btn_add_device})
-    @SuppressWarnings("unused")
-    void flipForm() {
+    private void flipForm() {
         if (!isDisplayingWizard()) {
             showWizard();
         } else {
@@ -410,13 +356,11 @@
         mSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
     }
 
-    @OnClick(R.id.btn_end_export)
-    @SuppressWarnings("unused")
-    public void hidePopWizard() {
+    private void hidePopWizard() {
         mSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
     }
 
-    public void hideWizard() {
+    private void hideWizard() {
         mSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
         KeyboardVisibilityManager.hideKeyboard(getActivity(), 0);
     }
@@ -434,8 +378,8 @@
     @Override
     public void showPasswordError() {
         dismissWaitDialog();
-        mPasswordLayout.setError(getString(R.string.account_export_end_decryption_message));
-        mRingPassword.setText("");
+        binding.passwordLayout.setError(getString(R.string.account_export_end_decryption_message));
+        binding.ringPassword.setText("");
     }
 
     @Override
@@ -448,12 +392,11 @@
                 .show();
     }
 
-    public boolean isDisplayingWizard() {
+    private boolean isDisplayingWizard() {
         return mSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED;
     }
 
-    @OnEditorAction(R.id.ring_password)
-    boolean onPasswordEditorAction(TextView pwd, int actionId, KeyEvent event) {
+    private boolean onPasswordEditorAction(TextView pwd, int actionId, KeyEvent event) {
         Log.i(TAG, "onEditorAction " + actionId + " " + (event == null ? null : event.toString()));
         if (actionId == EditorInfo.IME_ACTION_DONE) {
             if (pwd.getText().length() == 0) {
@@ -466,8 +409,7 @@
         return false;
     }
 
-    @OnClick({R.id.profile_container, R.id.user_profile_edit})
-    public void profileContainerClicked() {
+    private void profileContainerClicked() {
         LayoutInflater inflater = LayoutInflater.from(getActivity());
         ViewGroup view = (ViewGroup) inflater.inflate(R.layout.dialog_profile, null);
 
@@ -498,15 +440,13 @@
                 .show();
     }
 
-    @OnClick(R.id.btn_start_export)
-    void onClickStart() {
-        mPasswordLayout.setError(null);
-        String password = mRingPassword.getText().toString();
+    private void onClickStart() {
+        binding.passwordLayout.setError(null);
+        String password = binding.ringPassword.getText().toString();
         presenter.startAccountExport(password);
     }
 
-    @OnClick(R.id.export_account_btn)
-    void onClickExport() {
+    private void onClickExport() {
         if (mAccountHasPassword) {
             onBackupAccount();
         } else {
@@ -514,13 +454,7 @@
         }
     }
 
-    @OnClick(R.id.account_switch)
-    void onToggleAccount() {
-        presenter.enableAccount(mAccountSwitch.isChecked());
-    }
-
-    @OnClick(R.id.register_name_btn)
-    void showUsernameRegistrationPopup() {
+    private void showUsernameRegistrationPopup() {
         Bundle args = new Bundle();
         args.putString(AccountEditionFragment.ACCOUNT_ID_KEY, getArguments().getString(AccountEditionFragment.ACCOUNT_ID_KEY));
         args.putBoolean(AccountEditionFragment.ACCOUNT_HAS_PASSWORD_KEY, mAccountHasPassword);
@@ -556,16 +490,6 @@
                 getString(R.string.account_password_change_wait_message));
     }
 
-    @Override
-    public int getLayout() {
-        return R.layout.frag_acc_summary;
-    }
-
-    @Override
-    public void injectFragment(JamiInjectionComponent component) {
-        component.inject(this);
-    }
-
     private void dismissWaitDialog() {
         if (mWaitDialog != null) {
             mWaitDialog.dismiss();
@@ -576,11 +500,11 @@
 
     @Override
     public void showPIN(final String pin) {
-        mRingPassword.setText("");
+        binding.ringPassword.setText("");
         mSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
-        mPasswordLayout.setVisibility(View.GONE);
-        mEndBtn.setVisibility(View.VISIBLE);
-        mStartBtn.setVisibility(View.GONE);
+        binding.passwordLayout.setVisibility(View.GONE);
+        binding.btnEndExport.setVisibility(View.VISIBLE);
+        binding.btnStartExport.setVisibility(View.GONE);
         dismissWaitDialog();
         String pined = getString(R.string.account_end_export_infos).replace("%%", pin);
         final SpannableString styledResultText = new SpannableString(pined);
@@ -588,8 +512,8 @@
         styledResultText.setSpan(new AlignmentSpan.Standard(Layout.Alignment.ALIGN_CENTER), pos, (pos + pin.length()), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
         styledResultText.setSpan(new StyleSpan(Typeface.BOLD), pos, (pos + pin.length()), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
         styledResultText.setSpan(new RelativeSizeSpan(2.8f), pos, (pos + pin.length()), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
-        mExportInfos.setText(styledResultText);
-        mExportInfos.requestFocus();
+        binding.accountLinkInfo.setText(styledResultText);
+        binding.accountLinkInfo.requestFocus();
 
         KeyboardVisibilityManager.hideKeyboard(getActivity(), 0);
     }
@@ -665,7 +589,7 @@
         presenter.revokeDevice(deviceId, password);
     }
 
-    public void onBackupAccount() {
+    private void onBackupAccount() {
         BackupAccountDialog dialog = new BackupAccountDialog();
         Bundle args = new Bundle();
         args.putString(AccountEditionFragment.ACCOUNT_ID_KEY, getArguments().getString(AccountEditionFragment.ACCOUNT_ID_KEY));
@@ -696,8 +620,7 @@
         dialog.show(requireFragmentManager(), FRAGMENT_DIALOG_RENAME);
     }
 
-    @OnClick(R.id.change_password_btn)
-    public void onPasswordChangeAsked() {
+    private void onPasswordChangeAsked() {
         ChangePasswordDialog dialog = new ChangePasswordDialog();
         Bundle args = new Bundle();
         args.putString(AccountEditionFragment.ACCOUNT_ID_KEY, getArguments().getString(AccountEditionFragment.ACCOUNT_ID_KEY));
@@ -767,15 +690,13 @@
         requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, HomeActivity.REQUEST_PERMISSION_READ_STORAGE);
     }
 
-    public void updatePhoto(Uri uriImage) {
+    private void updatePhoto(Uri uriImage) {
         mDisposableBag.add(AndroidFileUtils.loadBitmap(getActivity(), uriImage)
                 .observeOn(AndroidSchedulers.mainThread())
                 .subscribe(this::updatePhoto, e -> Log.e(TAG, "Error loading image " + uriImage, e)));
-
-        updateUserView();
     }
 
-    public void updatePhoto(Bitmap image) {
+    private void updatePhoto(Bitmap image) {
         mSourcePhoto = image;
         AvatarDrawable avatarDrawable = new AvatarDrawable.Builder()
                         .withPhoto(image)
@@ -788,11 +709,9 @@
                 .subscribeOn(Schedulers.io())
                 .observeOn(AndroidSchedulers.mainThread())
                 .subscribe(avatar -> mProfilePhoto.setImageDrawable(avatar), e-> Log.e(TAG, "Error loading image", e)));
-
-        updateUserView();
     }
 
-    public String getAccountAlias(Account account) {
+    private String getAccountAlias(Account account) {
         if (account == null) {
             cx.ring.utils.Log.e(TAG, "Not able to get account alias");
             return null;
@@ -801,7 +720,7 @@
         return (alias == null) ? account.getAlias() : alias;
     }
 
-    public String getAlias(Account account) {
+    private String getAlias(Account account) {
         if (account == null) {
             cx.ring.utils.Log.e(TAG, "Not able to get alias");
             return null;
@@ -819,7 +738,7 @@
         return null;
     }
 
-    public String getUri(Account account, CharSequence defaultNameSip) {
+    private String getUri(Account account, CharSequence defaultNameSip) {
         if (account.isIP2IP()) {
             return defaultNameSip.toString();
         }
@@ -845,13 +764,14 @@
 
     @Override
     public void onScrollChanged() {
-        if (mIsVisible && mScrollView != null) {
-            ((HomeActivity) getActivity()).setToolbarElevation(mScrollView.canScrollVertically(SCROLL_DIRECTION_UP));
+        if (mIsVisible && binding != null) {
+            Activity activity = getActivity();
+            if (activity instanceof HomeActivity)
+                ((HomeActivity) activity).setToolbarElevation(binding.scrollview.canScrollVertically(SCROLL_DIRECTION_UP));
         }
     }
 
     public void setFragmentVisibility(boolean isVisible) {
         mIsVisible = isVisible;
     }
-
 }
diff --git a/ring-android/app/src/main/java/cx/ring/account/JamiLinkAccountFragment.java b/ring-android/app/src/main/java/cx/ring/account/JamiLinkAccountFragment.java
index c408502..3eeca84 100644
--- a/ring-android/app/src/main/java/cx/ring/account/JamiLinkAccountFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/account/JamiLinkAccountFragment.java
@@ -20,42 +20,28 @@
 package cx.ring.account;
 
 import android.app.Activity;
+import android.os.Bundle;
 import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.inputmethod.EditorInfo;
-import android.widget.Button;
-import android.widget.EditText;
 
-import butterknife.BindView;
-import butterknife.OnClick;
-import butterknife.OnEditorAction;
-import butterknife.OnTextChanged;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
 import cx.ring.R;
-import cx.ring.dependencyinjection.JamiInjectionComponent;
+import cx.ring.application.JamiApplication;
+import cx.ring.databinding.FragAccRingLinkBinding;
 import cx.ring.mvp.BaseSupportFragment;
 import cx.ring.mvp.AccountCreationModel;
 
 public class JamiLinkAccountFragment extends BaseSupportFragment<JamiLinkAccountPresenter> implements JamiLinkAccountView {
 
     public static final String TAG = JamiLinkAccountFragment.class.getSimpleName();
-
-    @BindView(R.id.pin_box)
-    protected ViewGroup mPinBox;
-
-    @BindView(R.id.pin_help_message)
-    protected View mPinMessage;
-
-    @BindView(R.id.ring_add_pin)
-    protected EditText mPinTxt;
-
-    @BindView(R.id.ring_existing_password)
-    protected EditText mPasswordTxt;
-
-    @BindView(R.id.link_button)
-    protected Button mLinkAccountBtn;
-
     private AccountCreationModel model;
+    private FragAccRingLinkBinding binding;
 
     public static JamiLinkAccountFragment newInstance(AccountCreationModelImpl ringAccountViewModel) {
         JamiLinkAccountFragment fragment = new JamiLinkAccountFragment();
@@ -63,14 +49,53 @@
         return fragment;
     }
 
+    @Nullable
     @Override
-    public int getLayout() {
-        return R.layout.frag_acc_ring_link;
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+        binding = FragAccRingLinkBinding.inflate(inflater, container, false);
+        ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
+        return binding.getRoot();
     }
 
     @Override
-    public void injectFragment(JamiInjectionComponent component) {
-        component.inject(this);
+    public void onDestroyView() {
+        super.onDestroyView();
+        binding = null;
+    }
+
+    @Override
+    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
+        binding.linkButton.setOnClickListener(v -> presenter.linkClicked());
+        binding.ringAddPin.setOnEditorActionListener((v, actionId, event) -> {
+            if (actionId == EditorInfo.IME_ACTION_DONE) {
+                presenter.linkClicked();
+            }
+            return false;
+        });
+        binding.ringAddPin.addTextChangedListener(new TextWatcher() {
+            @Override
+            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+            @Override
+            public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+            @Override
+            public void afterTextChanged(Editable s) {
+                presenter.pinChanged(s.toString());
+            }
+        });
+        binding.ringExistingPassword.addTextChangedListener(new TextWatcher() {
+            @Override
+            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+            @Override
+            public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+            @Override
+            public void afterTextChanged(Editable s) {
+                presenter.passwordChanged(s.toString());
+            }
+        });
     }
 
     @Override
@@ -78,39 +103,16 @@
         presenter.init(model);
     }
 
-    @OnClick(R.id.link_button)
-    public void onLinkClick() {
-        presenter.linkClicked();
-    }
-
-    @OnTextChanged(value = R.id.ring_existing_password, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
-    public void afterPasswordChanged(Editable txt) {
-        presenter.passwordChanged(txt.toString());
-    }
-
-    @OnTextChanged(value = R.id.ring_add_pin, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
-    public void afterPinChanged(Editable txt) {
-        presenter.pinChanged(txt.toString());
-    }
-
-    @OnEditorAction(value = R.id.ring_add_pin)
-    public boolean onPasswordConfirmDone(int keyCode) {
-        if (keyCode == EditorInfo.IME_ACTION_DONE) {
-            presenter.linkClicked();
-        }
-        return false;
-    }
-
     @Override
     public void enableLinkButton(boolean enable) {
-        mLinkAccountBtn.setEnabled(enable);
+        binding.linkButton.setEnabled(enable);
     }
 
     @Override
     public void showPin(boolean show) {
-        mPinBox.setVisibility(show ? View.VISIBLE : View.GONE);
-        mPinMessage.setVisibility(show ? View.VISIBLE : View.GONE);
-        mLinkAccountBtn.setText(show ? R.string.account_link_device : R.string.account_link_archive_button);
+        binding.pinBox.setVisibility(show ? View.VISIBLE : View.GONE);
+        binding.pinHelpMessage.setVisibility(show ? View.VISIBLE : View.GONE);
+        binding.linkButton.setText(show ? R.string.account_link_device : R.string.account_link_archive_button);
     }
 
     @Override
diff --git a/ring-android/app/src/main/java/cx/ring/account/ProfileCreationFragment.java b/ring-android/app/src/main/java/cx/ring/account/ProfileCreationFragment.java
index ca6ab30..4367071 100644
--- a/ring-android/app/src/main/java/cx/ring/account/ProfileCreationFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/account/ProfileCreationFragment.java
@@ -31,22 +31,20 @@
 import android.os.Bundle;
 import android.provider.MediaStore;
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
 import android.text.Editable;
+import android.text.TextWatcher;
 import android.util.Log;
+import android.view.LayoutInflater;
 import android.view.View;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.ImageButton;
-import android.widget.ImageView;
+import android.view.ViewGroup;
 
 import java.io.File;
 import java.io.IOException;
 
-import butterknife.BindView;
-import butterknife.OnClick;
-import butterknife.OnTextChanged;
-import cx.ring.R;
-import cx.ring.dependencyinjection.JamiInjectionComponent;
+import cx.ring.application.JamiApplication;
+import cx.ring.databinding.FragAccProfileCreateBinding;
 import cx.ring.model.Account;
 import cx.ring.mvp.AccountCreationModel;
 import cx.ring.mvp.BaseSupportFragment;
@@ -63,23 +61,9 @@
     public static final int REQUEST_PERMISSION_CAMERA = 3;
     public static final int REQUEST_PERMISSION_READ_STORAGE = 4;
 
-    @BindView(R.id.profile_photo)
-    protected ImageView mPhotoView;
-
-    @BindView(R.id.user_name)
-    protected EditText mFullnameView;
-
-    @BindView(R.id.gallery)
-    protected ImageButton mGalleryButton;
-
-    @BindView(R.id.camera)
-    protected ImageButton mCameraButton;
-
-    @BindView(R.id.next_create_account)
-    protected Button mNextButton;
-
     private AccountCreationModel model;
     private Uri tmpProfilePhotoUri;
+    private FragAccProfileCreateBinding binding;
 
     public static ProfileCreationFragment newInstance(AccountCreationModelImpl model) {
         ProfileCreationFragment fragment = new ProfileCreationFragment();
@@ -87,14 +71,18 @@
         return fragment;
     }
 
+    @Nullable
     @Override
-    public int getLayout() {
-        return R.layout.frag_acc_profile_create;
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+        binding = FragAccProfileCreateBinding.inflate(inflater, container, false);
+        ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
+        return binding.getRoot();
     }
 
     @Override
-    public void injectFragment(JamiInjectionComponent component) {
-        component.inject(this);
+    public void onDestroyView() {
+        super.onDestroyView();
+        binding = null;
     }
 
     @Override
@@ -106,8 +94,8 @@
             getActivity().finish();
             return;
         }
-        if (mPhotoView.getDrawable() == null) {
-            mPhotoView.setImageDrawable(
+        if (binding.profilePhoto.getDrawable() == null) {
+            binding.profilePhoto.setImageDrawable(
                     new AvatarDrawable.Builder()
                             .withNameData(model.getFullName(), model.getUsername())
                             .withCircleCrop(true)
@@ -115,6 +103,23 @@
             );
         }
         presenter.initPresenter(model);
+
+        binding.gallery.setOnClickListener(v -> presenter.galleryClick());
+        binding.camera.setOnClickListener(v -> presenter.cameraClick());
+        binding.nextCreateAccount.setOnClickListener(v -> presenter.nextClick());
+        binding.skipCreateAccount.setOnClickListener(v -> presenter.skipClick());
+        binding.userName.addTextChangedListener(new TextWatcher() {
+            @Override
+            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+            @Override
+            public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+            @Override
+            public void afterTextChanged(Editable s) {
+                presenter.fullNameUpdated(s.toString());
+            }
+        });
     }
 
     @Override
@@ -163,29 +168,9 @@
         }
     }
 
-    @OnClick(R.id.gallery)
-    void galleryClicked() {
-        presenter.galleryClick();
-    }
-
-    @OnClick(R.id.camera)
-    void cameraClicked() {
-        presenter.cameraClick();
-    }
-
-    @OnClick(R.id.next_create_account)
-    void nextClicked() {
-        presenter.nextClick();
-    }
-
-    @OnClick(R.id.skip_create_account)
-    void skipClicked() {
-        presenter.skipClick();
-    }
-
     @Override
     public void displayProfileName(String profileName) {
-        mFullnameView.setText(profileName);
+        binding.userName.setText(profileName);
     }
 
     @Override
@@ -235,7 +220,7 @@
     public void setProfile(AccountCreationModel accountCreationModel) {
         AccountCreationModelImpl model = ((AccountCreationModelImpl) accountCreationModel);
         Account newAccount = model.getNewAccount();
-        mPhotoView.setImageDrawable(
+        binding.profilePhoto.setImageDrawable(
                 new AvatarDrawable.Builder()
                         .withPhoto(model.getPhoto())
                         .withNameData(accountCreationModel.getFullName(), accountCreationModel.getUsername())
@@ -245,8 +230,4 @@
         );
     }
 
-    @OnTextChanged(value = R.id.user_name, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
-    public void afterTextChanged(Editable txt) {
-        presenter.fullNameUpdated(txt.toString());
-    }
 }
diff --git a/ring-android/app/src/main/java/cx/ring/account/RegisterNameDialog.java b/ring-android/app/src/main/java/cx/ring/account/RegisterNameDialog.java
index 83a09d6..5c46aa5 100644
--- a/ring-android/app/src/main/java/cx/ring/account/RegisterNameDialog.java
+++ b/ring-android/app/src/main/java/cx/ring/account/RegisterNameDialog.java
@@ -27,23 +27,18 @@
 import android.view.WindowManager;
 import android.view.inputmethod.EditorInfo;
 import android.widget.Button;
-import android.widget.EditText;
 import android.widget.TextView;
 
 import com.google.android.material.dialog.MaterialAlertDialogBuilder;
-import com.google.android.material.textfield.TextInputLayout;
 
 import javax.inject.Inject;
 
 import androidx.annotation.NonNull;
 import androidx.appcompat.app.AlertDialog;
 import androidx.fragment.app.DialogFragment;
-import butterknife.BindString;
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import butterknife.OnEditorAction;
 import cx.ring.R;
 import cx.ring.application.JamiApplication;
+import cx.ring.databinding.FragRegisterNameBinding;
 import cx.ring.services.AccountService;
 import cx.ring.utils.RegisteredNameFilter;
 import cx.ring.utils.RegisteredNameTextWatcher;
@@ -52,28 +47,8 @@
 
 public class RegisterNameDialog extends DialogFragment {
     static final String TAG = RegisterNameDialog.class.getSimpleName();
-    @BindView(R.id.ring_username_txt_box)
-    public TextInputLayout mUsernameTxtBox;
-    @BindView(R.id.ring_username)
-    public EditText mUsernameTxt;
-    @BindView(R.id.password_txt_box)
-    public TextInputLayout mPasswordTxtBox;
-    @BindView(R.id.password_txt)
-    public EditText mPasswordTxt;
-    @BindString(R.string.register_name)
-    public String mRegisterTitle;
-    @BindString(R.string.register_username)
-    public String mRegisterMessage;
-    @BindString(R.string.prompt_new_username)
-    public String mPromptUsername;
-    @BindString(R.string.prompt_password)
-    public String mPromptPassword;
     @Inject
     AccountService mAccountService;
-    @BindString(R.string.username_already_taken)
-    String mUserNameAlreadyTaken;
-    @BindString(R.string.invalid_username)
-    String mInvalidUsername;
     @Inject
     Scheduler mUiScheduler;
 
@@ -81,16 +56,17 @@
     private RegisterNameDialogListener mListener = null;
 
     private Disposable mDisposableListener;
+    private FragRegisterNameBinding binding;
 
     public void setListener(RegisterNameDialogListener l) {
         mListener = l;
     }
 
     private void handleBlockchainResult(final int state, final String name) {
-        String actualName = mUsernameTxt.getText().toString();
-        if (actualName.isEmpty()) {
-            mUsernameTxtBox.setErrorEnabled(false);
-            mUsernameTxtBox.setError(null);
+        CharSequence actualName = binding.ringUsername.getText();
+        if (actualName == null || actualName.length() == 0) {
+            binding.ringUsernameTxtBox.setErrorEnabled(false);
+            binding.ringUsernameTxtBox.setError(null);
             return;
         }
 
@@ -98,18 +74,18 @@
             switch (state) {
                 case 0:
                     // on found
-                    mUsernameTxtBox.setErrorEnabled(true);
-                    mUsernameTxtBox.setError(mUserNameAlreadyTaken);
+                    binding.ringUsernameTxtBox.setErrorEnabled(true);
+                    binding.ringUsernameTxtBox.setError(getText(R.string.username_already_taken));
                     break;
                 case 1:
                     // invalid name
-                    mUsernameTxtBox.setErrorEnabled(true);
-                    mUsernameTxtBox.setError(mInvalidUsername);
+                    binding.ringUsernameTxtBox.setErrorEnabled(true);
+                    binding.ringUsernameTxtBox.setError(getText(R.string.invalid_username));
                     break;
                 default:
                     // on error
-                    mUsernameTxtBox.setErrorEnabled(false);
-                    mUsernameTxtBox.setError(null);
+                    binding.ringUsernameTxtBox.setErrorEnabled(false);
+                    binding.ringUsernameTxtBox.setError(null);
                     break;
             }
         }
@@ -118,11 +94,11 @@
     @NonNull
     @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
-        View view = getActivity().getLayoutInflater().inflate(R.layout.frag_register_name, null);
-        ButterKnife.bind(this, view);
+        binding = FragRegisterNameBinding.inflate(getActivity().getLayoutInflater());
+        View view = binding.getRoot();
 
         // dependency injection
-        ((JamiApplication) getActivity().getApplication()).getRingInjectionComponent().inject(this);
+        ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
 
         String accountId = "";
         boolean hasPassword = true;
@@ -132,10 +108,13 @@
             hasPassword = args.getBoolean(AccountEditionFragment.ACCOUNT_HAS_PASSWORD_KEY, true);
         }
 
-        mUsernameTxt.setFilters(new InputFilter[]{new RegisteredNameFilter()});
-        mUsernameTextWatcher = new RegisteredNameTextWatcher(getActivity(), mAccountService, accountId, mUsernameTxtBox, mUsernameTxt);
-        mUsernameTxt.addTextChangedListener(mUsernameTextWatcher);
-        mPasswordTxtBox.setVisibility(hasPassword ? View.VISIBLE : View.GONE);
+        mUsernameTextWatcher = new RegisteredNameTextWatcher(getActivity(), mAccountService, accountId, binding.ringUsernameTxtBox, binding.ringUsername);
+        binding.ringUsername.setFilters(new InputFilter[]{new RegisteredNameFilter()});
+        binding.ringUsername.addTextChangedListener(mUsernameTextWatcher);
+        // binding.ringUsername.setOnEditorActionListener((v, actionId, event) -> RegisterNameDialog.this.onEditorAction(v, actionId));
+
+        binding.passwordTxtBox.setVisibility(hasPassword ? View.VISIBLE : View.GONE);
+        binding.passwordTxt.setOnEditorActionListener((v, actionId, event) -> RegisterNameDialog.this.onEditorAction(v, actionId));
 
         AlertDialog dialog = (AlertDialog) getDialog();
         if (dialog != null) {
@@ -145,8 +124,8 @@
 
         AlertDialog result = new MaterialAlertDialogBuilder(requireContext())
                 .setView(view)
-                .setMessage(mRegisterMessage)
-                .setTitle(mRegisterTitle)
+                .setMessage(R.string.register_username)
+                .setTitle(R.string.register_name)
                 .setPositiveButton(android.R.string.ok, null) //Set to null. We override the onclick
                 .setNegativeButton(android.R.string.cancel, (d, b) -> dismiss())
                 .create();
@@ -164,10 +143,10 @@
     }
 
     @Override
-    public void onAttach(Context context) {
+    public void onAttach(@NonNull Context context) {
         super.onAttach(context);
-        if (mUsernameTxt != null) {
-            mUsernameTxt.addTextChangedListener(mUsernameTextWatcher);
+        if (binding != null) {
+            binding.ringUsername.addTextChangedListener(mUsernameTextWatcher);
         }
     }
 
@@ -188,61 +167,62 @@
 
     @Override
     public void onDetach() {
-        if (mUsernameTxt != null) {
-            mUsernameTxt.removeTextChangedListener(mUsernameTextWatcher);
+        if (binding != null) {
+            binding.ringUsername.removeTextChangedListener(mUsernameTextWatcher);
         }
         super.onDetach();
     }
 
     private boolean isValidUsername() {
-        return mUsernameTxtBox.getError() == null;
+        return binding.ringUsernameTxtBox.getError() == null;
     }
 
-    public boolean checkInput() {
-        if (mUsernameTxt.getText().toString().isEmpty()) {
-            mUsernameTxtBox.setErrorEnabled(true);
-            mUsernameTxtBox.setError(mPromptUsername);
+    private boolean checkInput() {
+        if (binding.ringUsername.getText() == null || binding.ringUsername.getText().length() == 0) {
+            binding.ringUsernameTxtBox.setErrorEnabled(true);
+            binding.ringUsernameTxtBox.setError(getText(R.string.prompt_new_username));
             return false;
         }
 
         if (!isValidUsername()) {
-            mUsernameTxt.requestFocus();
+            binding.ringUsername.requestFocus();
             return false;
         }
 
-        mUsernameTxtBox.setErrorEnabled(false);
-        mUsernameTxtBox.setError(null);
+        binding.ringUsernameTxtBox.setErrorEnabled(false);
+        binding.ringUsernameTxtBox.setError(null);
 
-        if (mPasswordTxtBox.getVisibility() == View.VISIBLE) {
-            if (mPasswordTxt.getText().toString().isEmpty()) {
-                mPasswordTxtBox.setErrorEnabled(true);
-                mPasswordTxtBox.setError(mPromptPassword);
+        if (binding.passwordTxtBox.getVisibility() == View.VISIBLE) {
+            if (binding.passwordTxt.getText() == null || binding.passwordTxt.getText().length() == 0) {
+                binding.passwordTxtBox.setErrorEnabled(true);
+                binding.passwordTxtBox.setError(getString(R.string.prompt_password));
                 return false;
             } else {
-                mPasswordTxtBox.setErrorEnabled(false);
-                mPasswordTxtBox.setError(null);
+                binding.passwordTxtBox.setErrorEnabled(false);
+                binding.passwordTxtBox.setError(null);
             }
         }
         return true;
     }
 
-    boolean validate() {
+    private boolean validate() {
         if (checkInput() && mListener != null) {
-            final String username = mUsernameTxt.getText().toString();
-            final String password = mPasswordTxt.getText().toString();
+            final String username = binding.ringUsername.getText().toString();
+            final String password = binding.passwordTxt.getText().toString();
             mListener.onRegisterName(username, password);
             return true;
         }
         return false;
     }
 
-    @OnEditorAction({R.id.ring_username, R.id.password_txt})
-    public boolean onEditorAction(TextView v, int actionId) {
-        if (v == mPasswordTxt) {
+    private boolean onEditorAction(TextView v, int actionId) {
+        if (v == binding.passwordTxt) {
             if (actionId == EditorInfo.IME_ACTION_DONE) {
                 boolean validationResult = validate();
                 if (validationResult) {
-                    getDialog().dismiss();
+                    Dialog dialog = getDialog();
+                    if (dialog != null)
+                        dialog.dismiss();
                 }
 
                 return validationResult;
diff --git a/ring-android/app/src/main/java/cx/ring/account/RenameDeviceDialog.java b/ring-android/app/src/main/java/cx/ring/account/RenameDeviceDialog.java
index ceb91d1..c81a74fc 100644
--- a/ring-android/app/src/main/java/cx/ring/account/RenameDeviceDialog.java
+++ b/ring-android/app/src/main/java/cx/ring/account/RenameDeviceDialog.java
@@ -22,34 +22,23 @@
 import android.os.Bundle;
 
 import com.google.android.material.dialog.MaterialAlertDialogBuilder;
-import com.google.android.material.textfield.TextInputLayout;
 
 import androidx.annotation.NonNull;
 import androidx.appcompat.app.AlertDialog;
-import android.view.View;
+
 import android.view.WindowManager;
 import android.view.inputmethod.EditorInfo;
 import android.widget.Button;
-import android.widget.EditText;
-import android.widget.TextView;
 
 import androidx.fragment.app.DialogFragment;
-import butterknife.BindString;
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import butterknife.OnEditorAction;
 import cx.ring.R;
+import cx.ring.databinding.DialogDeviceRenameBinding;
 
 public class RenameDeviceDialog extends DialogFragment {
     public static final String DEVICENAME_KEY = "devicename_key";
     static final String TAG = RenameDeviceDialog.class.getSimpleName();
-    @BindView(R.id.ring_device_name_txt_box)
-    public TextInputLayout mDeviceNameTxtBox;
-    @BindView(R.id.ring_device_name_txt)
-    public EditText mDeviceNameTxt;
-    @BindString(R.string.account_device_name_empty)
-    protected String mPromptDeviceName;
     private RenameDeviceListener mListener = null;
+    private DialogDeviceRenameBinding binding;
 
     public void setListener(RenameDeviceListener listener) {
         mListener = listener;
@@ -58,13 +47,22 @@
     @NonNull
     @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
-        View view = requireActivity().getLayoutInflater().inflate(R.layout.dialog_device_rename, null);
-        ButterKnife.bind(this, view);
+        binding = DialogDeviceRenameBinding.inflate(getActivity().getLayoutInflater());
 
-        mDeviceNameTxt.setText(getArguments().getString(DEVICENAME_KEY));
+        binding.ringDeviceNameTxt.setText(getArguments().getString(DEVICENAME_KEY));
+        binding.ringDeviceNameTxt.setOnEditorActionListener((v, actionId, event) -> {
+            if (actionId == EditorInfo.IME_ACTION_DONE) {
+                boolean validationResult = validate();
+                if (validationResult) {
+                    getDialog().dismiss();
+                }
+                return validationResult;
+            }
+            return false;
+        });
 
         final AlertDialog dialog = new MaterialAlertDialogBuilder(requireContext())
-                .setView(view)
+                .setView(binding.getRoot())
                 .setTitle(R.string.rename_device_title)
                 .setMessage(R.string.rename_device_message)
                 .setPositiveButton(R.string.rename_device_button, null)
@@ -90,18 +88,18 @@
 
     private boolean checkInput(String input) {
         if (input.isEmpty()) {
-            mDeviceNameTxtBox.setErrorEnabled(true);
-            mDeviceNameTxtBox.setError(mPromptDeviceName);
+            binding.ringDeviceNameTxtBox.setErrorEnabled(true);
+            binding.ringDeviceNameTxtBox.setError(getText(R.string.account_device_name_empty));
             return false;
         } else {
-            mDeviceNameTxtBox.setErrorEnabled(false);
-            mDeviceNameTxtBox.setError(null);
+            binding.ringDeviceNameTxtBox.setErrorEnabled(false);
+            binding.ringDeviceNameTxtBox.setError(null);
         }
         return true;
     }
 
     private boolean validate() {
-        String input = mDeviceNameTxt.getText().toString().trim();
+        String input = binding.ringDeviceNameTxt.getText().toString().trim();
         if (checkInput(input) && mListener != null) {
             mListener.onDeviceRename(input);
             return true;
@@ -109,20 +107,6 @@
         return false;
     }
 
-    @OnEditorAction({R.id.ring_device_name_txt})
-    public boolean onEditorAction(TextView v, int actionId) {
-        if (v == mDeviceNameTxt) {
-            if (actionId == EditorInfo.IME_ACTION_DONE) {
-                boolean validationResult = validate();
-                if (validationResult) {
-                    getDialog().dismiss();
-                }
-                return validationResult;
-            }
-        }
-        return false;
-    }
-
     public interface RenameDeviceListener {
         void onDeviceRename(String newName);
     }
diff --git a/ring-android/app/src/main/java/cx/ring/adapters/AccountView.java b/ring-android/app/src/main/java/cx/ring/adapters/AccountView.java
deleted file mode 100644
index 84a8e4d..0000000
--- a/ring-android/app/src/main/java/cx/ring/adapters/AccountView.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- *  Copyright (C) 2004-2019 Savoir-faire Linux Inc.
- *
- *  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.graphics.Color;
-import android.view.View;
-import android.widget.CheckBox;
-import android.widget.ImageView;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-
-import androidx.recyclerview.widget.RecyclerView;
-
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import cx.ring.R;
-import cx.ring.model.Account;
-import cx.ring.views.AvatarDrawable;
-import io.reactivex.android.schedulers.AndroidSchedulers;
-import io.reactivex.disposables.CompositeDisposable;
-import io.reactivex.schedulers.Schedulers;
-
-public class AccountView extends RecyclerView.ViewHolder {
-
-    public interface OnAccountActionListener {
-        void onAccountSelected(Account account);
-        void onAccountEnabled(Account account);
-    }
-
-    private final OnAccountActionListener listener;
-
-    @BindView(R.id.account_photo)
-    ImageView photo;
-
-    @BindView(R.id.account_alias)
-    TextView alias;
-
-    @BindView(R.id.account_host)
-    TextView host;
-
-    @BindView(R.id.error_indicator)
-    ImageView error;
-
-    @BindView(R.id.loading_indicator)
-    ProgressBar loading;
-
-    private TextView disabled_flag;
-    private CheckBox enabled;
-
-    private final CompositeDisposable mDisposable = new CompositeDisposable();
-
-    public AccountView(View view, OnAccountActionListener l) {
-        super(view);
-        listener = l;
-        ButterKnife.bind(this, view);
-        disabled_flag = view.findViewById(R.id.account_disabled);
-        enabled = view.findViewById(R.id.account_checked);
-    }
-
-    public void update(final Account account) {
-        final Context context = itemView.getContext();
-        mDisposable.clear();
-        mDisposable.add(AvatarDrawable.load(context, account)
-                .subscribeOn(Schedulers.computation())
-                .observeOn(AndroidSchedulers.mainThread())
-                .subscribe(avatar -> photo.setImageDrawable(avatar)));
-        itemView.setOnClickListener(v -> listener.onAccountSelected(account));
-
-        mDisposable.add(account.getAccountAlias()
-                .observeOn(AndroidSchedulers.mainThread())
-                .subscribe(a -> alias.setText(a)));
-
-        host.setText(account.getDisplayUri(context.getText(R.string.account_type_ip2ip)));
-        itemView.setEnabled(account.isEnabled());
-
-        if (disabled_flag != null) {
-            disabled_flag.setVisibility(account.isEnabled() ? View.GONE : View.VISIBLE);
-        }
-
-        if (enabled != null) {
-            enabled.setChecked(account.isEnabled());
-            enabled.setOnClickListener(v -> {
-                account.setEnabled(!account.isEnabled());
-                listener.onAccountEnabled(account);
-            });
-        }
-
-        if (account.isEnabled()) {
-            alias.setTextColor(context.getResources().getColor(R.color.textColorPrimary));
-            host.setTextColor(context.getResources().getColor(R.color.textColorPrimary));
-            if (!account.isActive()) {
-                error.setImageResource(R.drawable.baseline_sync_disabled_24);
-                error.setColorFilter(Color.BLACK);
-                error.setVisibility(View.VISIBLE);
-                loading.setVisibility(View.GONE);
-            } else if (account.isTrying()) {
-                error.setVisibility(View.GONE);
-                loading.setVisibility(View.VISIBLE);
-            } else if (account.needsMigration()) {
-                host.setText(R.string.account_update_needed);
-                host.setTextColor(Color.RED);
-                error.setImageResource(R.drawable.baseline_warning_24);
-                error.setColorFilter(Color.RED);
-                error.setVisibility(View.VISIBLE);
-            } else if (account.isInError() || !account.isRegistered()) {
-                error.setImageResource(R.drawable.baseline_error_24);
-                error.setColorFilter(Color.RED);
-                error.setVisibility(View.VISIBLE);
-                loading.setVisibility(View.GONE);
-            } else {
-                error.setVisibility(View.GONE);
-                loading.setVisibility(View.GONE);
-            }
-        } else {
-            alias.setTextColor(context.getResources().getColor(R.color.textColorSecondary));
-            error.setVisibility(View.GONE);
-            loading.setVisibility(View.GONE);
-        }
-    }
-}
diff --git a/ring-android/app/src/main/java/cx/ring/application/JamiApplication.java b/ring-android/app/src/main/java/cx/ring/application/JamiApplication.java
index 035c385..6b23129 100644
--- a/ring-android/app/src/main/java/cx/ring/application/JamiApplication.java
+++ b/ring-android/app/src/main/java/cx/ring/application/JamiApplication.java
@@ -300,7 +300,7 @@
         sInstance = null;
     }
 
-    public JamiInjectionComponent getRingInjectionComponent() {
+    public JamiInjectionComponent getInjectionComponent() {
         return mJamiInjectionComponent;
     }
 
diff --git a/ring-android/app/src/main/java/cx/ring/client/ContactDetailsActivity.java b/ring-android/app/src/main/java/cx/ring/client/ContactDetailsActivity.java
index 47e0232..a76f940 100644
--- a/ring-android/app/src/main/java/cx/ring/client/ContactDetailsActivity.java
+++ b/ring-android/app/src/main/java/cx/ring/client/ContactDetailsActivity.java
@@ -65,7 +65,6 @@
 import cx.ring.model.SipCall;
 import cx.ring.services.AccountService;
 import cx.ring.services.NotificationService;
-import cx.ring.utils.ContentUriHandler;
 import cx.ring.utils.ConversationPath;
 import cx.ring.views.AvatarDrawable;
 import io.reactivex.android.schedulers.AndroidSchedulers;
@@ -172,7 +171,7 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         binding = DataBindingUtil.setContentView(this, R.layout.activity_contact_details);
-        JamiApplication.getInstance().getRingInjectionComponent().inject(this);
+        JamiApplication.getInstance().getInjectionComponent().inject(this);
 
         CollapsingToolbarLayout collapsingToolbarLayout = findViewById(R.id.toolbar_layout);
         collapsingToolbarLayout.setTitle("");
@@ -275,7 +274,7 @@
     @Override
     protected void onDestroy() {
         adapter.actions.clear();
-        mDisposableBag.clear();
+        mDisposableBag.dispose();
         super.onDestroy();
         contactAction = null;
         colorAction = null;
diff --git a/ring-android/app/src/main/java/cx/ring/client/ConversationActivity.java b/ring-android/app/src/main/java/cx/ring/client/ConversationActivity.java
index 68a3d8c..4361b47 100644
--- a/ring-android/app/src/main/java/cx/ring/client/ConversationActivity.java
+++ b/ring-android/app/src/main/java/cx/ring/client/ConversationActivity.java
@@ -40,30 +40,21 @@
 import androidx.coordinatorlayout.widget.CoordinatorLayout;
 import androidx.core.view.ViewCompat;
 
-import com.google.android.material.appbar.AppBarLayout;
-
-import butterknife.BindView;
-import butterknife.ButterKnife;
 import cx.ring.R;
 import cx.ring.application.JamiApplication;
+import cx.ring.databinding.ActivityConversationBinding;
 import cx.ring.fragments.ConversationFragment;
 import cx.ring.interfaces.Colorable;
 import cx.ring.utils.ConversationPath;
 import cx.ring.utils.MediaButtonsHelper;
 
 public class ConversationActivity extends AppCompatActivity implements Colorable {
-    @BindView(R.id.toolbar_layout)
-    AppBarLayout mToolbarLayout;
-
-    @BindView(R.id.main_toolbar)
-    Toolbar mToolbar;
 
     private ConversationFragment mConversationFragment;
-    /*private String contactUri = null;
-    private String accountId = null;*/
     private ConversationPath conversationPath = null;
 
     private Intent mPendingIntent = null;
+    private ActivityConversationBinding binding;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -71,9 +62,10 @@
 
         JamiApplication.getInstance().startDaemon();
 
-        setContentView(R.layout.activity_conversation);
-        ButterKnife.bind(this);
-        setSupportActionBar(mToolbar);
+        binding = ActivityConversationBinding.inflate(getLayoutInflater());
+        setContentView(binding.getRoot());
+
+        setSupportActionBar(binding.mainToolbar);
         ActionBar ab = getSupportActionBar();
         if (ab != null)
             ab.setDisplayHomeAsUpEnabled(true);
@@ -86,10 +78,10 @@
                         | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                         | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
 
-        ViewCompat.setOnApplyWindowInsetsListener(mToolbarLayout, (v, insets) -> {
-            CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) mToolbarLayout.getLayoutParams();
+        ViewCompat.setOnApplyWindowInsetsListener(binding.toolbarLayout, (v, insets) -> {
+            CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) binding.toolbarLayout.getLayoutParams();
             params.topMargin = insets.getSystemWindowInsetTop();
-            mToolbarLayout.setLayoutParams(params);
+            binding.toolbarLayout.setLayoutParams(params);
             insets.consumeSystemWindowInsets();
             return insets;
         });
@@ -153,7 +145,7 @@
     }
 
     public void setColor(@ColorInt int color) {
-        colouriseToolbar(mToolbar, color);
+        colouriseToolbar(binding.mainToolbar, color);
         //mToolbar.setBackground(new ColorDrawable(color));
         //getWindow().setStatusBarColor(color);
     }
diff --git a/ring-android/app/src/main/java/cx/ring/client/ConversationSelectionActivity.java b/ring-android/app/src/main/java/cx/ring/client/ConversationSelectionActivity.java
index 4ad662e..1f03a1c 100644
--- a/ring-android/app/src/main/java/cx/ring/client/ConversationSelectionActivity.java
+++ b/ring-android/app/src/main/java/cx/ring/client/ConversationSelectionActivity.java
@@ -24,9 +24,7 @@
 import android.text.TextUtils;
 
 import androidx.annotation.Nullable;
-import androidx.appcompat.app.ActionBar;
 import androidx.appcompat.app.AppCompatActivity;
-import androidx.appcompat.widget.Toolbar;
 import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 
@@ -69,7 +67,7 @@
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        JamiApplication.getInstance().getRingInjectionComponent().inject(this);
+        JamiApplication.getInstance().getInjectionComponent().inject(this);
         setContentView(R.layout.frag_selectconv);
         RecyclerView list = findViewById(R.id.conversationList);
 
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 9e2456a..a3f204b 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
@@ -24,7 +24,6 @@
 import android.net.Uri;
 import android.os.Bundle;
 
-import com.google.android.material.appbar.AppBarLayout;
 import com.google.android.material.badge.BadgeDrawable;
 import com.google.android.material.bottomnavigation.BottomNavigationView;
 import com.google.android.material.dialog.MaterialAlertDialogBuilder;
@@ -34,7 +33,6 @@
 import androidx.core.util.Pair;
 import androidx.appcompat.app.ActionBar;
 import androidx.appcompat.app.AppCompatActivity;
-import androidx.appcompat.widget.Toolbar;
 
 import android.util.Log;
 import android.view.MenuItem;
@@ -52,8 +50,6 @@
 import androidx.fragment.app.FragmentManager;
 import androidx.fragment.app.FragmentTransaction;
 
-import butterknife.BindView;
-import butterknife.ButterKnife;
 import cx.ring.BuildConfig;
 import cx.ring.R;
 import cx.ring.about.AboutFragment;
@@ -62,6 +58,7 @@
 import cx.ring.application.JamiApplication;
 import cx.ring.contactrequests.ContactRequestsFragment;
 import cx.ring.contacts.AvatarFactory;
+import cx.ring.databinding.ActivityHomeBinding;
 import cx.ring.fragments.ConversationFragment;
 import cx.ring.fragments.SmartListFragment;
 import cx.ring.interfaces.BackHandlerInterface;
@@ -119,22 +116,12 @@
     @Inject
     NotificationService mNotificationService;
 
-    @BindView(R.id.main_toolbar)
-    Toolbar mToolbar;
-
-    @BindView(R.id.spinner_toolbar)
-    Spinner mToolbarSpinner;
-
-    @BindView(R.id.navigation_view)
-    BottomNavigationView mBottomNavigationView;
-
-    @BindView(R.id.app_bar)
-    AppBarLayout mAppBarLayout;
-
     @Inject
     @Named("UiScheduler")
     protected Scheduler mUiScheduler;
 
+    private ActivityHomeBinding binding;
+
     private boolean mIsMigrationDialogAlreadyShowed;
     private String mAccountWithPendingrequests = null;
 
@@ -162,34 +149,32 @@
         mDisposable.add(mAccountCheckDisposable);
 
         JamiApplication.getInstance().startDaemon();
-        FragmentManager fragmentManager = getSupportFragmentManager();
 
-        setContentView(R.layout.activity_home);
-
-        ButterKnife.bind(this);
+        binding = ActivityHomeBinding.inflate(getLayoutInflater());
+        setContentView(binding.getRoot());
 
         // dependency injection
-        JamiApplication.getInstance().getRingInjectionComponent().inject(this);
+        JamiApplication.getInstance().getInjectionComponent().inject(this);
 
         mOrientation = getResources().getConfiguration().orientation;
 
-        setSupportActionBar(mToolbar);
+        setSupportActionBar(binding.mainToolbar);
 
         ActionBar ab = getSupportActionBar();
         if (ab != null) {
             ab.setTitle("");
         }
 
-        mBottomNavigationView.setOnNavigationItemSelectedListener(this);
-        mBottomNavigationView.getMenu().getItem(NAVIGATION_CONVERSATIONS).setChecked(true);
+        binding.navigationView.setOnNavigationItemSelectedListener(this);
+        binding.navigationView.getMenu().getItem(NAVIGATION_CONVERSATIONS).setChecked(true);
 
-        mOutlineProvider = mAppBarLayout.getOutlineProvider();
+        mOutlineProvider = binding.appBar.getOutlineProvider();
 
         if (!DeviceUtils.isTablet(this)) {
             getWindow().setNavigationBarColor(ContextCompat.getColor(this, R.color.bottom_navigation));
         }
 
-        mToolbarSpinner.setOnItemSelectedListener(this);
+        binding.spinnerToolbar.setOnItemSelectedListener(this);
 
         // if app opened from notification display trust request fragment when mService will connected
         Intent intent = getIntent();
@@ -203,6 +188,7 @@
         } else if (Intent.ACTION_SEND.equals(action) || Intent.ACTION_SEND_MULTIPLE.equals(action)) {
             handleShareIntent(intent);
         }
+        FragmentManager fragmentManager = getSupportFragmentManager();
         fContent = fragmentManager.findFragmentById(R.id.main_frame);
         if (fContent == null || Intent.ACTION_SEARCH.equals(action)) {
             fContent = new SmartListFragment();
@@ -221,6 +207,7 @@
     protected void onDestroy() {
         super.onDestroy();
         fContent = null;
+        mDisposable.dispose();
     }
 
     private void handleShareIntent(Intent intent) {
@@ -287,20 +274,20 @@
     }
 
     public void setToolbarState(String title, String subtitle) {
-        mToolbar.setLogo(null);
-        mToolbar.setTitle(title);
+        binding.mainToolbar.setLogo(null);
+        binding.mainToolbar.setTitle(title);
 
         if (subtitle != null) {
-            mToolbar.setSubtitle(subtitle);
+            binding.mainToolbar.setSubtitle(subtitle);
         } else {
-            mToolbar.setSubtitle(null);
+            binding.mainToolbar.setSubtitle(null);
         }
     }
 
     private void showProfileInfo() {
-        mToolbarSpinner.setVisibility(View.VISIBLE);
-        mToolbar.setTitle(null);
-        mToolbar.setSubtitle(null);
+        binding.spinnerToolbar.setVisibility(View.VISIBLE);
+        binding.mainToolbar.setTitle(null);
+        binding.mainToolbar.setSubtitle(null);
 
         int targetSize = (int) (AvatarFactory.SIZE_AB * getResources().getDisplayMetrics().density);
         mDisposable.add(mAccountService.getCurrentAccountSubject()
@@ -308,7 +295,7 @@
                         .map(avatar -> new Pair<>(account, avatar)))
                 .observeOn(AndroidSchedulers.mainThread())
                 .subscribe(d -> {
-                    mToolbar.setLogo(new BitmapDrawable(getResources(), d.second));
+                    binding.mainToolbar.setLogo(new BitmapDrawable(getResources(), d.second));
                 }, e -> Log.e(TAG, "Error loading avatar", e)));
     }
 
@@ -336,7 +323,7 @@
                 .observeOn(mUiScheduler)
                 .subscribe(accounts -> {
                     mAccountAdapter = new ToolbarSpinnerAdapter(HomeActivity.this, R.layout.item_toolbar_spinner, accounts);
-                    mToolbarSpinner.setAdapter(mAccountAdapter);
+                    binding.spinnerToolbar.setAdapter(mAccountAdapter);
                     showProfileInfo();
                 }, e ->  cx.ring.utils.Log.e(TAG, "Error loading account list !", e)));
 
@@ -389,7 +376,7 @@
         }
         fContent = new ContactRequestsFragment();
         fContent.setArguments(bundle);
-        mBottomNavigationView.getMenu().getItem(NAVIGATION_CONTACT_REQUESTS).setChecked(true);
+        binding.navigationView.getMenu().getItem(NAVIGATION_CONTACT_REQUESTS).setChecked(true);
         getSupportFragmentManager().beginTransaction()
                 .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
                 .replace(R.id.main_frame, fContent, CONTACT_REQUESTS_TAG)
@@ -422,8 +409,8 @@
             fContent = fragmentManager.findFragmentById(entry.getId());
             fragmentManager.popBackStack();
             if (fCount == 2) {
-                mBottomNavigationView.getMenu().getItem(NAVIGATION_CONVERSATIONS).setChecked(true);
-                mBottomNavigationView.setVisibility(View.VISIBLE);
+                binding.navigationView.getMenu().getItem(NAVIGATION_CONVERSATIONS).setChecked(true);
+                binding.navigationView.setVisibility(View.VISIBLE);
                 showProfileInfo();
                 showToolbarSpinner();
                 if (!conversationSelected) {
@@ -583,7 +570,7 @@
 
             Account account = mAccountService.getCurrentAccount();
             if (account != null) {
-                mToolbarSpinner.setSelection(mAccountService.getAccountList().indexOf(account.getAccountID()));
+                binding.spinnerToolbar.setSelection(mAccountService.getAccountList().indexOf(account.getAccountID()));
             }
         }
     }
@@ -599,21 +586,21 @@
 
     public void setBadge(int menuId, int number) {
         if (number == 0) {
-            mBottomNavigationView.removeBadge(menuId);
+            binding.navigationView.removeBadge(menuId);
             return;
         }
 
-        mBottomNavigationView.getOrCreateBadge(menuId);
-        BadgeDrawable badgeDrawable = mBottomNavigationView.getBadge(menuId);
+        binding.navigationView.getOrCreateBadge(menuId);
+        BadgeDrawable badgeDrawable = binding.navigationView.getBadge(menuId);
         if (badgeDrawable != null) {
             badgeDrawable.setNumber(number);
         }
     }
 
     private void hideTabletToolbar() {
-        TextView title = mToolbar.findViewById(R.id.contact_title);
-        TextView subtitle = mToolbar.findViewById(R.id.contact_subtitle);
-        ImageView logo = mToolbar.findViewById(R.id.contact_image);
+        TextView title = binding.mainToolbar.findViewById(R.id.contact_title);
+        TextView subtitle = binding.mainToolbar.findViewById(R.id.contact_subtitle);
+        ImageView logo = binding.mainToolbar.findViewById(R.id.contact_image);
 
         if (title != null)
             title.setText(null);
@@ -625,17 +612,17 @@
 
     private void showTabletToolbar() {
         if (DeviceUtils.isTablet(this)) {
-            mToolbar.findViewById(R.id.tablet_toolbar).setVisibility(View.VISIBLE);
+            binding.mainToolbar.findViewById(R.id.tablet_toolbar).setVisibility(View.VISIBLE);
         }
     }
 
     private void showToolbarSpinner() {
-        mToolbarSpinner.setVisibility(View.VISIBLE);
+        binding.spinnerToolbar.setVisibility(View.VISIBLE);
     }
 
     private void hideToolbarSpinner() {
         if (!DeviceUtils.isTablet(HomeActivity.this)) {
-            mToolbarSpinner.setVisibility(View.GONE);
+            binding.spinnerToolbar.setVisibility(View.GONE);
         }
     }
 
@@ -656,20 +643,19 @@
     }
 
     public void setToolbarElevation(boolean enable) {
-        if (mAppBarLayout != null)
-            mAppBarLayout.setElevation(enable ? getResources().getDimension(R.dimen.toolbar_elevation) : 0);
+        binding.appBar.setElevation(enable ? getResources().getDimension(R.dimen.toolbar_elevation) : 0);
     }
 
     public void setToolbarOutlineState(boolean enabled) {
         if (!enabled) {
-            mAppBarLayout.setOutlineProvider(null);
+            binding.appBar.setOutlineProvider(null);
         } else {
-            mAppBarLayout.setOutlineProvider(mOutlineProvider);
+            binding.appBar.setOutlineProvider(mOutlineProvider);
         }
     }
 
     public void selectNavigationItem(int id) {
-        mBottomNavigationView.setSelectedItemId(id);
+        binding.navigationView.setSelectedItemId(id);
     }
 
 }
diff --git a/ring-android/app/src/main/java/cx/ring/client/RingtoneActivity.java b/ring-android/app/src/main/java/cx/ring/client/RingtoneActivity.java
index ec53cee..ac37da4 100644
--- a/ring-android/app/src/main/java/cx/ring/client/RingtoneActivity.java
+++ b/ring-android/app/src/main/java/cx/ring/client/RingtoneActivity.java
@@ -83,7 +83,7 @@
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
-        JamiApplication.getInstance().getRingInjectionComponent().inject(this);
+        JamiApplication.getInstance().getInjectionComponent().inject(this);
         setContentView(R.layout.activity_ringtone);
         super.onCreate(savedInstanceState);
         mAccount = mAccountService.getAccount(getIntent().getExtras().getString(AccountEditionFragment.ACCOUNT_ID_KEY));
diff --git a/ring-android/app/src/main/java/cx/ring/contactrequests/BlackListFragment.java b/ring-android/app/src/main/java/cx/ring/contactrequests/BlackListFragment.java
index ed38dc1..b0956e1 100644
--- a/ring-android/app/src/main/java/cx/ring/contactrequests/BlackListFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/contactrequests/BlackListFragment.java
@@ -23,20 +23,17 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.TextView;
 
 import java.util.Collection;
 
-import butterknife.BindView;
-import cx.ring.R;
 import cx.ring.account.AccountEditionFragment;
-import cx.ring.dependencyinjection.JamiInjectionComponent;
+import cx.ring.application.JamiApplication;
+import cx.ring.databinding.FragBlacklistBinding;
 import cx.ring.model.CallContact;
 import cx.ring.mvp.BaseSupportFragment;
 
@@ -45,35 +42,27 @@
 
     public static final String TAG = BlackListFragment.class.getSimpleName();
 
-    @BindView(R.id.blacklist)
-    protected RecyclerView mBlacklist;
-
-    @BindView(R.id.emptyTextView)
-    protected TextView mEmptyTextView;
-
     private BlackListAdapter mAdapter;
-
-    @Override
-    public int getLayout() {
-        return R.layout.frag_blacklist;
-    }
-
-    @Override
-    public void injectFragment(JamiInjectionComponent component) {
-        component.inject(this);
-    }
+    private FragBlacklistBinding binding;
 
     @Nullable
     @Override
-    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+        binding = FragBlacklistBinding.inflate(inflater, container, false);
+        ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
         setHasOptionsMenu(true);
-        return super.onCreateView(inflater, container, savedInstanceState);
+        return binding.getRoot();
+    }
+
+    @Override
+    public void onDestroyView() {
+        super.onDestroyView();
+        binding = null;
     }
 
     @Override
     public void onResume() {
         super.onResume();
-
         if (getArguments() == null || getArguments().getString(AccountEditionFragment.ACCOUNT_ID_KEY) == null) {
             return;
         }
@@ -81,7 +70,7 @@
     }
 
     @Override
-    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+    public void onCreateOptionsMenu(Menu menu, @NonNull MenuInflater inflater) {
         menu.clear();
     }
 
@@ -97,26 +86,24 @@
 
     @Override
     public void updateView(final Collection<CallContact> list) {
-        getActivity().runOnUiThread(() -> {
-            mBlacklist.setVisibility(View.VISIBLE);
-            if (mBlacklist.getAdapter() != null) {
-                mAdapter.replaceAll(list);
-            } else {
-                mAdapter = new BlackListAdapter(list, BlackListFragment.this);
-                LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
-                mBlacklist.setLayoutManager(layoutManager);
-                mBlacklist.setAdapter(mAdapter);
-            }
-        });
+        binding.blacklist.setVisibility(View.VISIBLE);
+        if (binding.blacklist.getAdapter() != null) {
+            mAdapter.replaceAll(list);
+        } else {
+            mAdapter = new BlackListAdapter(list, BlackListFragment.this);
+            LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
+            binding.blacklist.setLayoutManager(layoutManager);
+            binding.blacklist.setAdapter(mAdapter);
+        }
     }
 
     @Override
     public void hideListView() {
-        getActivity().runOnUiThread(() -> mBlacklist.setVisibility(View.GONE));
+        binding.blacklist.setVisibility(View.GONE);
     }
 
     @Override
     public void displayEmptyListMessage(final boolean display) {
-        getActivity().runOnUiThread(() -> mEmptyTextView.setVisibility(display ? View.VISIBLE : View.GONE));
+        binding.emptyTextView.setVisibility(display ? View.VISIBLE : View.GONE);
     }
 }
\ No newline at end of file
diff --git a/ring-android/app/src/main/java/cx/ring/contactrequests/BlackListViewHolder.java b/ring-android/app/src/main/java/cx/ring/contactrequests/BlackListViewHolder.java
index 3e52d2a..dbbdcef 100644
--- a/ring-android/app/src/main/java/cx/ring/contactrequests/BlackListViewHolder.java
+++ b/ring-android/app/src/main/java/cx/ring/contactrequests/BlackListViewHolder.java
@@ -21,36 +21,22 @@
 
 import androidx.recyclerview.widget.RecyclerView;
 import android.view.View;
-import android.widget.ImageButton;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import cx.ring.R;
 import cx.ring.contacts.AvatarFactory;
+import cx.ring.databinding.ItemContactBlacklistBinding;
 import cx.ring.model.CallContact;
 
 public class BlackListViewHolder extends RecyclerView.ViewHolder {
-    @BindView(R.id.unblock)
-    protected ImageButton mButtonUnblock;
+    private final ItemContactBlacklistBinding binding;
 
-    @BindView(R.id.photo)
-    protected ImageView mPhoto;
-
-    @BindView(R.id.display_name)
-    protected TextView mDisplayname;
-
-
-    public BlackListViewHolder(View view) {
+    BlackListViewHolder(View view) {
         super(view);
-        ButterKnife.bind(this, view);
+        binding = ItemContactBlacklistBinding.bind(view);
     }
 
-    public void bind(final BlackListListeners clickListener, final CallContact contact) {
-        AvatarFactory.loadGlideAvatar(mPhoto, contact);
-        mDisplayname.setText(contact.getRingUsername());
-        mButtonUnblock.setOnClickListener(view -> clickListener.onUnblockClicked(contact));
+    void bind(final BlackListListeners clickListener, final CallContact contact) {
+        AvatarFactory.loadGlideAvatar(binding.photo, contact);
+        binding.displayName.setText(contact.getRingUsername());
+        binding.unblock.setOnClickListener(view -> clickListener.onUnblockClicked(contact));
     }
 
     public interface BlackListListeners {
diff --git a/ring-android/app/src/main/java/cx/ring/contactrequests/ContactRequestsFragment.java b/ring-android/app/src/main/java/cx/ring/contactrequests/ContactRequestsFragment.java
index ba51dd5..85b71ba 100644
--- a/ring-android/app/src/main/java/cx/ring/contactrequests/ContactRequestsFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/contactrequests/ContactRequestsFragment.java
@@ -24,6 +24,7 @@
 import android.os.Bundle;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 import android.view.LayoutInflater;
@@ -31,17 +32,16 @@
 import android.view.MenuInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.TextView;
 
 import java.util.List;
 import java.util.Objects;
 
-import butterknife.BindView;
 import cx.ring.R;
 import cx.ring.adapters.SmartListAdapter;
+import cx.ring.application.JamiApplication;
 import cx.ring.client.ConversationActivity;
 import cx.ring.client.HomeActivity;
-import cx.ring.dependencyinjection.JamiInjectionComponent;
+import cx.ring.databinding.FragPendingContactRequestsBinding;
 import cx.ring.mvp.BaseSupportFragment;
 import cx.ring.smartlist.SmartListViewModel;
 import cx.ring.utils.ConversationPath;
@@ -56,31 +56,23 @@
 
     private static final int SCROLL_DIRECTION_UP = -1;
 
-    @BindView(R.id.requests_list)
-    protected RecyclerView mRequestsList;
+    private SmartListAdapter mAdapter;
+    private FragPendingContactRequestsBinding binding;
 
-    @BindView(R.id.pane_ringID)
-    protected TextView mPaneTextView;
-
-    @BindView(R.id.emptyTextView)
-    protected TextView mEmptyTextView;
-
-    public SmartListAdapter mAdapter;
-
+    @Nullable
     @Override
-    public int getLayout() {
-        return R.layout.frag_pending_contact_requests;
-    }
-
-    @Override
-    public void injectFragment(JamiInjectionComponent component) {
-        component.inject(this);
-    }
-
-    @Override
-    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+        binding = FragPendingContactRequestsBinding.inflate(inflater, container, false);
+        ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
         setHasOptionsMenu(true);
-        return super.onCreateView(inflater, parent, savedInstanceState);
+        return binding.getRoot();
+    }
+
+    @Override
+    public void onDestroyView() {
+        super.onDestroyView();
+        mAdapter = null;
+        binding = null;
     }
 
     public void presentForAccount(Bundle bundle) {
@@ -103,7 +95,7 @@
     }
 
     @Override
-    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+    public void onCreateOptionsMenu(Menu menu, @NonNull MenuInflater inflater) {
         menu.clear();
     }
 
@@ -114,26 +106,26 @@
 
     @Override
     public void updateView(final List<SmartListViewModel> list) {
-        if (mPaneTextView == null || mEmptyTextView == null) {
+        if (binding == null) {
             return;
         }
 
         if (!list.isEmpty()) {
-            mPaneTextView.setVisibility(/*viewModel.hasPane() ? View.VISIBLE :*/ View.GONE);
+            binding.paneRingID.setVisibility(/*viewModel.hasPane() ? View.VISIBLE :*/ View.GONE);
         }
 
-        mEmptyTextView.setVisibility(list.isEmpty() ? View.VISIBLE : View.GONE);
+        binding.emptyTextView.setVisibility(list.isEmpty() ? View.VISIBLE : View.GONE);
 
-        if (mRequestsList.getAdapter() != null) {
+        if (binding.requestsList.getAdapter() != null) {
             mAdapter.update(list);
         } else {
             mAdapter = new SmartListAdapter(list, ContactRequestsFragment.this);
-            mRequestsList.setAdapter(mAdapter);
+            binding.requestsList.setAdapter(mAdapter);
             LinearLayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
-            mRequestsList.setLayoutManager(mLayoutManager);
+            binding.requestsList.setLayoutManager(mLayoutManager);
         }
 
-        mRequestsList.addOnScrollListener(new RecyclerView.OnScrollListener() {
+        binding.requestsList.addOnScrollListener(new RecyclerView.OnScrollListener() {
             @Override
             public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                 super.onScrollStateChanged(recyclerView, newState);
@@ -141,7 +133,7 @@
 
             @Override
             public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
-                ((HomeActivity) getActivity()).setToolbarElevation(mRequestsList.canScrollVertically(SCROLL_DIRECTION_UP));
+                ((HomeActivity) getActivity()).setToolbarElevation(recyclerView.canScrollVertically(SCROLL_DIRECTION_UP));
             }
         });
 
diff --git a/ring-android/app/src/main/java/cx/ring/dependencyinjection/ServiceInjectionModule.java b/ring-android/app/src/main/java/cx/ring/dependencyinjection/ServiceInjectionModule.java
index e3f7eab..a6da464 100755
--- a/ring-android/app/src/main/java/cx/ring/dependencyinjection/ServiceInjectionModule.java
+++ b/ring-android/app/src/main/java/cx/ring/dependencyinjection/ServiceInjectionModule.java
@@ -67,7 +67,7 @@
     @Singleton
     PreferencesService provideSettingsService() {
         SharedPreferencesServiceImpl settingsService = new SharedPreferencesServiceImpl();
-        mJamiApplication.getRingInjectionComponent().inject(settingsService);
+        mJamiApplication.getInjectionComponent().inject(settingsService);
         return settingsService;
     }
 
@@ -75,7 +75,7 @@
     @Singleton
     HistoryService provideHistoryService() {
         HistoryServiceImpl historyService = new HistoryServiceImpl();
-        mJamiApplication.getRingInjectionComponent().inject(historyService);
+        mJamiApplication.getInjectionComponent().inject(historyService);
         return historyService;
     }
 
@@ -91,7 +91,7 @@
     @Singleton
     NotificationService provideNotificationService() {
         NotificationServiceImpl service = new NotificationServiceImpl();
-        mJamiApplication.getRingInjectionComponent().inject(service);
+        mJamiApplication.getInjectionComponent().inject(service);
         service.initHelper();
         return service;
     }
@@ -100,7 +100,7 @@
     @Singleton
     DeviceRuntimeService provideDeviceRuntimeService(LogService logService) {
         DeviceRuntimeServiceImpl runtimeService = new DeviceRuntimeServiceImpl();
-        mJamiApplication.getRingInjectionComponent().inject(runtimeService);
+        mJamiApplication.getInjectionComponent().inject(runtimeService);
         runtimeService.loadNativeLibrary();
         return runtimeService;
     }
@@ -109,7 +109,7 @@
     @Singleton
     DaemonService provideDaemonService(DeviceRuntimeService deviceRuntimeService) {
         DaemonService daemonService = new DaemonService(deviceRuntimeService);
-        mJamiApplication.getRingInjectionComponent().inject(daemonService);
+        mJamiApplication.getInjectionComponent().inject(daemonService);
         return daemonService;
     }
 
@@ -117,7 +117,7 @@
     @Singleton
     CallService provideCallService() {
         CallService callService = new CallService();
-        mJamiApplication.getRingInjectionComponent().inject(callService);
+        mJamiApplication.getInjectionComponent().inject(callService);
         return callService;
     }
 
@@ -125,7 +125,7 @@
     @Singleton
     AccountService provideAccountService() {
         AccountService accountService = new AccountService();
-        mJamiApplication.getRingInjectionComponent().inject(accountService);
+        mJamiApplication.getInjectionComponent().inject(accountService);
         return accountService;
     }
 
@@ -133,7 +133,7 @@
     @Singleton
     HardwareService provideHardwareService(Context context) {
         HardwareServiceImpl hardwareService = new HardwareServiceImpl(context);
-        mJamiApplication.getRingInjectionComponent().inject(hardwareService);
+        mJamiApplication.getInjectionComponent().inject(hardwareService);
         return hardwareService;
     }
 
@@ -141,7 +141,7 @@
     @Singleton
     ContactService provideContactService(PreferencesService sharedPreferencesService) {
         ContactServiceImpl contactService = new ContactServiceImpl();
-        mJamiApplication.getRingInjectionComponent().inject(contactService);
+        mJamiApplication.getInjectionComponent().inject(contactService);
         return contactService;
     }
 
@@ -154,7 +154,7 @@
             AccountService accountService,
             NotificationService notificationService) {
         ConversationFacade conversationFacade = new ConversationFacade(historyService, callService, accountService, contactService, notificationService);
-        mJamiApplication.getRingInjectionComponent().inject(conversationFacade);
+        mJamiApplication.getInjectionComponent().inject(conversationFacade);
         return conversationFacade;
     }
 
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/AccountMigrationFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/AccountMigrationFragment.java
index c6a11cd..1eea06b 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/AccountMigrationFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/AccountMigrationFragment.java
@@ -25,15 +25,13 @@
 import android.content.pm.ActivityInfo;
 import android.os.Bundle;
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.appcompat.app.AlertDialog;
 import android.text.TextUtils;
-import android.util.Log;
-import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.inputmethod.EditorInfo;
-import android.widget.EditText;
 import android.widget.TextView;
 
 import java.util.HashMap;
@@ -44,13 +42,9 @@
 
 import com.google.android.material.dialog.MaterialAlertDialogBuilder;
 
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import butterknife.OnClick;
-import butterknife.OnEditorAction;
-import butterknife.OnFocusChange;
 import cx.ring.R;
 import cx.ring.application.JamiApplication;
+import cx.ring.databinding.FragAccountMigrationBinding;
 import cx.ring.model.Account;
 import cx.ring.model.AccountConfig;
 import cx.ring.model.ConfigKey;
@@ -63,9 +57,9 @@
     static final String TAG = AccountMigrationFragment.class.getSimpleName();
     @Inject
     AccountService mAccountService;
-    // UI references.
-    @BindView(R.id.ring_password)
-    EditText mRingPassword;
+
+    private FragAccountMigrationBinding binding;
+
     private String mAccountId;
     private ProgressDialog mProgress = null;
 
@@ -80,33 +74,22 @@
     }
 
     @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
-        final View inflatedView = inflater.inflate(R.layout.frag_account_migration, parent, false);
-        ButterKnife.bind(this, inflatedView);
-
-        // dependency injection
-        ((JamiApplication) getActivity().getApplication()).getRingInjectionComponent().inject(this);
-
-        return inflatedView;
+    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
+        binding = FragAccountMigrationBinding.inflate(inflater, parent, false);
+        ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
+        return binding.getRoot();
     }
 
-    @OnEditorAction(R.id.ring_password)
-    public boolean onPasswordEditorAction(TextView v, int actionId, KeyEvent event) {
-        Log.d(TAG, "onPasswordEditorAction: " + actionId + " " + (event == null ? null : event.toString()));
-        return actionId == EditorInfo.IME_ACTION_NEXT && checkPassword(v, null);
-    }
+    @Override
+    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
+        binding.ringPassword.setOnEditorActionListener((v, actionId, event) -> actionId == EditorInfo.IME_ACTION_NEXT && checkPassword(v, null));
+        binding.ringPassword.setOnFocusChangeListener((v, hasFocus) -> {
+            if (!hasFocus) {
+                checkPassword((TextView) v, null);
+            }
+        });
 
-    @OnFocusChange(R.id.ring_password)
-    public void onPasswordFocusChange(View v, boolean hasFocus) {
-        if (!hasFocus) {
-            checkPassword((TextView) v, null);
-        }
-    }
-
-    @OnClick(R.id.ring_migrate_btn)
-    @SuppressWarnings("unused")
-    void onMigrateButtonClick(View view) {
-        initAccountMigration(mRingPassword.getText().toString());
+        binding.ringMigrateBtn.setOnClickListener(v -> initAccountMigration(binding.ringPassword.getText().toString()));
     }
 
     @Override
@@ -117,12 +100,6 @@
         }
     }
 
-    @Override
-    public void onPause() {
-        super.onPause();
-    }
-
-    @SuppressWarnings("unchecked")
     private void initAccountMigration(String password) {
         if (migratingAccount) {
             return;
@@ -131,7 +108,9 @@
         migratingAccount = true;
 
         //orientation is locked during the migration of account to avoid the destruction of the thread
-        getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
+        Activity activity = getActivity();
+        if (activity != null)
+            getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
 
         mProgress = new ProgressDialog(getActivity());
         mProgress.setTitle(R.string.dialog_wait_update);
@@ -196,24 +175,24 @@
             //do things
         });
         boolean success = false;
-        switch (newState) {
-            case AccountConfig.STATE_INVALID:
-                dialogBuilder.setTitle(R.string.account_cannot_be_found_title)
-                        .setMessage(R.string.account_cannot_be_updated_message);
-                break;
-            default:
-                dialogBuilder.setTitle(R.string.account_device_updated_title)
-                        .setMessage(R.string.account_device_updated_message);
-                success = true;
-                break;
+        if (AccountConfig.STATE_INVALID.equals(newState)) {
+            dialogBuilder.setTitle(R.string.account_cannot_be_found_title)
+                    .setMessage(R.string.account_cannot_be_updated_message);
+        } else {
+            dialogBuilder.setTitle(R.string.account_device_updated_title)
+                    .setMessage(R.string.account_device_updated_message);
+            success = true;
         }
         AlertDialog dialogSuccess = dialogBuilder.show();
         if (success) {
             dialogSuccess.setOnDismissListener(dialogInterface -> {
-                getActivity().setResult(Activity.RESULT_OK, new Intent());
-                //unlock the screen orientation
-                getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
-                getActivity().finish();
+                Activity activity = getActivity();
+                if (activity != null) {
+                    activity.setResult(Activity.RESULT_OK, new Intent());
+                    //unlock the screen orientation
+                    activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
+                    activity.finish();
+                }
             });
         }
     }
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/AdvancedAccountFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/AdvancedAccountFragment.java
index b87dc65..ea9b89c 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/AdvancedAccountFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/AdvancedAccountFragment.java
@@ -47,7 +47,7 @@
 
     @Override
     public void onCreatePreferences(Bundle bundle, String s) {
-        ((JamiApplication) requireActivity().getApplication()).getRingInjectionComponent().inject(this);
+        ((JamiApplication) requireActivity().getApplication()).getInjectionComponent().inject(this);
         super.onCreatePreferences(bundle, s);
 
         // Load the preferences from an XML resource
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/CallFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/CallFragment.java
index e35cf8c..02008e0 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/CallFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/CallFragment.java
@@ -263,16 +263,6 @@
     }
 
     @Override
-    public int getLayout() {
-        return R.layout.frag_call;
-    }
-
-    @Override
-    public void injectFragment(JamiInjectionComponent component) {
-        component.inject(this);
-    }
-
-    @Override
     public void onStart() {
         super.onStart();
         if (restartVideo && restartPreview) {
@@ -299,7 +289,7 @@
     @Nullable
     @Override
     public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
-        injectFragment(((JamiApplication) requireActivity().getApplication()).getRingInjectionComponent());
+        ((JamiApplication) requireActivity().getApplication()).getInjectionComponent().inject(this);
         binding = DataBindingUtil.inflate(inflater, R.layout.frag_call, container, false);
         binding.setPresenter(this);
         return binding.getRoot();
@@ -541,8 +531,14 @@
         if (mScreenWakeLock != null && mScreenWakeLock.isHeld()) {
             mScreenWakeLock.release();
         }
+        binding = null;
     }
 
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        mCompositeDisposable.dispose();
+    }
 
     @Override
     public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/ConversationFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/ConversationFragment.java
index 3c86847..b6bf0e0 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/ConversationFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/ConversationFragment.java
@@ -75,7 +75,6 @@
 import java.util.List;
 import java.util.Map;
 
-import butterknife.OnEditorAction;
 import cx.ring.BuildConfig;
 import cx.ring.R;
 import cx.ring.adapters.ConversationAdapter;
@@ -89,7 +88,6 @@
 import cx.ring.conversation.ConversationPresenter;
 import cx.ring.conversation.ConversationView;
 import cx.ring.databinding.FragConversationBinding;
-import cx.ring.dependencyinjection.JamiInjectionComponent;
 import cx.ring.interfaces.Colorable;
 import cx.ring.model.Account;
 import cx.ring.model.CallContact;
@@ -197,16 +195,6 @@
         }
     }
 
-    @Override
-    public int getLayout() {
-        return R.layout.frag_conversation;
-    }
-
-    @Override
-    public void injectFragment(JamiInjectionComponent component) {
-        component.inject(this);
-    }
-
     private static void setBottomPadding(@NonNull View view, int padding) {
         view.setPadding(
                 view.getPaddingLeft(),
@@ -227,7 +215,7 @@
     @Nullable
     @Override
     public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
-        injectFragment(((JamiApplication) getActivity().getApplication()).getRingInjectionComponent());
+        ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
         Resources res = getResources();
         marginPx = res.getDimensionPixelSize(R.dimen.conversation_message_input_margin);
         mapWidth = res.getDimensionPixelSize(R.dimen.location_sharing_minmap_width);
@@ -340,6 +328,8 @@
         if (animator != null)
             animator.setSupportsChangeAnimations(false);
         binding.histList.setAdapter(mAdapter);
+
+
     }
 
     @Override
@@ -741,7 +731,6 @@
         }
     }
 
-    @OnEditorAction(R.id.msg_input_txt)
     boolean actionSendMsgText(int actionId) {
         switch (actionId) {
             case EditorInfo.IME_ACTION_SEND:
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/GeneralAccountFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/GeneralAccountFragment.java
index 945885a..b037f35 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/GeneralAccountFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/GeneralAccountFragment.java
@@ -143,7 +143,7 @@
 
     @Override
     public void onCreatePreferences(Bundle bundle, String rootKey) {
-        ((JamiApplication) requireActivity().getApplication()).getRingInjectionComponent().inject(this);
+        ((JamiApplication) requireActivity().getApplication()).getInjectionComponent().inject(this);
         super.onCreatePreferences(bundle, rootKey);
 
         Bundle args = getArguments();
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/LocationSharingFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/LocationSharingFragment.java
index b34d0bb..958d229 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/LocationSharingFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/LocationSharingFragment.java
@@ -157,7 +157,7 @@
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        ((JamiApplication) requireActivity().getApplication()).getRingInjectionComponent().inject(this);
+        ((JamiApplication) requireActivity().getApplication()).getInjectionComponent().inject(this);
         setRetainInstance(true);
 
         Bundle args = getArguments();
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/MediaPreferenceFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/MediaPreferenceFragment.java
index f333745..a9ff785 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/MediaPreferenceFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/MediaPreferenceFragment.java
@@ -74,7 +74,7 @@
 
     @Override
     public void onCreatePreferences(Bundle bundle, String rootKey) {
-        ((JamiApplication) getActivity().getApplication()).getRingInjectionComponent().inject(this);
+        ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
         super.onCreatePreferences(bundle, rootKey);
 
         String accountId = getArguments().getString(AccountEditionFragment.ACCOUNT_ID_KEY);
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/SIPAccountCreationFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/SIPAccountCreationFragment.java
index 1b3e61a..119e609 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/SIPAccountCreationFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/SIPAccountCreationFragment.java
@@ -25,68 +25,54 @@
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 
-import android.view.KeyEvent;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
 import android.view.inputmethod.EditorInfo;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 
 import com.google.android.material.dialog.MaterialAlertDialogBuilder;
 
-import butterknife.BindView;
-import butterknife.OnClick;
-import butterknife.OnEditorAction;
 import cx.ring.R;
-import cx.ring.dependencyinjection.JamiInjectionComponent;
+import cx.ring.application.JamiApplication;
+import cx.ring.databinding.FragAccSipCreateBinding;
 import cx.ring.mvp.BaseSupportFragment;
 import cx.ring.mvp.SIPCreationView;
 import cx.ring.wizard.SIPCreationPresenter;
 
 public class SIPAccountCreationFragment extends BaseSupportFragment<SIPCreationPresenter> implements SIPCreationView {
-
     public static final String TAG = SIPAccountCreationFragment.class.getSimpleName();
 
-    @BindView(R.id.alias)
-    protected EditText mAliasView;
-
-    @BindView(R.id.hostname)
-    protected EditText mHostnameView;
-
-    @BindView(R.id.username)
-    protected EditText mUsernameView;
-
-    @BindView(R.id.password)
-    protected EditText mPasswordView;
-
-    @BindView(R.id.create_sip_button)
-    protected Button mCreateSIPAccountButton;
-
     private ProgressDialog mProgress = null;
+    private FragAccSipCreateBinding binding = null;
 
+    @Nullable
     @Override
-    public int getLayout() {
-        return R.layout.frag_acc_sip_create;
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+        binding = FragAccSipCreateBinding.inflate(inflater, container, false);
+        ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
+        return binding.getRoot();
     }
 
     @Override
-    public void injectFragment(JamiInjectionComponent component) {
-        component.inject(this);
+    public void onDestroyView() {
+        super.onDestroyView();
+        binding = null;
     }
 
-    @OnEditorAction(R.id.password)
-    public boolean keyPressedOnPasswordField(TextView v, int actionId, KeyEvent event) {
-        if (actionId == EditorInfo.IME_ACTION_DONE) {
-            mCreateSIPAccountButton.callOnClick();
-        }
-        return false;
-    }
-
-    /************************
-     * SIP Account ADD
-     ***********************/
-    @OnClick(R.id.create_sip_button)
-    public void createSIPAccount() {
-        createSIPAccount(false);
+    @Override
+    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+        binding.password.setOnEditorActionListener((v, actionId, event) -> {
+            if (actionId == EditorInfo.IME_ACTION_DONE) {
+                binding.createSipButton.callOnClick();
+            }
+            return false;
+        });
+        binding.createSipButton.setOnClickListener(v -> createSIPAccount(false));
     }
 
     /**
@@ -98,17 +84,17 @@
         //orientation is locked during the create of account to avoid the destruction of the thread
         getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
 
-        String alias = mAliasView.getText().toString();
-        String hostname = mHostnameView.getText().toString();
-        String username = mUsernameView.getText().toString();
-        String password = mPasswordView.getText().toString();
+        String alias = binding.alias.getText().toString();
+        String hostname = binding.hostname.getText().toString();
+        String username = binding.username.getText().toString();
+        String password = binding.password.getText().toString();
         presenter.startCreation(alias, hostname, username, password, bypassWarnings);
     }
 
     @Override
     public void showUsernameError() {
-        mUsernameView.setError(getString(R.string.error_field_required));
-        mUsernameView.requestFocus();
+        binding.username.setError(getString(R.string.error_field_required));
+        binding.username.requestFocus();
     }
 
     @Override
@@ -123,20 +109,20 @@
 
     @Override
     public void resetErrors() {
-        mAliasView.setError(null);
-        mPasswordView.setError(null);
+        binding.alias.setError(null);
+        binding.password.setError(null);
     }
 
     @Override
     public void showAliasError() {
-        mAliasView.setError(getString(R.string.error_field_required));
-        mAliasView.requestFocus();
+        binding.alias.setError(getString(R.string.error_field_required));
+        binding.alias.requestFocus();
     }
 
     @Override
     public void showPasswordError() {
-        mPasswordView.setError(getString(R.string.error_field_required));
-        mPasswordView.requestFocus();
+        binding.password.setError(getString(R.string.error_field_required));
+        binding.password.requestFocus();
     }
 
     @Override
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/SecurityAccountFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/SecurityAccountFragment.java
index ab6cdd5..ee1c375 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/SecurityAccountFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/SecurityAccountFragment.java
@@ -100,7 +100,7 @@
     @Override
     public void onCreatePreferences(Bundle bundle, String s) {
         // dependency injection
-        ((JamiApplication) getActivity().getApplication()).getRingInjectionComponent().inject(this);
+        ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
         super.onCreatePreferences(bundle, s);
 
         addPreferencesFromResource(R.xml.account_security_prefs);
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/ShareWithFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/ShareWithFragment.java
index 77047de..863783b 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/ShareWithFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/ShareWithFragment.java
@@ -32,7 +32,6 @@
 import androidx.recyclerview.widget.RecyclerView;
 import androidx.appcompat.widget.Toolbar;
 
-import android.text.TextUtils;
 import android.util.Log;
 import android.view.InflateException;
 import android.view.LayoutInflater;
@@ -83,7 +82,7 @@
      * fragment (e.g. upon screen orientation changes).
      */
     public ShareWithFragment() {
-        JamiApplication.getInstance().getRingInjectionComponent().inject(this);
+        JamiApplication.getInstance().getInjectionComponent().inject(this);
     }
 
     public static ShareWithFragment newInstance() {
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/SmartListFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/SmartListFragment.java
index 3cdb1da..61418c0 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/SmartListFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/SmartListFragment.java
@@ -35,7 +35,6 @@
 import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton;
 import com.google.android.material.snackbar.Snackbar;
 
-import androidx.coordinatorlayout.widget.CoordinatorLayout;
 import androidx.recyclerview.widget.DefaultItemAnimator;
 import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
@@ -45,6 +44,7 @@
 import android.os.Handler;
 import android.text.InputType;
 import android.util.Log;
+import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
@@ -53,7 +53,6 @@
 import android.view.inputmethod.EditorInfo;
 import android.widget.EditText;
 import android.widget.ImageView;
-import android.widget.ProgressBar;
 import android.widget.RelativeLayout;
 import android.widget.TextView;
 
@@ -61,16 +60,15 @@
 
 import javax.inject.Inject;
 
-import butterknife.BindView;
-import butterknife.OnClick;
 import cx.ring.R;
 import cx.ring.adapters.SmartListAdapter;
+import cx.ring.application.JamiApplication;
 import cx.ring.client.CallActivity;
 import cx.ring.client.ConversationActivity;
 import cx.ring.client.HomeActivity;
 import cx.ring.client.QRCodeActivity;
 import cx.ring.contacts.AvatarFactory;
-import cx.ring.dependencyinjection.JamiInjectionComponent;
+import cx.ring.databinding.FragSmartlistBinding;
 import cx.ring.model.CallContact;
 import cx.ring.model.Conversation;
 import cx.ring.mvp.BaseSupportFragment;
@@ -96,24 +94,6 @@
 
     private static final int SCROLL_DIRECTION_UP = -1;
 
-    @BindView(R.id.list_coordinator)
-    protected CoordinatorLayout mCoordinator;
-
-    @BindView(R.id.newconv_fab)
-    protected ExtendedFloatingActionButton mFloatingActionButton;
-
-    @BindView(R.id.confs_list)
-    protected RecyclerView mRecyclerView;
-
-    @BindView(R.id.loading_indicator)
-    protected ProgressBar mLoader;
-
-    @BindView(R.id.empty_text_view)
-    protected TextView mEmptyTextView;
-
-    @BindView(R.id.newcontact_element)
-    protected ViewGroup mNewContact;
-
     @Inject
     AccountService mAccountService;
 
@@ -122,6 +102,7 @@
     private SearchView mSearchView = null;
     private MenuItem mSearchMenuItem = null;
     private MenuItem mDialpadMenuItem = null;
+    private FragSmartlistBinding binding;
 
     @Override
     public void onResume() {
@@ -140,7 +121,7 @@
             @Override
             public boolean onMenuItemActionCollapse(MenuItem item) {
                 mDialpadMenuItem.setVisible(false);
-                mFloatingActionButton.show();
+                binding.newconvFab.show();
                 setOverflowMenuVisible(menu, true);
                 changeSeparatorHeight(false);
                 return true;
@@ -149,7 +130,7 @@
             @Override
             public boolean onMenuItemActionExpand(MenuItem item) {
                 mDialpadMenuItem.setVisible(true);
-                mFloatingActionButton.hide();
+                binding.newconvFab.hide();
                 setOverflowMenuVisible(menu, false);
                 changeSeparatorHeight(true);
                 return true;
@@ -238,11 +219,10 @@
 
     @Override
     public void onSaveInstanceState(@NonNull Bundle outState) {
-        if (null != mLoader) {
-            // if there's another fragment on top of this one, when a rotation is done, this fragment is destroyed and
-            // in the process of recreating it, as it is not shown on the top of the screen, the "onCreateView" method is never called, so the mLoader is null
-            outState.putBoolean(STATE_LOADING, mLoader.isShown());
-        }
+        // if there's another fragment on top of this one, when a rotation is done, this fragment is destroyed and
+        // in the process of recreating it, as it is not shown on the top of the screen, the "onCreateView" method is never called, so the mLoader is null
+        if (binding != null)
+            outState.putBoolean(STATE_LOADING, binding.loadingIndicator.isShown());
         super.onSaveInstanceState(outState);
     }
 
@@ -252,14 +232,18 @@
         return true;
     }
 
+    @Nullable
     @Override
-    public int getLayout() {
-        return R.layout.frag_smartlist;
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+        binding = FragSmartlistBinding.inflate(inflater, container, false);
+        ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
+        return binding.getRoot();
     }
 
     @Override
-    public void injectFragment(JamiInjectionComponent component) {
-        component.inject(this);
+    public void onDestroyView() {
+        super.onDestroyView();
+        binding = null;
     }
 
     @Override
@@ -267,9 +251,9 @@
         setHasOptionsMenu(true);
         super.onViewCreated(view, savedInstanceState);
 
-        mNewContact.setVisibility(View.GONE);
+        binding.newcontactElement.setVisibility(View.GONE);
 
-        mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
+        binding.confsList.addOnScrollListener(new RecyclerView.OnScrollListener() {
             @Override
             public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                 super.onScrollStateChanged(recyclerView, newState);
@@ -278,14 +262,12 @@
             @Override
             public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                 boolean canScrollUp = recyclerView.canScrollVertically(SCROLL_DIRECTION_UP);
-                ExtendedFloatingActionButton btn = mFloatingActionButton;
-                if (btn != null) {
-                    boolean isExtended = btn.isExtended();
-                    if (dy > 0 && isExtended) {
-                        btn.shrink();
-                    } else if ((dy < 0 || !canScrollUp) && !isExtended) {
-                        btn.extend();
-                    }
+                ExtendedFloatingActionButton btn = binding.newconvFab;
+                boolean isExtended = btn.isExtended();
+                if (dy > 0 && isExtended) {
+                    btn.shrink();
+                } else if ((dy < 0 || !canScrollUp) && !isExtended) {
+                    btn.extend();
                 }
 
                 HomeActivity activity = (HomeActivity) getActivity();
@@ -294,33 +276,19 @@
             }
         });
 
-        DefaultItemAnimator animator = (DefaultItemAnimator) mRecyclerView.getItemAnimator();
+        DefaultItemAnimator animator = (DefaultItemAnimator) binding.confsList.getItemAnimator();
         if (animator != null) {
             animator.setSupportsChangeAnimations(false);
         }
-    }
 
-    @OnClick(R.id.newcontact_element)
-    void newContactClicked() {
-        presenter.newContactClicked();
-    }
-
-    @OnClick(R.id.quick_call)
-    void quickCallClicked() {
-        presenter.quickCallClicked();
-    }
-
-    @OnClick(R.id.newconv_fab)
-    void fabButtonClicked() {
-        presenter.fabButtonClicked();
+        binding.newcontactElement.setOnClickListener(v -> presenter.newContactClicked());
+        //binding.quickCall.setOnClickListener(v -> presenter.quickCallClicked());
+        binding.newconvFab.setOnClickListener(v -> presenter.fabButtonClicked());
     }
 
     @Override
     public void setLoading(final boolean loading) {
-        if (mLoader == null) {
-            return;
-        }
-        mLoader.setVisibility(loading ? View.VISIBLE : View.GONE);
+        binding.loadingIndicator.setVisibility(loading ? View.VISIBLE : View.GONE);
     }
 
     /**
@@ -355,11 +323,9 @@
 
     @Override
     public void clipBoardDidCopyNumber(String copiedNumber) {
-        if (mCoordinator != null) {
-            String snackbarText = getString(R.string.conversation_action_copied_peer_number_clipboard,
-                    ActionHelper.getShortenedNumber(copiedNumber));
-            Snackbar.make(mCoordinator, snackbarText, Snackbar.LENGTH_LONG).show();
-        }
+        String snackbarText = getString(R.string.conversation_action_copied_peer_number_clipboard,
+                ActionHelper.getShortenedNumber(copiedNumber));
+        Snackbar.make(binding.listCoordinator, snackbarText, Snackbar.LENGTH_LONG).show();
     }
 
     public void onFabButtonClicked() {
@@ -368,17 +334,13 @@
 
     @Override
     public void displayContact(final CallContact contact) {
-        if (mNewContact == null) {
-            return;
-        }
-
-        TextView display_name = mNewContact.findViewById(R.id.display_name);
+        TextView display_name = binding.newcontactElement.findViewById(R.id.display_name);
         display_name.setText(contact.getRingUsername());
 
-        ImageView photo = mNewContact.findViewById(R.id.photo);
+        ImageView photo = binding.newcontactElement.findViewById(R.id.photo);
 
         AvatarFactory.loadGlideAvatar(photo, contact);
-        mNewContact.setVisibility(View.VISIBLE);
+        binding.newcontactElement.setVisibility(View.VISIBLE);
     }
 
     @Override
@@ -399,8 +361,8 @@
     @Override
     public void displayNoConversationMessage() {
         String emptyText = getResources().getQuantityString(R.plurals.home_conferences_title, 0, 0);
-        mEmptyTextView.setText(emptyText);
-        mEmptyTextView.setVisibility(View.VISIBLE);
+        binding.emptyTextView.setText(emptyText);
+        binding.emptyTextView.setVisibility(View.VISIBLE);
     }
 
     @Override
@@ -449,38 +411,35 @@
 
     @Override
     public void hideSearchRow() {
-        if (mNewContact == null) {
-            return;
-        }
-        mNewContact.setVisibility(View.GONE);
+        binding.newcontactElement.setVisibility(View.GONE);
     }
 
 
     @Override
     public void hideList() {
-        mRecyclerView.setVisibility(View.GONE);
+        binding.confsList.setVisibility(View.GONE);
     }
 
     @Override
     public void hideNoConversationMessage() {
-        mEmptyTextView.setVisibility(View.GONE);
+        binding.emptyTextView.setVisibility(View.GONE);
     }
 
     @Override
     public void updateList(@Nullable final List<SmartListViewModel> smartListViewModels) {
-        if (mRecyclerView == null)
+        if (binding == null)
             return;
-        if (mRecyclerView.getAdapter() == null) {
+        if (binding.confsList.getAdapter() == null) {
             mSmartListAdapter = new SmartListAdapter(smartListViewModels, SmartListFragment.this);
-            mRecyclerView.setAdapter(mSmartListAdapter);
-            mRecyclerView.setHasFixedSize(true);
+            binding.confsList.setAdapter(mSmartListAdapter);
+            binding.confsList.setHasFixedSize(true);
             LinearLayoutManager llm = new LinearLayoutManager(getActivity());
             llm.setOrientation(RecyclerView.VERTICAL);
-            mRecyclerView.setLayoutManager(llm);
+            binding.confsList.setLayoutManager(llm);
         } else {
             mSmartListAdapter.update(smartListViewModels);
         }
-        mRecyclerView.setVisibility(View.VISIBLE);
+        binding.confsList.setVisibility(View.VISIBLE);
 
         View view = getView();
         if (view != null) {
@@ -553,8 +512,8 @@
 
     @Override
     public void scrollToTop() {
-        if (mRecyclerView != null)
-            mRecyclerView.scrollToPosition(0);
+        if (binding != null)
+            binding.confsList.scrollToPosition(0);
     }
 
     @Override
@@ -569,27 +528,25 @@
 
     private void changeSeparatorHeight(boolean open) {
         if (DeviceUtils.isTablet(getActivity())) {
-            int margin;
+            int margin = 0;
 
-            View separator = getView().findViewById(R.id.separator);
-            RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) separator.getLayoutParams();
+            RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) binding.separator.getLayoutParams();
             if (open) {
                 Toolbar toolbar = getActivity().findViewById(R.id.main_toolbar);
-                margin = toolbar.getHeight();
-            } else {
-                margin = 0;
+                if (toolbar != null)
+                    margin = toolbar.getHeight();
             }
 
             params.topMargin = margin;
-            separator.setLayoutParams(params);
+            binding.separator.setLayoutParams(params);
         }
     }
 
     private void selectFirstItem() {
         if (mSmartListAdapter != null && mSmartListAdapter.getItemCount() > 0) {
             new Handler().postDelayed(() -> {
-                if (mRecyclerView != null) {
-                    RecyclerView.ViewHolder holder = mRecyclerView.findViewHolderForAdapterPosition(0);
+                if (binding != null) {
+                    RecyclerView.ViewHolder holder = binding.confsList.findViewHolderForAdapterPosition(0);
                     if (holder != null)
                         holder.itemView.performClick();
                 }
diff --git a/ring-android/app/src/main/java/cx/ring/history/DatabaseHelper.java b/ring-android/app/src/main/java/cx/ring/history/DatabaseHelper.java
index 555ac63..9b950ae 100644
--- a/ring-android/app/src/main/java/cx/ring/history/DatabaseHelper.java
+++ b/ring-android/app/src/main/java/cx/ring/history/DatabaseHelper.java
@@ -65,7 +65,7 @@
     public DatabaseHelper(Context context, String dbDirectory) {
         super(context, dbDirectory, null, DATABASE_VERSION);
         Log.d(TAG, "Helper initialized for " + dbDirectory);
-        ((JamiApplication) context.getApplicationContext()).getRingInjectionComponent().inject(this);
+        ((JamiApplication) context.getApplicationContext()).getInjectionComponent().inject(this);
     }
 
     /**
diff --git a/ring-android/app/src/main/java/cx/ring/launch/LaunchActivity.java b/ring-android/app/src/main/java/cx/ring/launch/LaunchActivity.java
index c70976d..e94d914 100644
--- a/ring-android/app/src/main/java/cx/ring/launch/LaunchActivity.java
+++ b/ring-android/app/src/main/java/cx/ring/launch/LaunchActivity.java
@@ -40,7 +40,7 @@
     @Override
     public void onCreate(Bundle savedInstanceState) {
         // dependency injection
-        JamiApplication.getInstance().getRingInjectionComponent().inject(this);
+        JamiApplication.getInstance().getInjectionComponent().inject(this);
         super.onCreate(savedInstanceState);
         JamiApplication.getInstance().startDaemon();
 
diff --git a/ring-android/app/src/main/java/cx/ring/mvp/BaseFragment.java b/ring-android/app/src/main/java/cx/ring/mvp/BaseFragment.java
index de3634d..b4cbf93 100644
--- a/ring-android/app/src/main/java/cx/ring/mvp/BaseFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/mvp/BaseFragment.java
@@ -22,20 +22,12 @@
 import android.app.Fragment;
 import android.os.Bundle;
 
-import androidx.annotation.LayoutRes;
-import androidx.annotation.Nullable;
-import android.view.LayoutInflater;
 import android.view.View;
-import android.view.ViewGroup;
 import android.widget.Toast;
 
 import javax.inject.Inject;
 
-import butterknife.ButterKnife;
-import butterknife.Unbinder;
 import cx.ring.R;
-import cx.ring.application.JamiApplication;
-import cx.ring.dependencyinjection.JamiInjectionComponent;
 import cx.ring.model.Error;
 
 public abstract class BaseFragment<T extends RootPresenter> extends Fragment implements BaseView {
@@ -45,24 +37,6 @@
     @Inject
     protected T presenter;
 
-    private Unbinder mUnbinder;
-
-    @LayoutRes
-    public abstract int getLayout();
-
-    public abstract void injectFragment(JamiInjectionComponent component);
-
-    @Nullable
-    @Override
-    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
-        final View inflatedView = inflater.inflate(getLayout(), container, false);
-        // dependency injection
-        injectFragment(((JamiApplication) getActivity().getApplication()).getRingInjectionComponent());
-        //Butterknife
-        mUnbinder = ButterKnife.bind(this, inflatedView);
-        return inflatedView;
-    }
-
     @Override
     public void onViewCreated(View view, Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
@@ -76,11 +50,6 @@
     public void onDestroyView() {
         super.onDestroyView();
         presenter.unbindView();
-        // Butterknife unbinding
-        if (mUnbinder != null) {
-            mUnbinder.unbind();
-            mUnbinder = null;
-        }
     }
 
     public void displayErrorToast(Error error) {
diff --git a/ring-android/app/src/main/java/cx/ring/mvp/BaseSupportFragment.java b/ring-android/app/src/main/java/cx/ring/mvp/BaseSupportFragment.java
index 928c668..9e78028 100644
--- a/ring-android/app/src/main/java/cx/ring/mvp/BaseSupportFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/mvp/BaseSupportFragment.java
@@ -20,24 +20,16 @@
 package cx.ring.mvp;
 
 import android.os.Bundle;
-import android.view.LayoutInflater;
 import android.view.View;
-import android.view.ViewGroup;
 import android.widget.Toast;
 
 import javax.inject.Inject;
 
 import androidx.annotation.IdRes;
-import androidx.annotation.LayoutRes;
 import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
 import androidx.fragment.app.Fragment;
-import butterknife.ButterKnife;
-import butterknife.Unbinder;
 import cx.ring.R;
 import cx.ring.account.JamiAccountCreationFragment;
-import cx.ring.application.JamiApplication;
-import cx.ring.dependencyinjection.JamiInjectionComponent;
 import cx.ring.model.Error;
 
 public abstract class BaseSupportFragment<T extends RootPresenter> extends Fragment implements BaseView {
@@ -47,28 +39,8 @@
     @Inject
     protected T presenter;
 
-    private Unbinder mUnbinder;
-
-    @LayoutRes
-    public abstract int getLayout();
-
-    public abstract void injectFragment(JamiInjectionComponent component);
-
-    @Nullable
-    @Override
-    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
-        final View inflatedView = inflater.inflate(getLayout(), container, false);
-        // dependency injection
-        injectFragment(((JamiApplication) getActivity().getApplication()).getRingInjectionComponent());
-        //Butterknife
-        mUnbinder = ButterKnife.bind(this, inflatedView);
-        return inflatedView;
-    }
-
     @Override
     public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
-        super.onViewCreated(view, savedInstanceState);
-
         //Be sure to do the injection in onCreateView method
         if (presenter != null) {
             presenter.bindView(this);
@@ -81,10 +53,6 @@
         super.onDestroyView();
         if (presenter != null)
             presenter.unbindView();
-        // Butterknife unbinding
-        if (mUnbinder != null) {
-            mUnbinder.unbind();
-        }
     }
 
     public void displayErrorToast(Error error) {
diff --git a/ring-android/app/src/main/java/cx/ring/service/BootReceiver.java b/ring-android/app/src/main/java/cx/ring/service/BootReceiver.java
index 08ba0bf..6e0207a 100644
--- a/ring-android/app/src/main/java/cx/ring/service/BootReceiver.java
+++ b/ring-android/app/src/main/java/cx/ring/service/BootReceiver.java
@@ -42,7 +42,7 @@
         final String action = intent.getAction();
         if (Intent.ACTION_BOOT_COMPLETED.equals(action) || Intent.ACTION_REBOOT.equals(action)) {
             try {
-                ((JamiApplication) context.getApplicationContext()).getRingInjectionComponent().inject(this);
+                ((JamiApplication) context.getApplicationContext()).getInjectionComponent().inject(this);
                 boolean isAllowRingOnStartup = mPreferencesService.getSettings().isAllowRingOnStartup();
 
                 if (isAllowRingOnStartup) {
diff --git a/ring-android/app/src/main/java/cx/ring/service/CallNotificationService.java b/ring-android/app/src/main/java/cx/ring/service/CallNotificationService.java
index e4e1b2e..bfdb470 100644
--- a/ring-android/app/src/main/java/cx/ring/service/CallNotificationService.java
+++ b/ring-android/app/src/main/java/cx/ring/service/CallNotificationService.java
@@ -65,7 +65,7 @@
 
     @Override
     public void onCreate() {
-        ((JamiApplication) getApplication()).getRingInjectionComponent().inject(this);
+        ((JamiApplication) getApplication()).getInjectionComponent().inject(this);
         notificationManager = NotificationManagerCompat.from(this);
         super.onCreate();
     }
diff --git a/ring-android/app/src/main/java/cx/ring/service/DRingService.java b/ring-android/app/src/main/java/cx/ring/service/DRingService.java
index 3d71e8b..281d276 100644
--- a/ring-android/app/src/main/java/cx/ring/service/DRingService.java
+++ b/ring-android/app/src/main/java/cx/ring/service/DRingService.java
@@ -49,13 +49,10 @@
 import java.io.File;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.ScheduledExecutorService;
 
 import javax.inject.Inject;
-import javax.inject.Named;
 import javax.inject.Singleton;
 
 import cx.ring.BuildConfig;
@@ -63,7 +60,6 @@
 import cx.ring.client.CallActivity;
 import cx.ring.client.ConversationActivity;
 import cx.ring.facades.ConversationFacade;
-import cx.ring.fragments.ConversationFragment;
 import cx.ring.model.Codec;
 import cx.ring.model.Settings;
 import cx.ring.model.Uri;
@@ -554,7 +550,7 @@
         super.onCreate();
 
         // dependency injection
-        JamiApplication.getInstance().getRingInjectionComponent().inject(this);
+        JamiApplication.getInstance().getInjectionComponent().inject(this);
         isRunning = true;
 
         if (mDeviceRuntimeService.hasContactPermission()) {
diff --git a/ring-android/app/src/main/java/cx/ring/services/DataTransferService.java b/ring-android/app/src/main/java/cx/ring/services/DataTransferService.java
index 1205531..573bdbd 100644
--- a/ring-android/app/src/main/java/cx/ring/services/DataTransferService.java
+++ b/ring-android/app/src/main/java/cx/ring/services/DataTransferService.java
@@ -84,7 +84,7 @@
     @Override
     public void onCreate() {
         Log.d(TAG, "OnCreate(), Service has been initialized");
-        ((JamiApplication) getApplication()).getRingInjectionComponent().inject(this);
+        ((JamiApplication) getApplication()).getInjectionComponent().inject(this);
         notificationManager = NotificationManagerCompat.from(this);
         super.onCreate();
     }
diff --git a/ring-android/app/src/main/java/cx/ring/services/JamiChooserTargetService.java b/ring-android/app/src/main/java/cx/ring/services/JamiChooserTargetService.java
index 337523c..7c93589 100644
--- a/ring-android/app/src/main/java/cx/ring/services/JamiChooserTargetService.java
+++ b/ring-android/app/src/main/java/cx/ring/services/JamiChooserTargetService.java
@@ -58,7 +58,7 @@
     public void onCreate() {
         super.onCreate();
         JamiApplication.getInstance().startDaemon();
-        JamiApplication.getInstance().getRingInjectionComponent().inject(this);
+        JamiApplication.getInstance().getInjectionComponent().inject(this);
         targetSize = (int) (AvatarFactory.SIZE_NOTIF * getResources().getDisplayMetrics().density);
     }
 
diff --git a/ring-android/app/src/main/java/cx/ring/services/LocationSharingService.java b/ring-android/app/src/main/java/cx/ring/services/LocationSharingService.java
index f504f81..a8e4b89 100644
--- a/ring-android/app/src/main/java/cx/ring/services/LocationSharingService.java
+++ b/ring-android/app/src/main/java/cx/ring/services/LocationSharingService.java
@@ -129,7 +129,7 @@
 
     @Override
     public void onCreate() {
-        ((JamiApplication) getApplication()).getRingInjectionComponent().inject(this);
+        ((JamiApplication) getApplication()).getInjectionComponent().inject(this);
 
         mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
         mNoticationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
diff --git a/ring-android/app/src/main/java/cx/ring/settings/SettingsFragment.java b/ring-android/app/src/main/java/cx/ring/settings/SettingsFragment.java
index 9fff9d7..d24ffc6 100644
--- a/ring-android/app/src/main/java/cx/ring/settings/SettingsFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/settings/SettingsFragment.java
@@ -23,6 +23,7 @@
 import android.graphics.Typeface;
 import android.os.Bundle;
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.appcompat.widget.Toolbar;
 import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentManager;
@@ -31,6 +32,7 @@
 import com.google.android.material.snackbar.Snackbar;
 
 import android.text.TextUtils;
+import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.View;
@@ -39,22 +41,17 @@
 import android.widget.CompoundButton;
 import android.widget.ImageView;
 import android.widget.RelativeLayout;
-import android.widget.Switch;
 import android.widget.TextView;
 import android.widget.Toast;
 
-import butterknife.BindView;
-import butterknife.OnCheckedChanged;
-import butterknife.OnClick;
 import cx.ring.R;
 import cx.ring.application.JamiApplication;
 import cx.ring.client.HomeActivity;
-import cx.ring.dependencyinjection.JamiInjectionComponent;
+import cx.ring.databinding.FragSettingsBinding;
 import cx.ring.model.Settings;
 import cx.ring.mvp.BaseSupportFragment;
 import cx.ring.mvp.GenericView;
 import cx.ring.utils.DeviceUtils;
-import cx.ring.views.BoundedScrollView;
 
 /**
  * TODO: improvements : handle multiples permissions for feature.
@@ -63,40 +60,31 @@
 
     private static final int SCROLL_DIRECTION_UP = -1;
 
-    @BindView(R.id.settings_push_notifications_layout)
-    ViewGroup mGroupPushNotifications;
-    @BindView(R.id.settings_push_notifications)
-    Switch mViewPushNotifications;
-    @BindView(R.id.settings_startup)
-    Switch mViewStartup;
-    @BindView(R.id.settings_persistNotification)
-    Switch mViewPersistNotif;
-    @BindView(R.id.settings_video_layout)
-    View settings_video_layout;
-    @BindView(R.id.settings_dark_theme)
-    Switch mDarkTheme;
-    @BindView(R.id.scrollview)
-    BoundedScrollView mScrollView;
+    private FragSettingsBinding binding;
 
     private boolean mIsRefreshingViewFromPresenter;
 
+    @Nullable
     @Override
-    public int getLayout() {
-        return R.layout.frag_settings;
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+        binding = FragSettingsBinding.inflate(inflater, container, false);
+        ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
+        return binding.getRoot();
     }
 
     @Override
-    public void injectFragment(JamiInjectionComponent component) {
-        component.inject(this);
+    public void onDestroyView() {
+        super.onDestroyView();
+        binding = null;
     }
 
     @Override
     public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
         setHasOptionsMenu(true);
         super.onViewCreated(view, savedInstanceState);
-        mDarkTheme.setChecked(presenter.getDarkMode());
+        binding.settingsDarkTheme.setChecked(presenter.getDarkMode());
         if (TextUtils.isEmpty(JamiApplication.getInstance().getPushToken())) {
-            mGroupPushNotifications.setVisibility(View.GONE);
+            binding.settingsPushNotificationsLayout.setVisibility(View.GONE);
         }
         // loading preferences
         presenter.loadSettings();
@@ -118,13 +106,43 @@
             ((HomeActivity) getActivity()).setToolbarState(R.string.menu_item_settings);
         }
 
-        mScrollView.getViewTreeObserver().addOnScrollChangedListener(this);
+        binding.scrollview.getViewTreeObserver().addOnScrollChangedListener(this);
+        binding.settingsDarkTheme.setOnCheckedChangeListener((buttonView, isChecked) -> presenter.setDarkMode(isChecked));
+
+        CompoundButton.OnCheckedChangeListener save = (buttonView, isChecked) -> {
+            if (!mIsRefreshingViewFromPresenter)
+                saveSettings();
+        };
+        binding.settingsPushNotifications.setOnCheckedChangeListener(save);
+        binding.settingsStartup.setOnCheckedChangeListener(save);
+        binding.settingsPersistNotification.setOnCheckedChangeListener(save);
+
+        binding.settingsVideoLayout.setOnClickListener(v -> {
+            HomeActivity activity = (HomeActivity) getActivity();
+            if (activity != null)
+                activity.goToVideoSettings();
+        });
+
+        binding.settingsClearHistory.setOnClickListener(v -> new MaterialAlertDialogBuilder(view.getContext())
+                .setTitle(getString(R.string.clear_history_dialog_title))
+                .setMessage(getString(R.string.clear_history_dialog_message))
+                .setPositiveButton(android.R.string.ok, (dialog, id) -> {
+                    // ask the presenter to clear history
+                    presenter.clearHistory();
+                    Snackbar.make(view,
+                            getString(R.string.clear_history_completed),
+                            Snackbar.LENGTH_SHORT).show();
+                })
+                .setNegativeButton(android.R.string.cancel, (dialog, id) -> {
+                    //~ Empty
+                })
+                .show());
     }
 
     @Override
     public void onResume() {
         super.onResume();
-        FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
+        FragmentManager fragmentManager = requireFragmentManager();
         Fragment existingFragment = fragmentManager.findFragmentByTag(SettingsFragment.TAG);
         if (existingFragment == null) {
             ((HomeActivity) getActivity()).goToSettings();
@@ -132,7 +150,7 @@
     }
 
     @Override
-    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+    public void onCreateOptionsMenu(Menu menu, @NonNull MenuInflater inflater) {
         menu.clear();
     }
 
@@ -141,58 +159,16 @@
         menu.clear();
     }
 
-    @OnCheckedChanged(R.id.settings_dark_theme)
-    public void onDarkThemeChanged(CompoundButton button, boolean isChecked) {
-        presenter.setDarkMode(isChecked);
-    }
-
-    @OnCheckedChanged({
-        R.id.settings_push_notifications,
-        R.id.settings_startup,
-        R.id.settings_persistNotification
-    })
-    public void onSettingsCheckedChanged(CompoundButton button, boolean isChecked) {
-        if (!mIsRefreshingViewFromPresenter)
-            saveSettings();
-    }
-
     private void saveSettings() {
         Settings newSettings = new Settings();
-
-        newSettings.setAllowRingOnStartup(mViewStartup.isChecked());
-        newSettings.setAllowPushNotifications(mViewPushNotifications.isChecked());
-        newSettings.setAllowPersistentNotification(mViewPersistNotif.isChecked());
+        newSettings.setAllowRingOnStartup(binding.settingsStartup.isChecked());
+        newSettings.setAllowPushNotifications(binding.settingsPushNotifications.isChecked());
+        newSettings.setAllowPersistentNotification(binding.settingsPersistNotification.isChecked());
 
         // save settings according to UI inputs
         presenter.saveSettings(newSettings);
     }
 
-    @OnClick(R.id.settings_video_layout)
-    void onVideoClick() {
-        HomeActivity activity = (HomeActivity) getActivity();
-        if (activity != null) {
-            activity.goToVideoSettings();
-        }
-    }
-
-    @OnClick(R.id.settings_clear_history)
-    public void onClearHistoryClick() {
-        new MaterialAlertDialogBuilder(getActivity())
-                .setTitle(getString(R.string.clear_history_dialog_title))
-                .setMessage(getString(R.string.clear_history_dialog_message))
-                .setPositiveButton(android.R.string.ok, (dialog, id) -> {
-                    // ask the presenter to clear history
-                    presenter.clearHistory();
-                    Snackbar.make(getView(),
-                            getString(R.string.clear_history_completed),
-                            Snackbar.LENGTH_SHORT).show();
-                })
-                .setNegativeButton(android.R.string.cancel, (dialog, id) -> {
-                    //~ Empty
-                })
-                .show();
-    }
-
     /**
      * Presents a Toast explaining why the Read Contacts permission is required to display the devi-
      * ces contacts in Ring.
@@ -220,16 +196,18 @@
     @Override
     public void showViewModel(Settings viewModel) {
         mIsRefreshingViewFromPresenter = true;
-        mViewPushNotifications.setChecked(viewModel.isAllowPushNotifications());
-        mViewPersistNotif.setChecked(viewModel.isAllowPersistentNotification());
-        mViewStartup.setChecked(viewModel.isAllowRingOnStartup());
+        binding.settingsPushNotifications.setChecked(viewModel.isAllowPushNotifications());
+        binding.settingsPersistNotification.setChecked(viewModel.isAllowPersistentNotification());
+        binding.settingsStartup.setChecked(viewModel.isAllowRingOnStartup());
         mIsRefreshingViewFromPresenter = false;
     }
 
     @Override
     public void onScrollChanged() {
-        if (mScrollView != null) {
-            ((HomeActivity) getActivity()).setToolbarElevation(mScrollView.canScrollVertically(SCROLL_DIRECTION_UP));
+        if (binding != null) {
+            Activity activity = getActivity();
+            if (activity instanceof HomeActivity)
+                ((HomeActivity) activity).setToolbarElevation(binding.scrollview.canScrollVertically(SCROLL_DIRECTION_UP));
         }
     }
 
diff --git a/ring-android/app/src/main/java/cx/ring/share/ScanFragment.java b/ring-android/app/src/main/java/cx/ring/share/ScanFragment.java
index f8ed56c..7afc4c8 100644
--- a/ring-android/app/src/main/java/cx/ring/share/ScanFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/share/ScanFragment.java
@@ -52,7 +52,6 @@
 
 import cx.ring.R;
 import cx.ring.application.JamiApplication;
-import cx.ring.dependencyinjection.JamiInjectionComponent;
 import cx.ring.fragments.ConversationFragment;
 import cx.ring.mvp.BaseSupportFragment;
 
@@ -63,21 +62,12 @@
     private DecoratedBarcodeView barcodeView;
     private TextView mErrorMessageTextView;
 
-    @Override
-    public int getLayout() {
-        return R.layout.frag_scan;
-    }
-
-    @Override
-    public void injectFragment(JamiInjectionComponent component) {
-    }
-
     private boolean hasCameraPermission() {
         return ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
     }
 
     @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
         View rootView = inflater.inflate(R.layout.frag_scan, container, false);
 
         barcodeView = rootView.findViewById(R.id.barcode_scanner);
@@ -153,7 +143,7 @@
         }
     }
 
-    public void displayNoPermissionsError() {
+    private void displayNoPermissionsError() {
         showErrorPanel(R.string.error_scan_no_camera_permissions);
     }
 
@@ -202,7 +192,7 @@
         }
     };
 
-    public void goToConversation(String contactId) {
+    private void goToConversation(String contactId) {
         Intent intent = new Intent().
                 putExtra(ConversationFragment.KEY_CONTACT_RING_ID, contactId);
         getActivity().setResult(Activity.RESULT_OK, intent);
diff --git a/ring-android/app/src/main/java/cx/ring/share/ShareFragment.java b/ring-android/app/src/main/java/cx/ring/share/ShareFragment.java
index 9079628..6e31bc7 100644
--- a/ring-android/app/src/main/java/cx/ring/share/ShareFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/share/ShareFragment.java
@@ -23,68 +23,54 @@
 import android.graphics.Bitmap;
 import android.os.Bundle;
 import android.text.TextUtils;
+import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
-import android.widget.Button;
-import android.widget.ImageView;
-import android.widget.TextView;
+import android.view.ViewGroup;
 
 import androidx.annotation.NonNull;
-import butterknife.BindString;
-import butterknife.BindView;
-import butterknife.OnClick;
+import androidx.annotation.Nullable;
+
 import cx.ring.R;
-import cx.ring.dependencyinjection.JamiInjectionComponent;
+import cx.ring.application.JamiApplication;
+import cx.ring.databinding.FragShareBinding;
 import cx.ring.mvp.BaseSupportFragment;
 import cx.ring.mvp.GenericView;
 import cx.ring.utils.QRCodeUtils;
 
 public class ShareFragment extends BaseSupportFragment<SharePresenter> implements GenericView<ShareViewModel> {
 
-    @BindView(R.id.share_instruction)
-    protected TextView mShareInstruction;
-
-    @BindView(R.id.qr_image)
-    protected ImageView mQrImage;
-
-    @BindString(R.string.share_message)
-    protected String mShareMessage;
-
-    @BindView(R.id.share_button)
-    protected Button mShareButton;
-
-    @BindString(R.string.share_message_no_account)
-    protected String mShareMessageNoAccount;
-
-    @BindString(R.string.account_contact_me)
-    protected String mAccountCountactMe;
-
-    @BindString(R.string.share_via)
-    protected String mShareVia;
-
     private String mUriToShow;
     private boolean isShareLocked = false;
+    private FragShareBinding binding;
 
+    @Nullable
     @Override
-    public int getLayout() {
-        return R.layout.frag_share;
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+        binding = FragShareBinding.inflate(inflater, container, false);
+        ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
+        return binding.getRoot();
     }
 
     @Override
-    public void injectFragment(JamiInjectionComponent component) {
-        component.inject(this);
+    public void onDestroyView() {
+        super.onDestroyView();
+        binding = null;
     }
 
     @Override
     public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
         setHasOptionsMenu(true);
+        binding.shareButton.setOnClickListener(v -> {
+            if (!isShareLocked) shareAccount();
+        });
     }
 
     @Override
-    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+    public void onCreateOptionsMenu(@NonNull Menu menu, MenuInflater inflater) {
         inflater.inflate(R.menu.qr_menu, menu);
     }
 
@@ -104,40 +90,31 @@
         }
     }
 
-    @OnClick(R.id.share_button)
-    void shareClicked(View view) {
-        if(!isShareLocked) {
-            shareAccount();
-        }
-    }
-
     private void shareAccount() {
         if (!TextUtils.isEmpty(mUriToShow)) {
             Intent sharingIntent = new Intent(Intent.ACTION_SEND);
             sharingIntent.setType("text/plain");
-            sharingIntent.putExtra(Intent.EXTRA_SUBJECT, mAccountCountactMe);
+            sharingIntent.putExtra(Intent.EXTRA_SUBJECT, getText(R.string.account_contact_me));
             sharingIntent.putExtra(Intent.EXTRA_TEXT, getString(R.string.account_share_body, mUriToShow, getText(R.string.app_website)));
-            startActivity(Intent.createChooser(sharingIntent, mShareVia));
+            startActivity(Intent.createChooser(sharingIntent, getText(R.string.share_via)));
         }
     }
 
     @Override
     public void showViewModel(final ShareViewModel viewModel) {
-        final QRCodeUtils.QRCodeData qrCodeData = viewModel.getAccountQRCodeData(0xFF000000, 0xFFFFFFFF);
-
-        if (mQrImage == null || mShareInstruction == null) {
+        if (binding == null)
             return;
-        }
 
+        final QRCodeUtils.QRCodeData qrCodeData = viewModel.getAccountQRCodeData(0xFF000000, 0xFFFFFFFF);
         if (qrCodeData == null) {
-            mQrImage.setVisibility(View.INVISIBLE);
-            mShareInstruction.setText(mShareMessageNoAccount);
+            binding.qrImage.setVisibility(View.INVISIBLE);
+            binding.shareInstruction.setText(R.string.share_message_no_account);
         } else {
             Bitmap bitmap = Bitmap.createBitmap(qrCodeData.getWidth(), qrCodeData.getHeight(), Bitmap.Config.ARGB_8888);
             bitmap.setPixels(qrCodeData.getData(), 0, qrCodeData.getWidth(), 0, 0, qrCodeData.getWidth(), qrCodeData.getHeight());
-            mQrImage.setImageBitmap(bitmap);
-            mShareInstruction.setText(mShareMessage);
-            mQrImage.setVisibility(View.VISIBLE);
+            binding.qrImage.setImageBitmap(bitmap);
+            binding.shareInstruction.setText(R.string.share_message);
+            binding.qrImage.setVisibility(View.VISIBLE);
         }
 
         mUriToShow = viewModel.getAccountDisplayUri();
diff --git a/ring-android/app/src/main/java/cx/ring/tv/about/AboutDetailsPresenter.java b/ring-android/app/src/main/java/cx/ring/tv/about/AboutDetailsPresenter.java
index ef7701c..51420db 100644
--- a/ring-android/app/src/main/java/cx/ring/tv/about/AboutDetailsPresenter.java
+++ b/ring-android/app/src/main/java/cx/ring/tv/about/AboutDetailsPresenter.java
@@ -20,21 +20,14 @@
 import android.content.Context;
 import androidx.leanback.widget.Presenter;
 import android.view.LayoutInflater;
-import android.view.View;
 import android.view.ViewGroup;
-import android.widget.TextView;
 
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import cx.ring.R;
+import cx.ring.databinding.DetailViewContentBinding;
 import cx.ring.tv.cards.iconcards.IconCard;
 
 public class AboutDetailsPresenter extends Presenter {
-    @BindView(R.id.primary_text)
-    TextView mPrimaryText;
-    @BindView(R.id.extra_text)
-    TextView mExtraText;
     private Context mContext;
+    private DetailViewContentBinding binding;
 
     public AboutDetailsPresenter(Context context) {
         mContext = context;
@@ -42,17 +35,15 @@
 
     @Override
     public ViewHolder onCreateViewHolder(ViewGroup parent) {
-        View view = LayoutInflater.from(mContext).inflate(R.layout.detail_view_content, null);
-        ButterKnife.bind(this, view);
-        return new ViewHolder(view);
+        binding = DetailViewContentBinding.inflate(LayoutInflater.from(mContext));
+        return new ViewHolder(binding.getRoot());
     }
 
     @Override
     public void onBindViewHolder(ViewHolder viewHolder, Object itemData) {
         IconCard card = (IconCard) itemData;
-
-        mPrimaryText.setText(card.getTitle());
-        mExtraText.setText(card.getDescription());
+        binding.primaryText.setText(card.getTitle());
+        binding.extraText.setText(card.getDescription());
     }
 
     @Override
diff --git a/ring-android/app/src/main/java/cx/ring/tv/account/TVAccountExport.java b/ring-android/app/src/main/java/cx/ring/tv/account/TVAccountExport.java
index a44d6d4..8b176e9 100644
--- a/ring-android/app/src/main/java/cx/ring/tv/account/TVAccountExport.java
+++ b/ring-android/app/src/main/java/cx/ring/tv/account/TVAccountExport.java
@@ -65,7 +65,7 @@
 
     @Override
     public void onViewCreated(View view, Bundle savedInstanceState) {
-        ((JamiApplication) getActivity().getApplication()).getRingInjectionComponent().inject(this);
+        ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
 
         super.onViewCreated(view, savedInstanceState);
         presenter.setAccountId(mIdAccount);
@@ -77,7 +77,7 @@
         String title = getString(R.string.account_export_title);
         String breadcrumb = "";
         String description = getString(R.string.account_link_export_info_light);
-        Drawable icon = getActivity().getResources().getDrawable(R.drawable.baseline_devices_24);
+        Drawable icon = getContext().getDrawable(R.drawable.baseline_devices_24);
         return new GuidanceStylist.Guidance(title, description, breadcrumb, icon);
     }
 
@@ -214,7 +214,7 @@
     }
 
     @Override
-    public void updateUserView() {
+    public void updateUserView(Account account) {
 
     }
 
diff --git a/ring-android/app/src/main/java/cx/ring/tv/account/TVAccountWizard.java b/ring-android/app/src/main/java/cx/ring/tv/account/TVAccountWizard.java
index 0f2a0cf..b9ceec3 100644
--- a/ring-android/app/src/main/java/cx/ring/tv/account/TVAccountWizard.java
+++ b/ring-android/app/src/main/java/cx/ring/tv/account/TVAccountWizard.java
@@ -22,7 +22,6 @@
 import android.app.FragmentManager;
 import android.app.ProgressDialog;
 import android.content.Intent;
-import android.content.pm.ActivityInfo;
 import android.os.Bundle;
 
 import androidx.leanback.app.GuidedStepSupportFragment;
@@ -32,7 +31,6 @@
 
 import java.io.File;
 
-import butterknife.ButterKnife;
 import cx.ring.R;
 import cx.ring.account.AccountCreationModelImpl;
 import cx.ring.account.AccountWizardPresenter;
@@ -42,7 +40,6 @@
 import cx.ring.model.AccountConfig;
 import cx.ring.mvp.AccountCreationModel;
 import cx.ring.mvp.BaseActivity;
-import cx.ring.tv.main.HomeActivity;
 import cx.ring.utils.VCardUtils;
 import ezvcard.VCard;
 import io.reactivex.Single;
@@ -61,9 +58,8 @@
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
-        JamiApplication.getInstance().getRingInjectionComponent().inject(this);
+        JamiApplication.getInstance().getInjectionComponent().inject(this);
         super.onCreate(savedInstanceState);
-        ButterKnife.bind(this);
         JamiApplication.getInstance().startDaemon();
 
         Intent intent = getIntent();
diff --git a/ring-android/app/src/main/java/cx/ring/tv/account/TVHomeAccountCreationFragment.java b/ring-android/app/src/main/java/cx/ring/tv/account/TVHomeAccountCreationFragment.java
index 1e364c3..3cb287b 100644
--- a/ring-android/app/src/main/java/cx/ring/tv/account/TVHomeAccountCreationFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/tv/account/TVHomeAccountCreationFragment.java
@@ -42,7 +42,7 @@
 
     @Override
     public void onViewCreated(View view, Bundle savedInstanceState) {
-        ((JamiApplication) getActivity().getApplication()).getRingInjectionComponent().inject(this);
+        ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
 
         super.onViewCreated(view, savedInstanceState);
     }
diff --git a/ring-android/app/src/main/java/cx/ring/tv/account/TVJamiAccountCreationFragment.java b/ring-android/app/src/main/java/cx/ring/tv/account/TVJamiAccountCreationFragment.java
index 5a8cd74..f544abd 100644
--- a/ring-android/app/src/main/java/cx/ring/tv/account/TVJamiAccountCreationFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/tv/account/TVJamiAccountCreationFragment.java
@@ -84,7 +84,7 @@
 
     @Override
     public void onViewCreated(View view, Bundle savedInstanceState) {
-        ((JamiApplication) getActivity().getApplication()).getRingInjectionComponent().inject(this);
+        ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
 
         // Bind the presenter to the view
         super.onViewCreated(view, savedInstanceState);
diff --git a/ring-android/app/src/main/java/cx/ring/tv/account/TVJamiLinkAccountFragment.java b/ring-android/app/src/main/java/cx/ring/tv/account/TVJamiLinkAccountFragment.java
index f3051c5..45d822c 100644
--- a/ring-android/app/src/main/java/cx/ring/tv/account/TVJamiLinkAccountFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/tv/account/TVJamiLinkAccountFragment.java
@@ -53,7 +53,7 @@
 
     @Override
     public void onViewCreated(View view, Bundle savedInstanceState) {
-        ((JamiApplication) getActivity().getApplication()).getRingInjectionComponent().inject(this);
+        ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
         super.onViewCreated(view, savedInstanceState);
 
         presenter.init(model);
diff --git a/ring-android/app/src/main/java/cx/ring/tv/account/TVProfileCreationFragment.java b/ring-android/app/src/main/java/cx/ring/tv/account/TVProfileCreationFragment.java
index 88efde7..4c86f3f 100644
--- a/ring-android/app/src/main/java/cx/ring/tv/account/TVProfileCreationFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/tv/account/TVProfileCreationFragment.java
@@ -119,7 +119,7 @@
 
     @Override
     public void onViewCreated(View view, Bundle savedInstanceState) {
-        ((JamiApplication) getActivity().getApplication()).getRingInjectionComponent().inject(this);
+        ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
         super.onViewCreated(view, savedInstanceState);
 
         if (mModel == null) {
diff --git a/ring-android/app/src/main/java/cx/ring/tv/account/TVProfileEditingFragment.java b/ring-android/app/src/main/java/cx/ring/tv/account/TVProfileEditingFragment.java
index af550c9..79216d7 100644
--- a/ring-android/app/src/main/java/cx/ring/tv/account/TVProfileEditingFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/tv/account/TVProfileEditingFragment.java
@@ -112,7 +112,7 @@
 
     @Override
     public void onViewCreated(View view, Bundle savedInstanceState) {
-        ((JamiApplication) getActivity().getApplication()).getRingInjectionComponent().inject(this);
+        ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
         super.onViewCreated(view, savedInstanceState);
         iconSize = (int) getResources().getDimension(R.dimen.tv_avatar_size);
     }
diff --git a/ring-android/app/src/main/java/cx/ring/tv/account/TVSettingsFragment.java b/ring-android/app/src/main/java/cx/ring/tv/account/TVSettingsFragment.java
index bf7b122..f211dd6 100644
--- a/ring-android/app/src/main/java/cx/ring/tv/account/TVSettingsFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/tv/account/TVSettingsFragment.java
@@ -71,7 +71,7 @@
 
         @Override
         public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
-            ((JamiApplication) getActivity().getApplication()).getRingInjectionComponent().inject(this);
+            ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
             super.onViewCreated(view, savedInstanceState);
             presenter.init();
         }
diff --git a/ring-android/app/src/main/java/cx/ring/tv/account/TVShareFragment.java b/ring-android/app/src/main/java/cx/ring/tv/account/TVShareFragment.java
index 2dafd65..4c2972f 100644
--- a/ring-android/app/src/main/java/cx/ring/tv/account/TVShareFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/tv/account/TVShareFragment.java
@@ -21,18 +21,18 @@
 
 import android.graphics.Bitmap;
 import android.os.Bundle;
+import android.view.LayoutInflater;
 import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
+import android.view.ViewGroup;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 
-import butterknife.BindString;
-import butterknife.BindView;
 import cx.ring.R;
-import cx.ring.dependencyinjection.JamiInjectionComponent;
+import cx.ring.application.JamiApplication;
+import cx.ring.databinding.TvFragShareBinding;
 import cx.ring.model.Account;
-import cx.ring.mvp.BaseFragment;
+import cx.ring.mvp.BaseSupportFragment;
 import cx.ring.mvp.GenericView;
 import cx.ring.services.VCardServiceImpl;
 import cx.ring.share.SharePresenter;
@@ -40,38 +40,32 @@
 import cx.ring.utils.Log;
 import cx.ring.utils.QRCodeUtils;
 import cx.ring.views.AvatarDrawable;
+import io.reactivex.disposables.CompositeDisposable;
 
-public class TVShareFragment extends BaseFragment<SharePresenter> implements GenericView<ShareViewModel> {
+public class TVShareFragment extends BaseSupportFragment<SharePresenter> implements GenericView<ShareViewModel> {
 
+    private TvFragShareBinding binding;
+    private final CompositeDisposable disposable = new CompositeDisposable();
 
-    @BindView(R.id.share_qr_instruction)
-    protected TextView mShareInstruction;
-
-    @BindView(R.id.qr_image)
-    protected ImageView mQrImage;
-
-    @BindString(R.string.share_message)
-    protected String mShareMessage;
-
-    @BindView(R.id.share_uri)
-    protected TextView mShareUri;
-
-    @BindView(R.id.qr_user_photo)
-    protected ImageView mUserPhoto;
-
+    @Nullable
     @Override
-    public int getLayout() {
-        return R.layout.tv_frag_share;
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+        binding = TvFragShareBinding.inflate(inflater, container, false);
+        ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
+        return binding.getRoot();
     }
 
     @Override
-    public void injectFragment(JamiInjectionComponent component) {
-        component.inject(this);
+    public void onDestroyView() {
+        super.onDestroyView();
+        binding = null;
+        disposable.clear();
     }
 
     @Override
-    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
-        super.onViewCreated(view, savedInstanceState);
+    public void onDestroy() {
+        super.onDestroy();
+        disposable.dispose();
     }
 
     @Override
@@ -79,37 +73,37 @@
         final QRCodeUtils.QRCodeData qrCodeData = viewModel.getAccountQRCodeData(0x00000000, 0xFFFFFFFF);
         getUserAvatar(viewModel.getAccount());
 
-        if (mQrImage == null || mShareInstruction == null || mShareUri == null) {
+        if (binding == null) {
             return;
         }
 
         if (qrCodeData == null) {
-            mQrImage.setVisibility(View.INVISIBLE);
+            binding.qrImage.setVisibility(View.INVISIBLE);
 
         } else {
             Bitmap bitmap = Bitmap.createBitmap(qrCodeData.getWidth(), qrCodeData.getHeight(), Bitmap.Config.ARGB_8888);
             bitmap.setPixels(qrCodeData.getData(), 0, qrCodeData.getWidth(), 0, 0, qrCodeData.getWidth(), qrCodeData.getHeight());
-            mQrImage.setImageBitmap(bitmap);
-            mShareInstruction.setText(mShareMessage);
-            mQrImage.setVisibility(View.VISIBLE);
+            binding.qrImage.setImageBitmap(bitmap);
+            binding.shareQrInstruction.setText(R.string.share_message);
+            binding.qrImage.setVisibility(View.VISIBLE);
         }
     }
 
     private void getUserAvatar(Account account) {
-        VCardServiceImpl
+        disposable.add(VCardServiceImpl
                 .loadProfile(account)
                 .doOnSuccess(profile -> {
-                    mShareUri.setVisibility(View.VISIBLE);
+                    binding.shareUri.setVisibility(View.VISIBLE);
                     if (profile.first != null && !profile.first.isEmpty()) {
-                        mShareUri.setText(profile.first);
+                        binding.shareUri.setText(profile.first);
                     } else {
-                        mShareUri.setText(account.getDisplayUri());
+                        binding.shareUri.setText(account.getDisplayUri());
                     }
                 })
                 .flatMap(p -> AvatarDrawable.load(getActivity(), account))
                 .subscribe(a -> {
-                    mUserPhoto.setVisibility(View.VISIBLE);
-                    mUserPhoto.setImageDrawable(a);
-                }, e-> Log.e(TAG, e.getMessage()));
+                    binding.qrUserPhoto.setVisibility(View.VISIBLE);
+                    binding.qrUserPhoto.setImageDrawable(a);
+                }, e-> Log.e(TAG, e.getMessage())));
     }
 }
diff --git a/ring-android/app/src/main/java/cx/ring/tv/call/TVCallActivity.java b/ring-android/app/src/main/java/cx/ring/tv/call/TVCallActivity.java
index 17f2b45..20f19ba 100644
--- a/ring-android/app/src/main/java/cx/ring/tv/call/TVCallActivity.java
+++ b/ring-android/app/src/main/java/cx/ring/tv/call/TVCallActivity.java
@@ -66,7 +66,7 @@
         setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
 
         // dependency injection
-        JamiApplication.getInstance().getRingInjectionComponent().inject(this);
+        JamiApplication.getInstance().getInjectionComponent().inject(this);
         JamiApplication.getInstance().startDaemon();
 
         boolean audioOnly = false;
diff --git a/ring-android/app/src/main/java/cx/ring/tv/call/TVCallFragment.java b/ring-android/app/src/main/java/cx/ring/tv/call/TVCallFragment.java
index e20d26d..ef26e92 100644
--- a/ring-android/app/src/main/java/cx/ring/tv/call/TVCallFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/tv/call/TVCallFragment.java
@@ -166,22 +166,12 @@
     }
 
     @Override
-    public int getLayout() {
-        return R.layout.tv_frag_call;
-    }
-
-    @Override
     public void handleCallWakelock(boolean isAudioOnly) { }
 
-    @Override
-    public void injectFragment(JamiInjectionComponent component) {
-        component.inject(this);
-    }
-
     @Nullable
     @Override
     public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
-        injectFragment(((JamiApplication) getActivity().getApplication()).getRingInjectionComponent());
+        ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
         binding = TvFragCallBinding.inflate(inflater, container, false);
         binding.setPresenter(this);
         return binding.getRoot();
diff --git a/ring-android/app/src/main/java/cx/ring/tv/camera/CustomCameraActivity.java b/ring-android/app/src/main/java/cx/ring/tv/camera/CustomCameraActivity.java
index d647c43..7a83ab2 100644
--- a/ring-android/app/src/main/java/cx/ring/tv/camera/CustomCameraActivity.java
+++ b/ring-android/app/src/main/java/cx/ring/tv/camera/CustomCameraActivity.java
@@ -38,17 +38,13 @@
 import android.widget.FrameLayout;
 import android.widget.Toast;
 
-import com.google.android.material.floatingactionbutton.FloatingActionButton;
-
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import butterknife.OnClick;
 import cx.ring.R;
+import cx.ring.databinding.CamerapickerBinding;
 import cx.ring.utils.AndroidFileUtils;
 import cx.ring.utils.ContentUriHandler;
 import io.reactivex.Single;
@@ -64,17 +60,14 @@
     private int cameraBack = -1;
     private int currentCamera = 0;
 
+    private CamerapickerBinding binding;
+
     private MediaRecorder recorder;
     private boolean mRecording = false;
     private boolean mActionVideo = false;
 
     private File mVideoFile;
 
-    @BindView(R.id.button_video)
-    FloatingActionButton mButtonVideo;
-    @BindView(R.id.button_picture)
-    FloatingActionButton mButtonPicture;
-
     private Camera mCamera;
     private CameraPreview mCameraPreview;
     private final Camera.PictureCallback mPicture = (input, camera) -> Single.fromCallable(() ->  {
@@ -99,13 +92,12 @@
                 finish();
             });
 
-    @OnClick(R.id.button_picture)
     public void takePicture() {
         if (mRecording)
             releaseMediaRecorder();
         if (mCamera != null) {
-            mButtonPicture.setEnabled(false);
-            mButtonVideo.setVisibility(View.GONE);
+            binding.buttonPicture.setEnabled(false);
+            binding.buttonVideo.setVisibility(View.GONE);
             try {
                 mCamera.takePicture(null, null, mPicture);
             } catch (Exception e) {
@@ -114,7 +106,6 @@
         }
     }
 
-    @OnClick(R.id.button_video)
     public void takeVideo() {
         if (mRecording) {
             releaseMediaRecorder();
@@ -124,13 +115,13 @@
                     .setType(TYPE_VIDEO);
             setResult(RESULT_OK, intent);
             finish();
-            mButtonVideo.setImageResource(R.drawable.baseline_videocam_24);
+            binding.buttonVideo.setImageResource(R.drawable.baseline_videocam_24);
             return;
         }
         if (mCamera != null) {
             initRecorder();
-            mButtonVideo.setImageResource(R.drawable.lb_ic_stop);
-            mButtonPicture.setVisibility(View.GONE);
+            binding.buttonVideo.setImageResource(R.drawable.lb_ic_stop);
+            binding.buttonPicture.setVisibility(View.GONE);
         }
         mRecording = !mRecording;
     }
@@ -141,8 +132,9 @@
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        setContentView(R.layout.camerapicker);
-        ButterKnife.bind(this);
+        binding = CamerapickerBinding.inflate(getLayoutInflater());
+        binding.buttonPicture.setOnClickListener(v -> takePicture());
+        binding.buttonVideo.setOnClickListener(v -> takeVideo());
 
         if (getIntent().getAction() != null) {
             mActionVideo = getIntent().getAction().equals(MediaStore.ACTION_VIDEO_CAPTURE);
@@ -159,7 +151,7 @@
         preview.addView(mCameraPreview, 0);
 
         if (mActionVideo) {
-            mButtonVideo.setVisibility(View.VISIBLE);
+            binding.buttonVideo.setVisibility(View.VISIBLE);
         }
     }
 
diff --git a/ring-android/app/src/main/java/cx/ring/tv/cards/iconcards/IconCardPresenter.java b/ring-android/app/src/main/java/cx/ring/tv/cards/iconcards/IconCardPresenter.java
index ba0cbaf..b824b3b 100644
--- a/ring-android/app/src/main/java/cx/ring/tv/cards/iconcards/IconCardPresenter.java
+++ b/ring-android/app/src/main/java/cx/ring/tv/cards/iconcards/IconCardPresenter.java
@@ -43,7 +43,7 @@
 
     @Override
     protected ImageCardView onCreateView() {
-        JamiApplication.getInstance().getRingInjectionComponent().inject(this);
+        JamiApplication.getInstance().getInjectionComponent().inject(this);
         ImageCardView imageCardView = new ImageCardView(getContext());
         final ImageView image = imageCardView.getMainImageView();
         image.setBackgroundResource(R.drawable.icon_focused);
diff --git a/ring-android/app/src/main/java/cx/ring/tv/contact/TVContactDetailPresenter.java b/ring-android/app/src/main/java/cx/ring/tv/contact/TVContactDetailPresenter.java
index 1b719a0..830edce 100644
--- a/ring-android/app/src/main/java/cx/ring/tv/contact/TVContactDetailPresenter.java
+++ b/ring-android/app/src/main/java/cx/ring/tv/contact/TVContactDetailPresenter.java
@@ -37,8 +37,7 @@
 
     @Override
     public ViewHolder onCreateViewHolder(ViewGroup viewGroup) {
-        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.tv, viewGroup, false);
-        return new CustomViewHolder(view);
+        return new CustomViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.tv, viewGroup, false));
     }
 
     @Override
@@ -51,13 +50,13 @@
 
     }
 
-    public static class CustomViewHolder extends Presenter.ViewHolder {
+    private static class CustomViewHolder extends Presenter.ViewHolder {
 
-        public CustomViewHolder(View view) {
+        CustomViewHolder(View view) {
             super(view);
         }
 
-        public void bind(TVListViewModel object) {
+        void bind(TVListViewModel object) {
             Fragment fragment = TvConversationFragment.newInstance(object);
             FragmentManager fragmentManager = ((TVContactActivity) view.getContext()).getSupportFragmentManager();
 
diff --git a/ring-android/app/src/main/java/cx/ring/tv/contact/TVContactFragment.java b/ring-android/app/src/main/java/cx/ring/tv/contact/TVContactFragment.java
index 5d8b804..78e612c 100644
--- a/ring-android/app/src/main/java/cx/ring/tv/contact/TVContactFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/tv/contact/TVContactFragment.java
@@ -72,7 +72,7 @@
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
-        ((JamiApplication) getActivity().getApplication()).getRingInjectionComponent().inject(this);
+        ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
         super.onCreate(savedInstanceState);
     }
 
diff --git a/ring-android/app/src/main/java/cx/ring/tv/conversation/TvConversationFragment.java b/ring-android/app/src/main/java/cx/ring/tv/conversation/TvConversationFragment.java
index 84d1d59..b2fa171 100644
--- a/ring-android/app/src/main/java/cx/ring/tv/conversation/TvConversationFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/tv/conversation/TvConversationFragment.java
@@ -23,7 +23,6 @@
 import android.app.Activity;
 import android.content.ActivityNotFoundException;
 import android.content.Context;
-import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.media.MediaPlayer;
@@ -35,7 +34,6 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.appcompat.app.AlertDialog;
-import androidx.core.app.ActivityCompat;
 import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 import androidx.transition.TransitionManager;
@@ -44,6 +42,7 @@
 import android.speech.RecognizerIntent;
 import android.text.TextUtils;
 import android.util.Log;
+import android.view.LayoutInflater;
 import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
@@ -69,8 +68,8 @@
 import cx.ring.contacts.AvatarFactory;
 import cx.ring.conversation.ConversationPresenter;
 import cx.ring.conversation.ConversationView;
-import cx.ring.dependencyinjection.JamiInjectionComponent;
 import cx.ring.model.Account;
+import cx.ring.databinding.FragConversationTvBinding;
 import cx.ring.model.CallContact;
 import cx.ring.model.Conversation;
 import cx.ring.model.DataTransfer;
@@ -130,6 +129,7 @@
     private Map<String, AvatarDrawable> mParticipantAvatars = new HashMap<>();
 
     private final CompositeDisposable mCompositeDisposable = new CompositeDisposable();
+    private FragConversationTvBinding binding;
 
     public static TvConversationFragment newInstance(TVListViewModel param) {
         TvConversationFragment fragment = new TvConversationFragment();
@@ -141,13 +141,25 @@
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
-        ((JamiApplication) getActivity().getApplication()).getRingInjectionComponent().inject(this);
         super.onCreate(savedInstanceState);
         if (getArguments() != null) {
             mTvListViewModel = getArguments().getParcelable(ARG_MODEL);
         }
+        requestPermissions(permissions, REQUEST_RECORD_AUDIO_PERMISSION);
+    }
 
-        ActivityCompat.requestPermissions(getActivity(), permissions, REQUEST_RECORD_AUDIO_PERMISSION);
+    @Nullable
+    @Override
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+        binding = FragConversationTvBinding.inflate(inflater, container, false);
+        ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
+        return binding.getRoot();
+    }
+
+    @Override
+    public void onDestroyView() {
+        super.onDestroyView();
+        binding = null;
     }
 
     // Create an intent that can start the Speech Recognizer activity
@@ -158,17 +170,6 @@
         startActivityForResult(intent, REQUEST_SPEECH_CODE);
     }
 
-
-    @Override
-    public int getLayout() {
-        return R.layout.frag_conversation_tv;
-    }
-
-    @Override
-    public void injectFragment(JamiInjectionComponent component) {
-        component.inject(this);
-    }
-
     @Override
     public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
@@ -281,14 +282,11 @@
                 .create();
         alertDialog.getWindow().setLayout(DIALOG_WIDTH, DIALOG_HEIGHT);
         alertDialog.setOwnerActivity(getActivity());
-        alertDialog.setOnShowListener(new DialogInterface.OnShowListener() {
-            @Override
-            public void onShow(DialogInterface dialog) {
-                Button positive = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
-                positive.setFocusable(true);
-                positive.setFocusableInTouchMode(true);
-                positive.requestFocus();
-            }
+        alertDialog.setOnShowListener(dialog -> {
+            Button positive = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
+            positive.setFocusable(true);
+            positive.setFocusableInTouchMode(true);
+            positive.requestFocus();
         });
 
         alertDialog.show();
diff --git a/ring-android/app/src/main/java/cx/ring/tv/main/HomeActivity.java b/ring-android/app/src/main/java/cx/ring/tv/main/HomeActivity.java
index 9f95266..0f64dd6 100644
--- a/ring-android/app/src/main/java/cx/ring/tv/main/HomeActivity.java
+++ b/ring-android/app/src/main/java/cx/ring/tv/main/HomeActivity.java
@@ -46,7 +46,7 @@
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         JamiApplication.getInstance().startDaemon();
-        JamiApplication.getInstance().getRingInjectionComponent().inject(this);
+        JamiApplication.getInstance().getInjectionComponent().inject(this);
         setContentView(R.layout.tv_activity_home);
         mBackgroundManager = BackgroundManager.getInstance(this);
         mBackgroundManager.attach(getWindow());
diff --git a/ring-android/app/src/main/java/cx/ring/tv/main/MainFragment.java b/ring-android/app/src/main/java/cx/ring/tv/main/MainFragment.java
index 9b962c2..5400c86 100644
--- a/ring-android/app/src/main/java/cx/ring/tv/main/MainFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/tv/main/MainFragment.java
@@ -98,7 +98,7 @@
 
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-        ((JamiApplication) getActivity().getApplication()).getRingInjectionComponent().inject(this);
+        ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
         return super.onCreateView(inflater, container, savedInstanceState);
     }
 
diff --git a/ring-android/app/src/main/java/cx/ring/tv/search/ContactSearchFragment.java b/ring-android/app/src/main/java/cx/ring/tv/search/ContactSearchFragment.java
index 3baae2f..c4fdc5e 100644
--- a/ring-android/app/src/main/java/cx/ring/tv/search/ContactSearchFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/tv/search/ContactSearchFragment.java
@@ -33,9 +33,6 @@
 import androidx.core.content.ContextCompat;
 import android.view.View;
 
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import butterknife.Unbinder;
 import cx.ring.R;
 import cx.ring.application.JamiApplication;
 import cx.ring.client.CallActivity;
@@ -51,16 +48,10 @@
 
 public class ContactSearchFragment extends BaseSearchFragment<ContactSearchPresenter>
         implements SearchSupportFragment.SearchResultProvider, ContactSearchView {
-
-    private static final String TAG = ContactSearchFragment.class.getSimpleName();
-    @BindView(R.id.lb_search_text_editor)
-    SearchEditText mTextEditor;
-
-    @BindView(R.id.lb_search_bar)
-    SearchBar mSearchBar;
+    private SearchEditText mTextEditor;
+    private SearchBar mSearchBar;
 
     private final ArrayObjectAdapter mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
-    private Unbinder mUnbinder;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
@@ -68,7 +59,7 @@
         setSearchResultProvider(this);
 
         // dependency injection
-        ((JamiApplication) getActivity().getApplication()).getRingInjectionComponent().inject(this);
+        ((JamiApplication) getActivity().getApplication()).getInjectionComponent().inject(this);
         setOnItemViewClickedListener((itemViewHolder, item, rowViewHolder, row) -> presenter.contactClicked(((ContactCard) item).getModel()));
         setBadgeDrawable(ContextCompat.getDrawable(getActivity(), R.mipmap.ic_launcher));
         setSearchQuery("", false);
@@ -77,8 +68,9 @@
     @Override
     public void onViewCreated(View view, Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
+        mTextEditor = view.findViewById(R.id.lb_search_text_editor);
+        mSearchBar = view.findViewById(R.id.lb_search_bar);
         // view injection
-        mUnbinder = ButterKnife.bind(this, view);
         mSearchBar.setSearchBarListener(new SearchBar.SearchBarListener() {
             @Override
             public void onSearchQueryChange(String query) {
@@ -109,7 +101,6 @@
 
     @Override
     public void onDestroyView() {
-        mUnbinder.unbind();
         super.onDestroyView();
     }
 
diff --git a/ring-android/app/src/main/res/layout/add_new_device_layout.xml b/ring-android/app/src/main/res/layout/add_new_device_layout.xml
deleted file mode 100644
index 25e3db6..0000000
--- a/ring-android/app/src/main/res/layout/add_new_device_layout.xml
+++ /dev/null
@@ -1,129 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2017-2019 Savoir-faire Linux Inc.
-
-Authors: Aline Bonnet <aline.bonnet@savoirfairelinux.com>
-         Adrien Beraud <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, see <https://www.gnu.org/licenses/>.
--->
-<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:layout_gravity="bottom"
-    android:clipToPadding="false"
-    tools:showIn="@layout/frag_acc_summary">
-
-    <com.google.android.material.card.MaterialCardView
-        android:id="@+id/layout_add_device"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        app:cardCornerRadius="15dp"
-        android:layout_marginBottom="-15dp"
-        android:elevation="4dp"
-        app:behavior_hideable="false"
-        app:behavior_peekHeight="50dp"
-        app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
-        >
-
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:background="@color/colorPrimary"
-            android:paddingBottom="15dp"
-            android:orientation="vertical">
-
-        <com.google.android.material.button.MaterialButton
-            android:id="@+id/btn_add_device"
-            style="@style/Widget.MaterialComponents.Button.TextButton"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center_horizontal"
-            android:text="@string/account_link_export_button"
-            android:textColor="@color/colorOnPrimary" />
-
-        <ScrollView
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content">
-
-                <LinearLayout
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:orientation="vertical">
-
-                    <TextView
-                        android:id="@+id/account_link_info"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:gravity="top"
-                        android:paddingLeft="16dp"
-                        android:paddingTop="5dp"
-                        android:paddingRight="16dp"
-                        android:paddingBottom="8dp"
-                        android:text="@string/account_link_export_info"
-                        android:textColor="@color/colorOnPrimary"
-                        android:textIsSelectable="true"
-                        android:textSize="14sp" />
-
-                    <com.google.android.material.textfield.TextInputLayout
-                        android:id="@+id/password_layout"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:textColorHint="@color/colorPrimary"
-                        app:passwordToggleTint="@color/colorPrimary"
-                        android:paddingLeft="16dp"
-                        android:paddingRight="16dp"
-                        android:layout_marginBottom="8dp"
-                        app:passwordToggleEnabled="true">
-
-                        <com.google.android.material.textfield.TextInputEditText
-                            android:id="@+id/ring_password"
-                            android:layout_width="match_parent"
-                            android:layout_height="wrap_content"
-                            android:hint="@string/account_enter_password"
-                            android:textColor="@color/colorPrimary"
-                            android:backgroundTint="@color/colorOnPrimary"
-                            android:imeOptions="actionDone"
-                            android:inputType="textPassword" />
-                    </com.google.android.material.textfield.TextInputLayout>
-
-                    <com.google.android.material.button.MaterialButton
-                        android:id="@+id/btn_start_export"
-                        style="@style/Widget.MaterialComponents.Button"
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:layout_gravity="center_horizontal"
-                        android:layout_marginBottom="8dp"
-                        android:text="@string/account_start_export_button"
-                        app:backgroundTint="@color/colorSecondary"
-                        android:textColor="@color/colorOnSecondary"/>
-
-                    <com.google.android.material.button.MaterialButton
-                        android:id="@+id/btn_end_export"
-                        style="@style/Widget.MaterialComponents.Button.TextButton"
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:layout_gravity="center_horizontal"
-                        android:text="@string/account_end_export_button"
-                        android:textColor="@color/colorOnPrimary"
-                        android:visibility="gone" />
-
-                </LinearLayout>
-            </ScrollView>
-
-        </LinearLayout>
-
-        </com.google.android.material.card.MaterialCardView>
-
-</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
diff --git a/ring-android/app/src/main/res/layout/frag_acc_summary.xml b/ring-android/app/src/main/res/layout/frag_acc_summary.xml
index 3abfa6b..74753e7 100644
--- a/ring-android/app/src/main/res/layout/frag_acc_summary.xml
+++ b/ring-android/app/src/main/res/layout/frag_acc_summary.xml
@@ -19,7 +19,8 @@
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    tools:context=".client.HomeActivity">
 
     <ScrollView
         android:id="@+id/scrollview"
@@ -37,37 +38,36 @@
                 android:id="@+id/ring_account_status_container"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
+                android:clipChildren="false"
+                android:clipToPadding="false"
                 android:paddingStart="16dp"
                 android:paddingTop="8dp"
                 android:paddingEnd="16dp"
-                android:paddingBottom="8dp"
-                android:clipToPadding="false"
-                android:clipChildren="false"
-                >
+                android:paddingBottom="8dp">
 
                 <com.google.android.material.chip.Chip
                     android:id="@+id/account_status"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:layout_alignParentTop="true"
                     android:layout_alignParentStart="true"
+                    android:layout_alignParentTop="true"
                     android:textColor="@color/white"
-                    tools:text="Registered"/>
+                    tools:text="Registered" />
 
                 <androidx.appcompat.widget.SwitchCompat
                     android:id="@+id/account_switch"
                     android:layout_width="50dp"
                     android:layout_height="wrap_content"
-                    android:layout_alignParentEnd="true"
-                    android:layout_alignParentTop="true"/>
+                    android:layout_alignParentTop="true"
+                    android:layout_alignParentEnd="true" />
 
                 <TextView
                     android:id="@+id/account_alias_txt"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
                     android:layout_below="@id/account_switch"
-                    android:paddingBottom="8dp"
                     android:paddingTop="8dp"
+                    android:paddingBottom="8dp"
                     android:textAppearance="@style/TextAppearance.MaterialComponents.Overline"
                     tools:text="@string/profile" />
 
@@ -77,68 +77,63 @@
                     android:layout_height="wrap_content"
                     android:layout_below="@+id/account_alias_txt"
                     android:layout_centerHorizontal="true"
-                    android:clipToPadding="false"
                     android:clipChildren="false"
-                    >
+                    android:clipToPadding="false">
 
                     <ImageView
                         android:id="@+id/user_photo"
                         android:layout_width="90dp"
                         android:layout_height="90dp"
                         android:src="@drawable/ic_contact_picture_fallback"
-                        app:layout_constraintTop_toTopOf="parent"
                         app:layout_constraintStart_toStartOf="parent"
-                        />
+                        app:layout_constraintTop_toTopOf="parent" />
 
                     <View
                         android:id="@+id/anchor"
                         android:layout_width="20dp"
                         android:layout_height="20dp"
-                        app:layout_constraintStart_toStartOf="@id/user_photo"
-                        app:layout_constraintEnd_toEndOf="@id/user_photo"
                         app:layout_constraintBottom_toBottomOf="@id/user_photo"
-                        />
+                        app:layout_constraintEnd_toEndOf="@id/user_photo"
+                        app:layout_constraintStart_toStartOf="@id/user_photo" />
 
                     <com.google.android.material.floatingactionbutton.FloatingActionButton
                         android:id="@+id/user_profile_edit"
                         android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
                         app:fabSize="mini"
-                        app:srcCompat="@drawable/baseline_edit_24"
+                        app:layout_constraintStart_toEndOf="@id/anchor"
                         app:layout_constraintTop_toTopOf="@id/anchor"
-                        app:layout_constraintStart_toEndOf="@id/anchor"/>
+                        app:srcCompat="@drawable/baseline_edit_24" />
 
                     <TextView
                         android:id="@+id/username"
                         android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
                         android:layout_toEndOf="@+id/user_photo"
+                        android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle2"
                         android:textSize="18sp"
-                        app:layout_constraintVertical_chainStyle="packed"
-                        app:layout_constraintTop_toTopOf="@id/user_photo"
                         app:layout_constraintBottom_toTopOf="@id/subtitle"
                         app:layout_constraintStart_toStartOf="@id/subtitle"
-                        android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle2"
-                        tools:text="username"
-                        />
+                        app:layout_constraintTop_toTopOf="@id/user_photo"
+                        app:layout_constraintVertical_chainStyle="packed"
+                        tools:text="username" />
 
                     <TextView
                         android:id="@+id/subtitle"
                         android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
-                        app:layout_constrainedWidth="true"
+                        android:layout_marginStart="20dp"
                         android:ellipsize="end"
                         android:maxLines="1"
                         android:textColor="@color/darker_gray"
                         android:textSize="14sp"
-                        android:layout_marginStart="20dp"
-                        tools:text="sub-username"
-                        app:layout_constraintTop_toBottomOf="@+id/username"
-                        app:layout_constraintStart_toEndOf="@+id/user_photo"
+                        app:layout_constrainedWidth="true"
                         app:layout_constraintBottom_toBottomOf="@id/user_photo"
                         app:layout_constraintEnd_toEndOf="parent"
                         app:layout_constraintHorizontal_bias="0"
-                        />
+                        app:layout_constraintStart_toEndOf="@+id/user_photo"
+                        app:layout_constraintTop_toBottomOf="@+id/username"
+                        tools:text="sub-username" />
 
                 </androidx.constraintlayout.widget.ConstraintLayout>
 
@@ -326,9 +321,113 @@
         </RelativeLayout>
     </ScrollView>
 
-    <include
-        layout="@layout/add_new_device_layout"
+    <androidx.coordinatorlayout.widget.CoordinatorLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_alignParentBottom="true" />
+        android:layout_alignParentBottom="true"
+        android:layout_gravity="bottom"
+        android:clipToPadding="false"
+        tools:showIn="@layout/frag_acc_summary">
+
+        <com.google.android.material.card.MaterialCardView
+            android:id="@+id/layout_add_device"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="-15dp"
+            android:elevation="4dp"
+            app:behavior_hideable="false"
+            app:behavior_peekHeight="50dp"
+            app:cardCornerRadius="15dp"
+            app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:background="@color/colorPrimary"
+                android:orientation="vertical"
+                android:paddingBottom="15dp">
+
+                <com.google.android.material.button.MaterialButton
+                    android:id="@+id/btn_add_device"
+                    style="@style/Widget.MaterialComponents.Button.TextButton"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center_horizontal"
+                    android:text="@string/account_link_export_button"
+                    android:textColor="@color/colorOnPrimary" />
+
+                <ScrollView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content">
+
+                    <LinearLayout
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:orientation="vertical">
+
+                        <TextView
+                            android:id="@+id/account_link_info"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:gravity="top"
+                            android:paddingLeft="16dp"
+                            android:paddingTop="5dp"
+                            android:paddingRight="16dp"
+                            android:paddingBottom="8dp"
+                            android:text="@string/account_link_export_info"
+                            android:textColor="@color/colorOnPrimary"
+                            android:textIsSelectable="true"
+                            android:textSize="14sp" />
+
+                        <com.google.android.material.textfield.TextInputLayout
+                            android:id="@+id/password_layout"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:layout_marginBottom="8dp"
+                            android:paddingLeft="16dp"
+                            android:paddingRight="16dp"
+                            android:textColorHint="@color/colorPrimary"
+                            app:passwordToggleEnabled="true"
+                            app:passwordToggleTint="@color/colorPrimary">
+
+                            <com.google.android.material.textfield.TextInputEditText
+                                android:id="@+id/ring_password"
+                                android:layout_width="match_parent"
+                                android:layout_height="wrap_content"
+                                android:backgroundTint="@color/colorOnPrimary"
+                                android:hint="@string/account_enter_password"
+                                android:imeOptions="actionDone"
+                                android:inputType="textPassword"
+                                android:textColor="@color/colorPrimary" />
+                        </com.google.android.material.textfield.TextInputLayout>
+
+                        <com.google.android.material.button.MaterialButton
+                            android:id="@+id/btn_start_export"
+                            style="@style/Widget.MaterialComponents.Button"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:layout_gravity="center_horizontal"
+                            android:layout_marginBottom="8dp"
+                            android:text="@string/account_start_export_button"
+                            android:textColor="@color/colorOnSecondary"
+                            app:backgroundTint="@color/colorSecondary" />
+
+                        <com.google.android.material.button.MaterialButton
+                            android:id="@+id/btn_end_export"
+                            style="@style/Widget.MaterialComponents.Button.TextButton"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:layout_gravity="center_horizontal"
+                            android:text="@string/account_end_export_button"
+                            android:textColor="@color/colorOnPrimary"
+                            android:visibility="gone" />
+
+                    </LinearLayout>
+                </ScrollView>
+
+            </LinearLayout>
+
+        </com.google.android.material.card.MaterialCardView>
+
+    </androidx.coordinatorlayout.widget.CoordinatorLayout>
 </RelativeLayout>