]> git.ktnx.net Git - mobile-ledger.git/commitdiff
major rework of the profile management
authorDamyan Ivanov <dam+mobileledger@ktnx.net>
Sun, 24 Feb 2019 21:48:29 +0000 (23:48 +0200)
committerDamyan Ivanov <dam+mobileledger@ktnx.net>
Sun, 24 Feb 2019 21:48:29 +0000 (23:48 +0200)
moved entirely to the navigation bar

24 files changed:
app/src/main/AndroidManifest.xml
app/src/main/java/net/ktnx/mobileledger/ProfileListViewModel.java [new file with mode: 0644]
app/src/main/java/net/ktnx/mobileledger/ui/activity/MainActivity.java
app/src/main/java/net/ktnx/mobileledger/ui/activity/ProfileDetailActivity.java
app/src/main/java/net/ktnx/mobileledger/ui/activity/ProfileListActivity.java [deleted file]
app/src/main/java/net/ktnx/mobileledger/ui/profiles/ProfileDetailFragment.java
app/src/main/java/net/ktnx/mobileledger/ui/profiles/ProfilesRecyclerViewAdapter.java [new file with mode: 0644]
app/src/main/java/net/ktnx/mobileledger/ui/profiles/dummy/DummyContent.java [new file with mode: 0644]
app/src/main/res/anim/layout_slide_down.xml [new file with mode: 0644]
app/src/main/res/anim/rotate_180.xml [new file with mode: 0644]
app/src/main/res/anim/rotate_180_back.xml [new file with mode: 0644]
app/src/main/res/anim/slide_down.xml [new file with mode: 0644]
app/src/main/res/anim/slide_in_down.xml [new file with mode: 0644]
app/src/main/res/anim/slide_up.xml [new file with mode: 0644]
app/src/main/res/drawable-anydpi-v21/ic_expand_more_black_24dp.xml [new file with mode: 0644]
app/src/main/res/drawable-anydpi-v21/ic_keyboard_arrow_down_black_24dp.xml [new file with mode: 0644]
app/src/main/res/drawable-anydpi-v21/ic_unfold_more_black_24dp.xml [new file with mode: 0644]
app/src/main/res/layout/activity_main.xml
app/src/main/res/layout/main_navigation.xml [new file with mode: 0644]
app/src/main/res/layout/nav_profile_list_head.xml [new file with mode: 0644]
app/src/main/res/layout/nav_profile_list_new_profile_row.xml [new file with mode: 0644]
app/src/main/res/layout/profile_list_content.xml
app/src/main/res/values-h360dp/styles.xml
app/src/main/res/values/styles.xml

index eec9d79baaa339234a67d0d04b597eaa112836ce..3407017d95b7195b1e1ea55b85182f110c39e065 100644 (file)
@@ -62,7 +62,7 @@
         <activity
             android:name=".ui.activity.ProfileDetailActivity"
             android:label="@string/title_profile_details"
-            android:parentActivityName=".ui.activity.ProfileListActivity"
+            android:parentActivityName=".ui.activity.MainActivity"
             android:theme="@style/AppTheme.NoActionBar">
             <meta-data
                 android:name="android.support.PARENT_ACTIVITY"
diff --git a/app/src/main/java/net/ktnx/mobileledger/ProfileListViewModel.java b/app/src/main/java/net/ktnx/mobileledger/ProfileListViewModel.java
new file mode 100644 (file)
index 0000000..70c775e
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright © 2019 Damyan Ivanov.
+ *  This file is part of MoLe.
+ *  MoLe is free software: you can distribute it and/or modify it
+ *  under the term of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your opinion), any later version.
+ *
+ *  MoLe 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 terms for details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Mobile-Ledger. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package net.ktnx.mobileledger;
+
+import androidx.lifecycle.ViewModel;
+
+public class ProfileListViewModel extends ViewModel {
+    // TODO: Implement the ViewModel
+}
index 15e4bef5cd4c81fb1b6ef35db762a436f52691e0..958c0e919745f6dd96dc6820db772c6be6bc2081 100644 (file)
@@ -23,22 +23,18 @@ import android.content.res.ColorStateList;
 import android.graphics.Color;
 import android.os.Build;
 import android.os.Bundle;
-import com.google.android.material.floatingactionbutton.FloatingActionButton;
-import androidx.fragment.app.Fragment;
-import androidx.fragment.app.FragmentManager;
-import androidx.fragment.app.FragmentPagerAdapter;
-import androidx.core.view.GravityCompat;
-import androidx.viewpager.widget.ViewPager;
-import androidx.drawerlayout.widget.DrawerLayout;
-import androidx.appcompat.app.ActionBarDrawerToggle;
-import androidx.appcompat.widget.Toolbar;
 import android.util.Log;
 import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
 import android.widget.LinearLayout;
 import android.widget.ProgressBar;
 import android.widget.TextView;
 import android.widget.Toast;
 
+import com.google.android.material.floatingactionbutton.FloatingActionButton;
+
 import net.ktnx.mobileledger.R;
 import net.ktnx.mobileledger.async.RefreshDescriptionsTask;
 import net.ktnx.mobileledger.async.RetrieveTransactionsTask;
@@ -46,6 +42,8 @@ import net.ktnx.mobileledger.model.Data;
 import net.ktnx.mobileledger.model.LedgerAccount;
 import net.ktnx.mobileledger.model.MobileLedgerProfile;
 import net.ktnx.mobileledger.ui.account_summary.AccountSummaryFragment;
+import net.ktnx.mobileledger.ui.profiles.ProfileDetailFragment;
+import net.ktnx.mobileledger.ui.profiles.ProfilesRecyclerViewAdapter;
 import net.ktnx.mobileledger.ui.transaction_list.TransactionListFragment;
 import net.ktnx.mobileledger.utils.Colors;
 import net.ktnx.mobileledger.utils.MLDB;
@@ -54,8 +52,23 @@ import java.lang.ref.WeakReference;
 import java.text.DateFormat;
 import java.util.Date;
 
+import androidx.appcompat.app.ActionBarDrawerToggle;
+import androidx.appcompat.widget.Toolbar;
+import androidx.core.view.GravityCompat;
+import androidx.drawerlayout.widget.DrawerLayout;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentPagerAdapter;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.viewpager.widget.ViewPager;
+
 public class MainActivity extends CrashReportingActivity {
+    private static final String STATE_CURRENT_PAGE = "current_page";
+    private static final String BUNDLE_SAVED_STATE = "bundle_savedState";
     DrawerLayout drawer;
+    private LinearLayout profileListContainer;
+    private View profileListHeadArrow;
     private FragmentManager fragmentManager;
     private TextView tvLastUpdate;
     private RetrieveTransactionsTask retrieveTransactionsTask;
@@ -65,6 +78,9 @@ public class MainActivity extends CrashReportingActivity {
     private SectionsPagerAdapter mSectionsPagerAdapter;
     private ViewPager mViewPager;
     private FloatingActionButton fab;
+    private boolean profileModificationEnabled = false;
+    private boolean profileListExpanded = false;
+    private ProfilesRecyclerViewAdapter mProfileListAdapter;
 
     @Override
     protected void onStart() {
@@ -85,13 +101,34 @@ public class MainActivity extends CrashReportingActivity {
         }
     }
     @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putInt(STATE_CURRENT_PAGE, mViewPager.getCurrentItem());
+    }
+    @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
         setContentView(R.layout.activity_main);
+
+        fab = findViewById(R.id.btn_add_transaction);
+        profileListContainer = findViewById(R.id.nav_profile_list_container);
+        profileListHeadArrow = findViewById(R.id.nav_profiles_arrow);
+        drawer = findViewById(R.id.drawer_layout);
+        tvLastUpdate = findViewById(R.id.transactions_last_update);
+        bTransactionListCancelDownload = findViewById(R.id.transaction_list_cancel_download);
+        progressBar = findViewById(R.id.transaction_list_progress_bar);
+        progressLayout = findViewById(R.id.transaction_progress_layout);
+        fragmentManager = getSupportFragmentManager();
+        mSectionsPagerAdapter = new SectionsPagerAdapter(fragmentManager);
+        mViewPager = findViewById(R.id.root_frame);
+
+        Bundle extra = getIntent().getBundleExtra(BUNDLE_SAVED_STATE);
+        if (extra != null && savedInstanceState == null) savedInstanceState = extra;
+
+
         Toolbar toolbar = findViewById(R.id.toolbar);
         setSupportActionBar(toolbar);
-        fab = findViewById(R.id.btn_add_transaction);
 
         Data.profile.addObserver((o, arg) -> {
             MobileLedgerProfile profile = Data.profile.get();
@@ -118,7 +155,6 @@ public class MainActivity extends CrashReportingActivity {
             });
         });
 
-        drawer = findViewById(R.id.drawer_layout);
         ActionBarDrawerToggle toggle =
                 new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open,
                         R.string.navigation_drawer_close);
@@ -136,22 +172,13 @@ public class MainActivity extends CrashReportingActivity {
             e.printStackTrace();
         }
 
-        tvLastUpdate = findViewById(R.id.transactions_last_update);
-
-        bTransactionListCancelDownload = findViewById(R.id.transaction_list_cancel_download);
-        progressBar = findViewById(R.id.transaction_list_progress_bar);
         if (progressBar == null)
             throw new RuntimeException("Can't get hold on the transaction value progress bar");
-        progressLayout = findViewById(R.id.transaction_progress_layout);
         if (progressLayout == null) throw new RuntimeException(
                 "Can't get hold on the transaction value progress bar layout");
 
-        fragmentManager = getSupportFragmentManager();
-        mSectionsPagerAdapter = new SectionsPagerAdapter(fragmentManager);
-
         markDrawerItemCurrent(R.id.nav_account_summary);
 
-        mViewPager = findViewById(R.id.root_frame);
         mViewPager.setAdapter(mSectionsPagerAdapter);
         mViewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
             @Override
@@ -171,6 +198,13 @@ public class MainActivity extends CrashReportingActivity {
             }
         });
 
+        if (savedInstanceState != null) {
+            int currentPage = savedInstanceState.getInt(STATE_CURRENT_PAGE, -1);
+            if (currentPage != -1) {
+                mViewPager.setCurrentItem(currentPage, false);
+            }
+        }
+
         Data.lastUpdateDate.addObserver((o, arg) -> {
             Log.d("main", "lastUpdateDate changed");
             runOnUiThread(() -> {
@@ -186,16 +220,35 @@ public class MainActivity extends CrashReportingActivity {
             });
         });
 
-        findViewById(R.id.btn_no_profiles_add).setOnClickListener(v -> startAddProfileActivity());
+        findViewById(R.id.btn_no_profiles_add)
+                .setOnClickListener(v -> startEditProfileActivity(null));
 
         findViewById(R.id.btn_add_transaction).setOnClickListener(this::fabNewTransactionClicked);
+
+        findViewById(R.id.nav_new_profile_button)
+                .setOnClickListener(v -> startEditProfileActivity(null));
+
+        RecyclerView root = findViewById(R.id.nav_profile_list);
+        if (root == null)
+            throw new RuntimeException("Can't get hold on the transaction value view");
+
+        mProfileListAdapter = new ProfilesRecyclerViewAdapter();
+        root.setAdapter(mProfileListAdapter);
+
+        LinearLayoutManager llm = new LinearLayoutManager(this);
+
+        llm.setOrientation(RecyclerView.VERTICAL);
+        root.setLayoutManager(llm);
     }
     private void profileThemeChanged() {
         setupProfileColors();
 
+        Bundle bundle = new Bundle();
+        onSaveInstanceState(bundle);
         // restart activity to reflect theme change
         finish();
         Intent intent = new Intent(this, this.getClass());
+        intent.putExtra(BUNDLE_SAVED_STATE, bundle);
         startActivity(intent);
     }
     @Override
@@ -203,11 +256,13 @@ public class MainActivity extends CrashReportingActivity {
         super.onResume();
         setupProfile();
     }
-    private void startAddProfileActivity() {
-        Intent intent = new Intent(this, ProfileListActivity.class);
+    public void startEditProfileActivity(MobileLedgerProfile profile) {
+        Intent intent = new Intent(this, ProfileDetailActivity.class);
         Bundle args = new Bundle();
-        args.putInt(ProfileListActivity.ARG_ACTION, ProfileListActivity.ACTION_EDIT_PROFILE);
-        args.putInt(ProfileListActivity.ARG_PROFILE_INDEX, ProfileListActivity.PROFILE_INDEX_NONE);
+        if (profile != null) {
+            int index = Data.getProfileIndex(profile);
+            if (index != -1) intent.putExtra(ProfileDetailFragment.ARG_ITEM_ID, index);
+        }
         intent.putExtras(args);
         startActivity(intent, args);
     }
@@ -377,15 +432,75 @@ public class MainActivity extends CrashReportingActivity {
             progressBar.setIndeterminate(false);
         }
     }
-    public void navProfilesClicked(View view) {
-        drawer.closeDrawers();
-        Intent intent = new Intent(this, ProfileListActivity.class);
-        startActivity(intent);
-    }
     public void fabShouldShow() {
         MobileLedgerProfile profile = Data.profile.get();
         if ((profile != null) && profile.isPostingPermitted()) fab.show();
     }
+    public void navProfilesHeadClicked(View view) {
+        if (profileListExpanded) {
+            collapseProfileList();
+        }
+        else {
+            expandProfileList();
+        }
+    }
+    private void expandProfileList() {
+        profileListExpanded = true;
+
+
+        profileListContainer.setVisibility(View.VISIBLE);
+        profileListContainer.startAnimation(AnimationUtils.loadAnimation(this, R.anim.slide_down));
+        profileListHeadArrow.startAnimation(AnimationUtils.loadAnimation(this, R.anim.rotate_180));
+    }
+    private void collapseProfileList() {
+        profileListExpanded = false;
+
+        final Animation animation = AnimationUtils.loadAnimation(this, R.anim.slide_up);
+        animation.setAnimationListener(new Animation.AnimationListener() {
+            @Override
+            public void onAnimationStart(Animation animation) {
+
+            }
+            @Override
+            public void onAnimationEnd(Animation animation) {
+                profileListContainer.setVisibility(View.GONE);
+            }
+            @Override
+            public void onAnimationRepeat(Animation animation) {
+
+            }
+        });
+        profileListContainer.startAnimation(animation);
+        profileListHeadArrow
+                .startAnimation(AnimationUtils.loadAnimation(this, R.anim.rotate_180_back));
+
+        mProfileListAdapter.stopEditingProfiles();
+    }
+    public void onProfileRowClicked(View v) {
+        Data.setCurrentProfile((MobileLedgerProfile) v.getTag());
+    }
+    public void enableProfileModifications() {
+        profileModificationEnabled = true;
+        ViewGroup profileList = findViewById(R.id.nav_profile_list);
+        for (int i = 0; i < profileList.getChildCount(); i++) {
+            View aRow = profileList.getChildAt(i);
+            aRow.findViewById(R.id.profile_list_edit_button).setVisibility(View.VISIBLE);
+            aRow.findViewById(R.id.profile_list_rearrange_handle).setVisibility(View.VISIBLE);
+        }
+        // FIXME enable rearranging
+
+    }
+    public void disableProfileModifications() {
+        profileModificationEnabled = false;
+        ViewGroup profileList = findViewById(R.id.nav_profile_list);
+        for (int i = 0; i < profileList.getChildCount(); i++) {
+            View aRow = profileList.getChildAt(i);
+            aRow.findViewById(R.id.profile_list_edit_button).setVisibility(View.GONE);
+            aRow.findViewById(R.id.profile_list_rearrange_handle).setVisibility(View.GONE);
+        }
+        // FIXME disable rearranging
+
+    }
 
     public class SectionsPagerAdapter extends FragmentPagerAdapter {
 
@@ -412,4 +527,5 @@ public class MainActivity extends CrashReportingActivity {
             return 2;
         }
     }
+
 }
index fa55b8784281d189c73a13369f47b1677d7f5a22..ee4707ca387c8a9626cc63a3a8f5829430295a7a 100644 (file)
 
 package net.ktnx.mobileledger.ui.activity;
 
-import android.content.Intent;
 import android.os.Bundle;
-import com.google.android.material.floatingactionbutton.FloatingActionButton;
-import com.google.android.material.snackbar.Snackbar;
-import androidx.appcompat.app.ActionBar;
-import androidx.appcompat.widget.Toolbar;
 import android.util.Log;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
 
+import com.google.android.material.floatingactionbutton.FloatingActionButton;
+import com.google.android.material.snackbar.Snackbar;
+
 import net.ktnx.mobileledger.R;
 import net.ktnx.mobileledger.model.Data;
 import net.ktnx.mobileledger.model.MobileLedgerProfile;
 import net.ktnx.mobileledger.ui.profiles.ProfileDetailFragment;
 
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.widget.Toolbar;
+
 /**
  * An activity representing a single Profile detail screen. This
  * activity is only used on narrow width devices. On tablet-size devices,
@@ -115,19 +116,4 @@ public class ProfileDetailActivity extends CrashReportingActivity {
         return true;
     }
 
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        int id = item.getItemId();
-        if (id == android.R.id.home) {
-            // This ID represents the Home or Up button. In the case of this
-            // activity, the Up button is shown. For
-            // more details, see the Navigation pattern on Android Design:
-            //
-            // http://developer.android.com/design/patterns/navigation.html#up-vs-back
-            //
-            navigateUpTo(new Intent(this, ProfileListActivity.class));
-            return true;
-        }
-        return super.onOptionsItemSelected(item);
-    }
 }
diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/activity/ProfileListActivity.java b/app/src/main/java/net/ktnx/mobileledger/ui/activity/ProfileListActivity.java
deleted file mode 100644 (file)
index 2fde364..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright © 2019 Damyan Ivanov.
- * This file is part of MoLe.
- * MoLe is free software: you can distribute it and/or modify it
- * under the term of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your opinion), any later version.
- *
- * MoLe 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 terms for details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MoLe. If not, see <https://www.gnu.org/licenses/>.
- */
-
-package net.ktnx.mobileledger.ui.activity;
-
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.Color;
-import android.os.Bundle;
-import androidx.annotation.NonNull;
-import androidx.appcompat.app.ActionBar;
-import androidx.recyclerview.widget.DividerItemDecoration;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.appcompat.widget.Toolbar;
-import androidx.recyclerview.widget.ItemTouchHelper;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.RadioButton;
-import android.widget.TextView;
-
-import net.ktnx.mobileledger.R;
-import net.ktnx.mobileledger.model.Data;
-import net.ktnx.mobileledger.model.MobileLedgerProfile;
-import net.ktnx.mobileledger.ui.profiles.ProfileDetailFragment;
-import net.ktnx.mobileledger.utils.Colors;
-
-import java.util.Collections;
-
-/**
- * An activity representing a list of Profiles. This activity
- * has different presentations for handset and tablet-size devices. On
- * handsets, the activity presents a list of items, which when touched,
- * lead to a {@link ProfileDetailActivity} representing
- * item details. On tablets, the activity presents the list of items and
- * item details side-by-side using two vertical panes.
- */
-public class ProfileListActivity extends CrashReportingActivity {
-
-    public static final String ARG_ACTION = "action";
-    public static final String ARG_PROFILE_INDEX = "profile_index";
-    public static final int PROFILE_INDEX_NONE = -1;
-    public static final int ACTION_EDIT_PROFILE = 1;
-    public static final int ACTION_INVALID = -1;
-    /**
-     * Whether or not the activity is in two-pane mode, i.e. running on a tablet
-     * device.
-     */
-    private boolean mTwoPane;
-    private RecyclerView recyclerView;
-
-    @Override
-    public boolean onSupportNavigateUp() {
-        onBackPressed();
-        return super.onSupportNavigateUp();
-    }
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.activity_profile_list);
-
-        Toolbar toolbar = findViewById(R.id.toolbar);
-        setSupportActionBar(toolbar);
-        toolbar.setTitle(getTitle());
-        final ActionBar supportActionBar = getSupportActionBar();
-        if (supportActionBar != null) {
-            supportActionBar.setDisplayHomeAsUpEnabled(true);
-            supportActionBar.setDisplayShowHomeEnabled(true);
-        }
-
-        recyclerView = findViewById(R.id.profile_list);
-        if (recyclerView == null) throw new AssertionError();
-        setupRecyclerView(recyclerView);
-
-        if (findViewById(R.id.profile_detail_container) != null) {
-            // The detail container view will be present only in the
-            // large-screen layouts (res/values-w900dp).
-            // If this view is present, then the
-            // activity should be in two-pane mode.
-            mTwoPane = true;
-        }
-
-        int action = getIntent().getIntExtra(ARG_ACTION, ACTION_INVALID);
-        if (action == ACTION_EDIT_PROFILE) {
-            Log.d("profiles", "got edit profile action");
-            int index = getIntent().getIntExtra(ARG_PROFILE_INDEX, PROFILE_INDEX_NONE);
-
-            MobileLedgerProfile profile = (index >= 0) ? Data.profiles.get(index) : null;
-            ProfilesRecyclerViewAdapter adapter =
-                    (ProfilesRecyclerViewAdapter) recyclerView.getAdapter();
-            if (adapter != null) {
-                adapter.editProfile(recyclerView, profile);
-
-                // if invoked from the initial screen, get out so that when the new profile
-                // activity finishes the user i navigated to the main activity
-                if ((profile == null) && Data.profiles.getList().isEmpty()) finish();
-            }
-        }
-    }
-    void launchNewProfileActivity() {
-        ProfilesRecyclerViewAdapter adapter =
-                (ProfilesRecyclerViewAdapter) recyclerView.getAdapter();
-        if (adapter != null) adapter.editProfile(recyclerView, null);
-    }
-    private void setupRecyclerView(@NonNull RecyclerView recyclerView) {
-        final ProfilesRecyclerViewAdapter adapter = new ProfilesRecyclerViewAdapter(this, mTwoPane);
-        recyclerView.setAdapter(adapter);
-        ItemTouchHelper.Callback cb = new ItemTouchHelper.Callback() {
-            @Override
-            public int getMovementFlags(@NonNull RecyclerView recyclerView,
-                                        @NonNull RecyclerView.ViewHolder viewHolder) {
-                return makeMovementFlags(ItemTouchHelper.UP | ItemTouchHelper.DOWN, 0);
-            }
-            @Override
-            public boolean onMove(@NonNull RecyclerView recyclerView,
-                                  @NonNull RecyclerView.ViewHolder viewHolder,
-                                  @NonNull RecyclerView.ViewHolder target) {
-                Collections.swap(Data.profiles.getList(), viewHolder.getAdapterPosition(),
-                        target.getAdapterPosition());
-                MobileLedgerProfile.storeProfilesOrder();
-                adapter.notifyItemMoved(viewHolder.getAdapterPosition(),
-                        target.getAdapterPosition());
-                return true;
-            }
-            @Override
-            public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
-
-            }
-        };
-        new ItemTouchHelper(cb).attachToRecyclerView(recyclerView);
-        recyclerView.addItemDecoration(new DividerItemDecoration(recyclerView.getContext(),
-                DividerItemDecoration.VERTICAL));
-    }
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        getMenuInflater().inflate(R.menu.profile_list, menu);
-        menu.findItem(R.id.menu_add_profile).setOnMenuItemClickListener(item -> {
-            launchNewProfileActivity();
-            return true;
-        });
-        return super.onCreateOptionsMenu(menu);
-    }
-    public static class ProfilesRecyclerViewAdapter
-            extends RecyclerView.Adapter<ProfilesRecyclerViewAdapter.ProfileListViewHolder> {
-
-        private final ProfileListActivity mParentActivity;
-        private final boolean mTwoPane;
-        private final View.OnClickListener mOnClickListener = view -> {
-            MobileLedgerProfile profile = (MobileLedgerProfile) ((View) view.getParent()).getTag();
-            editProfile(view, profile);
-        };
-        ProfilesRecyclerViewAdapter(ProfileListActivity parent, boolean twoPane) {
-            mParentActivity = parent;
-            mTwoPane = twoPane;
-            Data.profiles.addObserver((o, arg) -> {
-                Log.d("profiles", "profile list changed");
-                if (arg == null) notifyDataSetChanged();
-                else notifyItemChanged((int) arg);
-            });
-        }
-        private void editProfile(View view, MobileLedgerProfile profile) {
-            int index = Data.profiles.indexOf(profile);
-            if (mTwoPane) {
-                Bundle arguments = new Bundle();
-                arguments.putInt(ProfileDetailFragment.ARG_ITEM_ID, index);
-                ProfileDetailFragment fragment = new ProfileDetailFragment();
-                fragment.setArguments(arguments);
-                mParentActivity.getSupportFragmentManager().beginTransaction()
-                        .replace(R.id.profile_detail_container, fragment).commit();
-            }
-            else {
-                Context context = view.getContext();
-                Intent intent = new Intent(context, ProfileDetailActivity.class);
-                intent.addFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION);
-                if (index != -1) intent.putExtra(ProfileDetailFragment.ARG_ITEM_ID, index);
-
-                context.startActivity(intent);
-            }
-        }
-        @NonNull
-        @Override
-        public ProfileListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
-            View view = LayoutInflater.from(parent.getContext())
-                    .inflate(R.layout.profile_list_content, parent, false);
-            ProfileListViewHolder holder = new ProfileListViewHolder(view);
-
-            holder.mRadioView.setOnCheckedChangeListener((buttonView, isChecked) -> {
-                if (!isChecked) return;
-                Log.d("profiles",
-                        String.format("Item %d got checked", holder.getAdapterPosition()));
-                MobileLedgerProfile profile = (MobileLedgerProfile) holder.itemView.getTag();
-                if (profile != null) {
-                    Log.d("profiles",
-                            String.format("Setting current profile to %s", profile.getUuid()));
-                    Data.setCurrentProfile(profile);
-                }
-            });
-            View.OnClickListener profileSelector = v -> holder.mRadioView.setChecked(true);
-            holder.mTitle.setOnClickListener(profileSelector);
-            holder.mSubTitle.setOnClickListener(profileSelector);
-            Data.profile.addObserver((o, arg) -> {
-                MobileLedgerProfile myProfile = (MobileLedgerProfile) holder.itemView.getTag();
-                final MobileLedgerProfile currentProfile = Data.profile.get();
-                final boolean sameProfile = currentProfile.equals(myProfile);
-                if (holder.mRadioView.isChecked() != sameProfile) {
-                    holder.mRadioView.setChecked(sameProfile);
-                }
-            });
-            return holder;
-        }
-        @Override
-        public void onBindViewHolder(@NonNull final ProfileListViewHolder holder, int position) {
-            final MobileLedgerProfile profile = Data.profiles.get(position);
-            final MobileLedgerProfile currentProfile = Data.profile.get();
-            Log.d("profiles", String.format("pos %d: %s, current: %s", position, profile.getUuid(),
-                    (currentProfile == null) ? "<NULL>" : currentProfile.getUuid()));
-            holder.itemView.setTag(profile);
-
-            int hue = profile.getThemeId();
-            if (hue == -1) holder.mColorTag.setBackgroundColor(Color.TRANSPARENT);
-            else holder.mColorTag.setBackgroundColor(Colors.getPrimaryColorForHue(hue));
-
-            holder.mTitle.setText(profile.getName());
-            holder.mSubTitle.setText(profile.getUrl());
-            holder.mRadioView.setChecked(profile.equals(currentProfile));
-
-            holder.mEditButton.setOnClickListener(mOnClickListener);
-        }
-        @Override
-        public int getItemCount() {
-            return Data.profiles.size();
-        }
-        class ProfileListViewHolder extends RecyclerView.ViewHolder {
-            final RadioButton mRadioView;
-            final TextView mEditButton;
-            final TextView mTitle, mSubTitle, mColorTag;
-
-            ProfileListViewHolder(View view) {
-                super(view);
-                mRadioView = view.findViewById(R.id.profile_list_radio);
-                mEditButton = view.findViewById(R.id.profile_list_edit_button);
-                mTitle = view.findViewById(R.id.title);
-                mSubTitle = view.findViewById(R.id.subtitle);
-                mColorTag = view.findViewById(R.id.colorTag);
-            }
-        }
-    }
-}
index 6d26e4ba71efeb84d8ef03a69e1e871084248319..0f307e0ab0998a70328416292c6c788a92da13d6 100644 (file)
@@ -21,13 +21,6 @@ import android.app.Activity;
 import android.content.Context;
 import android.os.Build;
 import android.os.Bundle;
-import androidx.annotation.ColorInt;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import com.google.android.material.appbar.CollapsingToolbarLayout;
-import com.google.android.material.floatingactionbutton.FloatingActionButton;
-import com.google.android.material.textfield.TextInputLayout;
-import androidx.fragment.app.Fragment;
 import android.text.Editable;
 import android.text.TextWatcher;
 import android.util.Log;
@@ -44,21 +37,28 @@ import android.widget.Spinner;
 import android.widget.Switch;
 import android.widget.TextView;
 
+import com.google.android.material.appbar.CollapsingToolbarLayout;
+import com.google.android.material.floatingactionbutton.FloatingActionButton;
+import com.google.android.material.textfield.TextInputLayout;
+
 import net.ktnx.mobileledger.R;
 import net.ktnx.mobileledger.model.Data;
 import net.ktnx.mobileledger.model.MobileLedgerProfile;
 import net.ktnx.mobileledger.ui.activity.ProfileDetailActivity;
-import net.ktnx.mobileledger.ui.activity.ProfileListActivity;
 import net.ktnx.mobileledger.utils.Colors;
 
 import org.jetbrains.annotations.NotNull;
 
 import java.util.List;
 
+import androidx.annotation.ColorInt;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+
 /**
  * A fragment representing a single Profile detail screen.
- * This fragment is either contained in a {@link ProfileListActivity}
- * in two-pane mode (on tablets) or a {@link ProfileDetailActivity}
+ *  a {@link ProfileDetailActivity}
  * on handsets.
  */
 public class ProfileDetailFragment extends Fragment {
diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/profiles/ProfilesRecyclerViewAdapter.java b/app/src/main/java/net/ktnx/mobileledger/ui/profiles/ProfilesRecyclerViewAdapter.java
new file mode 100644 (file)
index 0000000..54386d9
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * Copyright © 2019 Damyan Ivanov.
+ *  This file is part of MoLe.
+ *  MoLe is free software: you can distribute it and/or modify it
+ *  under the term of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your opinion), any later version.
+ *
+ *  MoLe 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 terms for details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Mobile-Ledger. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package net.ktnx.mobileledger.ui.profiles;
+
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import net.ktnx.mobileledger.R;
+import net.ktnx.mobileledger.model.Data;
+import net.ktnx.mobileledger.model.MobileLedgerProfile;
+import net.ktnx.mobileledger.ui.activity.ProfileDetailActivity;
+import net.ktnx.mobileledger.utils.Colors;
+
+import java.util.Collections;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.ItemTouchHelper;
+import androidx.recyclerview.widget.RecyclerView;
+
+public class ProfilesRecyclerViewAdapter
+        extends RecyclerView.Adapter<ProfilesRecyclerViewAdapter.ProfileListViewHolder> {
+    private final View.OnClickListener mOnClickListener = view -> {
+        MobileLedgerProfile profile = (MobileLedgerProfile) ((View) view.getParent()).getTag();
+        editProfile(view, profile);
+    };
+    private boolean editingProfiles = false;
+    private RecyclerView recyclerView;
+    private ItemTouchHelper rearrangeHelper;
+    public ProfilesRecyclerViewAdapter() {
+        Data.profiles.addObserver((o, arg) -> {
+            Log.d("profiles", "profile list changed");
+            if (arg == null) notifyDataSetChanged();
+            else notifyItemChanged((int) arg);
+        });
+
+        ItemTouchHelper.Callback cb = new ItemTouchHelper.Callback() {
+            @Override
+            public int getMovementFlags(@NonNull RecyclerView recyclerView,
+                                        @NonNull RecyclerView.ViewHolder viewHolder) {
+                return makeMovementFlags(ItemTouchHelper.UP | ItemTouchHelper.DOWN, 0);
+            }
+            @Override
+            public boolean onMove(@NonNull RecyclerView recyclerView,
+                                  @NonNull RecyclerView.ViewHolder viewHolder,
+                                  @NonNull RecyclerView.ViewHolder target) {
+                Collections.swap(Data.profiles.getList(), viewHolder.getAdapterPosition(),
+                        target.getAdapterPosition());
+                MobileLedgerProfile.storeProfilesOrder();
+                notifyItemMoved(viewHolder.getAdapterPosition(), target.getAdapterPosition());
+                return true;
+            }
+            @Override
+            public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
+            }
+        };
+        rearrangeHelper = new ItemTouchHelper(cb);
+    }
+    @Override
+    public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
+        rearrangeHelper.attachToRecyclerView(null);
+        super.onDetachedFromRecyclerView(recyclerView);
+        this.recyclerView = null;
+    }
+    @Override
+    public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
+        super.onAttachedToRecyclerView(recyclerView);
+        this.recyclerView = recyclerView;
+        rearrangeHelper.attachToRecyclerView(recyclerView);
+    }
+    public boolean editingProfiles() {
+        return this.editingProfiles;
+    }
+    public void startEditingProfiles() {
+        if (editingProfiles) return;
+        this.editingProfiles = true;
+        notifyDataSetChanged();
+        rearrangeHelper.attachToRecyclerView(recyclerView);
+    }
+    public void stopEditingProfiles() {
+        if (!editingProfiles) return;
+        this.editingProfiles = false;
+        notifyDataSetChanged();
+        rearrangeHelper.attachToRecyclerView(null);
+    }
+    public void flipEditingProfiles() {
+        if (editingProfiles) stopEditingProfiles();
+        else startEditingProfiles();
+    }
+    private void editProfile(View view, MobileLedgerProfile profile) {
+        int index = Data.profiles.indexOf(profile);
+        Context context = view.getContext();
+        Intent intent = new Intent(context, ProfileDetailActivity.class);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION);
+        if (index != -1) intent.putExtra(ProfileDetailFragment.ARG_ITEM_ID, index);
+
+        context.startActivity(intent);
+    }
+    @NonNull
+    @Override
+    public ProfileListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+        View view = LayoutInflater.from(parent.getContext())
+                .inflate(R.layout.profile_list_content, parent, false);
+        ProfileListViewHolder holder = new ProfileListViewHolder(view);
+
+        holder.mTitle.setOnClickListener(v -> {
+            View row = (View) v.getParent();
+            MobileLedgerProfile profile = (MobileLedgerProfile) row.getTag();
+            if (profile == null)
+                throw new IllegalStateException("Profile row without associated profile");
+            Log.d("profiles", "Setting profile to " + profile.getName());
+            Data.setCurrentProfile(profile);
+        });
+        holder.mTitle.setOnLongClickListener(v -> {
+            flipEditingProfiles();
+            return true;
+        });
+        Data.profile.addObserver((o, arg) -> {
+            MobileLedgerProfile myProfile = (MobileLedgerProfile) holder.itemView.getTag();
+            final MobileLedgerProfile currentProfile = Data.profile.get();
+            final boolean sameProfile = currentProfile.equals(myProfile);
+            view.setAlpha(sameProfile ? 1 : 0.5f);
+        });
+        return holder;
+    }
+    @Override
+    public void onBindViewHolder(@NonNull final ProfileListViewHolder holder, int position) {
+        final MobileLedgerProfile profile = Data.profiles.get(position);
+        final MobileLedgerProfile currentProfile = Data.profile.get();
+        Log.d("profiles", String.format("pos %d: %s, current: %s", position, profile.getUuid(),
+                (currentProfile == null) ? "<NULL>" : currentProfile.getUuid()));
+        holder.itemView.setTag(profile);
+
+        int hue = profile.getThemeId();
+        if (hue == -1) holder.mColorTag.setBackgroundColor(Color.TRANSPARENT);
+        else holder.mColorTag.setBackgroundColor(Colors.getPrimaryColorForHue(hue));
+
+        holder.mTitle.setText(profile.getName());
+//            holder.mSubTitle.setText(profile.getUrl());
+
+        holder.mEditButton.setOnClickListener(mOnClickListener);
+
+        final boolean sameProfile = currentProfile.equals(profile);
+        holder.itemView.setAlpha(sameProfile ? 1 : 0.5f);
+        holder.itemView
+                .setBackground(sameProfile ? new ColorDrawable(Colors.tableRowLightBG) : null);
+        if (editingProfiles) {
+            holder.mRearrangeHandle.setVisibility(View.VISIBLE);
+            holder.mEditButton.setVisibility(View.VISIBLE);
+        }
+        else {
+            holder.mRearrangeHandle.setVisibility(View.GONE);
+            holder.mEditButton.setVisibility(View.GONE);
+        }
+    }
+    @Override
+    public int getItemCount() {
+        return Data.profiles.size();
+    }
+    class ProfileListViewHolder extends RecyclerView.ViewHolder {
+        final TextView mEditButton;
+        final TextView mTitle, mColorTag;
+        final ImageView mRearrangeHandle;
+
+        ProfileListViewHolder(View view) {
+            super(view);
+            mEditButton = view.findViewById(R.id.profile_list_edit_button);
+            mTitle = view.findViewById(R.id.title);
+            mColorTag = view.findViewById(R.id.colorTag);
+            mRearrangeHandle = view.findViewById(R.id.profile_list_rearrange_handle);
+        }
+    }
+}
diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/profiles/dummy/DummyContent.java b/app/src/main/java/net/ktnx/mobileledger/ui/profiles/dummy/DummyContent.java
new file mode 100644 (file)
index 0000000..4100c51
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright © 2019 Damyan Ivanov.
+ *  This file is part of MoLe.
+ *  MoLe is free software: you can distribute it and/or modify it
+ *  under the term of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your opinion), any later version.
+ *
+ *  MoLe 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 terms for details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Mobile-Ledger. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package net.ktnx.mobileledger.ui.profiles.dummy;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Helper class for providing sample content for user interfaces created by
+ * Android template wizards.
+ * <p>
+ * TODO: Replace all uses of this class before publishing your app.
+ */
+public class DummyContent {
+
+    /**
+     * An array of sample (dummy) items.
+     */
+    public static final List<DummyItem> ITEMS = new ArrayList<DummyItem>();
+
+    /**
+     * A map of sample (dummy) items, by ID.
+     */
+    public static final Map<String, DummyItem> ITEM_MAP = new HashMap<String, DummyItem>();
+
+    private static final int COUNT = 25;
+
+    static {
+        // Add some sample items.
+        for (int i = 1; i <= COUNT; i++) {
+            addItem(createDummyItem(i));
+        }
+    }
+
+    private static void addItem(DummyItem item) {
+        ITEMS.add(item);
+        ITEM_MAP.put(item.id, item);
+    }
+
+    private static DummyItem createDummyItem(int position) {
+        return new DummyItem(String.valueOf(position), "Item " + position, makeDetails(position));
+    }
+
+    private static String makeDetails(int position) {
+        StringBuilder builder = new StringBuilder();
+        builder.append("Details about Item: ").append(position);
+        for (int i = 0; i < position; i++) {
+            builder.append("\nMore details information here.");
+        }
+        return builder.toString();
+    }
+
+    /**
+     * A dummy item representing a piece of content.
+     */
+    public static class DummyItem {
+        public final String id;
+        public final String content;
+        public final String details;
+
+        public DummyItem(String id, String content, String details) {
+            this.id = id;
+            this.content = content;
+            this.details = details;
+        }
+
+        @Override
+        public String toString() {
+            return content;
+        }
+    }
+}
diff --git a/app/src/main/res/anim/layout_slide_down.xml b/app/src/main/res/anim/layout_slide_down.xml
new file mode 100644 (file)
index 0000000..6efb0da
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright © 2019 Damyan Ivanov.
+  ~  This file is part of MoLe.
+  ~  MoLe is free software: you can distribute it and/or modify it
+  ~  under the term of the GNU General Public License as published by
+  ~  the Free Software Foundation, either version 3 of the License, or
+  ~  (at your opinion), any later version.
+  ~
+  ~  MoLe 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 terms for details.
+  ~
+  ~  You should have received a copy of the GNU General Public License
+  ~  along with Mobile-Ledger. If not, see <https://www.gnu.org/licenses/>.
+  -->
+
+<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
+    android:animation="@anim/slide_in_right"
+    android:interpolator="@android:anim/accelerate_decelerate_interpolator" />
\ No newline at end of file
diff --git a/app/src/main/res/anim/rotate_180.xml b/app/src/main/res/anim/rotate_180.xml
new file mode 100644 (file)
index 0000000..f04f8ed
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright © 2019 Damyan Ivanov.
+  ~  This file is part of MoLe.
+  ~  MoLe is free software: you can distribute it and/or modify it
+  ~  under the term of the GNU General Public License as published by
+  ~  the Free Software Foundation, either version 3 of the License, or
+  ~  (at your opinion), any later version.
+  ~
+  ~  MoLe 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 terms for details.
+  ~
+  ~  You should have received a copy of the GNU General Public License
+  ~  along with Mobile-Ledger. If not, see <https://www.gnu.org/licenses/>.
+  -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    android:duration="@android:integer/config_shortAnimTime"
+    android:fillAfter="true">
+    <rotate
+        android:fromDegrees="0"
+        android:pivotX="50%"
+        android:pivotY="50%"
+        android:toDegrees="180" />
+</set>
\ No newline at end of file
diff --git a/app/src/main/res/anim/rotate_180_back.xml b/app/src/main/res/anim/rotate_180_back.xml
new file mode 100644 (file)
index 0000000..2bba978
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright © 2019 Damyan Ivanov.
+  ~  This file is part of MoLe.
+  ~  MoLe is free software: you can distribute it and/or modify it
+  ~  under the term of the GNU General Public License as published by
+  ~  the Free Software Foundation, either version 3 of the License, or
+  ~  (at your opinion), any later version.
+  ~
+  ~  MoLe 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 terms for details.
+  ~
+  ~  You should have received a copy of the GNU General Public License
+  ~  along with Mobile-Ledger. If not, see <https://www.gnu.org/licenses/>.
+  -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    android:duration="@android:integer/config_shortAnimTime"
+    android:fillAfter="true">
+    <rotate
+        android:fromDegrees="180"
+        android:pivotX="50%"
+        android:pivotY="50%"
+        android:toDegrees="0" />
+</set>
\ No newline at end of file
diff --git a/app/src/main/res/anim/slide_down.xml b/app/src/main/res/anim/slide_down.xml
new file mode 100644 (file)
index 0000000..a435507
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright © 2019 Damyan Ivanov.
+  ~  This file is part of MoLe.
+  ~  MoLe is free software: you can distribute it and/or modify it
+  ~  under the term of the GNU General Public License as published by
+  ~  the Free Software Foundation, either version 3 of the License, or
+  ~  (at your opinion), any later version.
+  ~
+  ~  MoLe 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 terms for details.
+  ~
+  ~  You should have received a copy of the GNU General Public License
+  ~  along with Mobile-Ledger. If not, see <https://www.gnu.org/licenses/>.
+  -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    android:duration="@android:integer/config_shortAnimTime"
+    android:fillAfter="true"
+    android:fillEnabled="true">
+    <scale
+        android:fillAfter="false"
+        android:fromYScale="0.0"
+        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
+        android:toYScale="1.0"
+        android:fromXScale="1.0"
+        android:toXScale="1.0"/>
+</set>
\ No newline at end of file
diff --git a/app/src/main/res/anim/slide_in_down.xml b/app/src/main/res/anim/slide_in_down.xml
new file mode 100644 (file)
index 0000000..620bb57
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright © 2019 Damyan Ivanov.
+  ~  This file is part of MoLe.
+  ~  MoLe is free software: you can distribute it and/or modify it
+  ~  under the term of the GNU General Public License as published by
+  ~  the Free Software Foundation, either version 3 of the License, or
+  ~  (at your opinion), any later version.
+  ~
+  ~  MoLe 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 terms for details.
+  ~
+  ~  You should have received a copy of the GNU General Public License
+  ~  along with Mobile-Ledger. If not, see <https://www.gnu.org/licenses/>.
+  -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    android:duration="@android:integer/config_shortAnimTime">
+    <translate
+        android:fromYDelta="-100%"
+        android:toYDelta="0%" />
+</set>
\ No newline at end of file
diff --git a/app/src/main/res/anim/slide_up.xml b/app/src/main/res/anim/slide_up.xml
new file mode 100644 (file)
index 0000000..a02516a
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright © 2019 Damyan Ivanov.
+  ~  This file is part of MoLe.
+  ~  MoLe is free software: you can distribute it and/or modify it
+  ~  under the term of the GNU General Public License as published by
+  ~  the Free Software Foundation, either version 3 of the License, or
+  ~  (at your opinion), any later version.
+  ~
+  ~  MoLe 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 terms for details.
+  ~
+  ~  You should have received a copy of the GNU General Public License
+  ~  along with Mobile-Ledger. If not, see <https://www.gnu.org/licenses/>.
+  -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    android:duration="@android:integer/config_shortAnimTime"
+    android:fillAfter="true"
+    android:fillEnabled="true">
+    <scale
+        android:fillAfter="false"
+        android:fromYScale="1.0"
+        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
+        android:toYScale="0.0"
+        android:fromXScale="1.0"
+        android:toXScale="1.0"/>
+</set>
\ No newline at end of file
diff --git a/app/src/main/res/drawable-anydpi-v21/ic_expand_more_black_24dp.xml b/app/src/main/res/drawable-anydpi-v21/ic_expand_more_black_24dp.xml
new file mode 100644 (file)
index 0000000..809847a
--- /dev/null
@@ -0,0 +1,21 @@
+<!--
+  ~ Copyright Google Inc.
+  ~
+  ~ Licensed under the Apache License, version 2.0 ("the License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the license at:
+  ~
+  ~ https://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distribution under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<vector android:height="24dp" android:tint="?colorAccent"
+    android:viewportHeight="24.0" android:viewportWidth="24.0"
+    android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="#FF000000" android:pathData="M16.59,8.59L12,13.17 7.41,8.59 6,10l6,6 6,-6z"/>
+</vector>
diff --git a/app/src/main/res/drawable-anydpi-v21/ic_keyboard_arrow_down_black_24dp.xml b/app/src/main/res/drawable-anydpi-v21/ic_keyboard_arrow_down_black_24dp.xml
new file mode 100644 (file)
index 0000000..7f0caed
--- /dev/null
@@ -0,0 +1,21 @@
+<!--
+  ~ Copyright Google Inc.
+  ~
+  ~ Licensed under the Apache License, version 2.0 ("the License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the license at:
+  ~
+  ~ https://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distribution under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<vector android:height="24dp" android:tint="?colorPrimary"
+    android:viewportHeight="24.0" android:viewportWidth="24.0"
+    android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="#FF000000" android:pathData="M7.41,7.84L12,12.42l4.59,-4.58L18,9.25l-6,6 -6,-6z"/>
+</vector>
diff --git a/app/src/main/res/drawable-anydpi-v21/ic_unfold_more_black_24dp.xml b/app/src/main/res/drawable-anydpi-v21/ic_unfold_more_black_24dp.xml
new file mode 100644 (file)
index 0000000..2d601d9
--- /dev/null
@@ -0,0 +1,21 @@
+<!--
+  ~ Copyright Google Inc.
+  ~
+  ~ Licensed under the Apache License, version 2.0 ("the License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the license at:
+  ~
+  ~ https://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distribution under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<vector android:height="24dp" android:tint="?colorAccent"
+    android:viewportHeight="24.0" android:viewportWidth="24.0"
+    android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="#FF000000" android:pathData="M12,5.83L15.17,9l1.41,-1.41L12,3 7.41,7.59 8.83,9 12,5.83zM12,18.17L8.83,15l-1.41,1.41L12,21l4.59,-4.59L15.17,15 12,18.17z"/>
+</vector>
index bd9f2f849c2f7f32def49e3b0f303c4189d7738a..e7cb8dba6c908c575d36711a93b27793781b34f5 100644 (file)
             <include layout="@layout/no_profiles" />
         </androidx.constraintlayout.widget.ConstraintLayout>
 
-        <com.google.android.material.navigation.NavigationView
-            android:id="@+id/nav_view"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_gravity="start"
-            android:fitsSystemWindows="true"
-            android:theme="@style/ThemeOverlay.AppCompat.Light">
-
-
-            <androidx.constraintlayout.widget.ConstraintLayout
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:layout_marginBottom="0dp"
-                android:orientation="vertical">
-
-                <LinearLayout
-                    android:id="@+id/nav_fixed_items"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:divider="@drawable/list_divider"
-                    android:elevation="2dp"
-                    android:orientation="vertical"
-                    android:showDividers="beginning"
-                    app:layout_constraintBottom_toBottomOf="parent">
-
-                    <TextView
-                        android:id="@+id/nav_profiles"
-                        style="@style/nav_button"
-                        android:layout_width="match_parent"
-                        android:layout_weight="1"
-                        android:drawableStart="@drawable/ic_view_list_black_24dp"
-                        android:onClick="navProfilesClicked"
-                        android:text="@string/profiles" />
-
-                    <TextView
-                        android:id="@+id/textView2"
-                        style="@style/nav_button"
-                        android:layout_weight="1"
-                        android:drawableStart="@drawable/ic_settings_black_24dp"
-                        android:onClick="navSettingsClicked"
-                        android:text="@string/action_settings" />
-
-                </LinearLayout>
-
-                <ScrollView
-                    android:layout_width="0dp"
-                    android:layout_height="0dp"
-                    app:layout_constraintBottom_toTopOf="@+id/nav_fixed_items"
-                    app:layout_constraintEnd_toEndOf="parent"
-                    app:layout_constraintLeft_toLeftOf="parent"
-                    app:layout_constraintStart_toStartOf="parent"
-                    app:layout_constraintTop_toTopOf="parent">
-
-                    <LinearLayout
-                        android:id="@+id/nav_upper"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:divider="@drawable/list_divider_inside_out"
-                        android:orientation="vertical"
-                        android:showDividers="beginning"
-                        app:layout_constraintBottom_toTopOf="@+id/nav_fixed_items"
-                        app:layout_constraintTop_toBottomOf="@+id/nav_header">
-
-                        <LinearLayout
-                            android:id="@+id/nav_header"
-                            android:layout_width="match_parent"
-                            android:layout_height="wrap_content"
-                            android:background="@drawable/side_nav_bar"
-                            android:gravity="center_vertical"
-                            android:orientation="horizontal"
-                            android:padding="@dimen/activity_vertical_margin"
-                            android:theme="@style/ThemeOverlay.AppCompat.Dark"
-                            app:layout_constraintTop_toTopOf="parent">
-
-                            <include layout="@layout/nav_header_logo" />
-
-                            <LinearLayout
-                                android:layout_width="match_parent"
-                                android:layout_height="match_parent"
-                                android:layout_marginStart="@dimen/activity_horizontal_margin"
-                                android:layout_marginEnd="@dimen/activity_horizontal_margin"
-                                android:gravity="center_vertical"
-                                android:orientation="vertical">
-
-                                <TextView
-                                    android:layout_width="match_parent"
-                                    android:layout_height="wrap_content"
-                                    android:text="@string/app_name"
-                                    android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
-
-                                <TextView
-                                    android:id="@+id/drawer_version_text"
-                                    android:layout_width="wrap_content"
-                                    android:layout_height="wrap_content"
-                                    android:text="dummy version"
-                                    tools:ignore="HardcodedText" />
-                            </LinearLayout>
-
-                        </LinearLayout>
-
-                        <LinearLayout
-                            android:id="@+id/nav_actions"
-                            android:layout_width="match_parent"
-                            android:layout_height="match_parent"
-                            android:orientation="vertical">
-
-                            <TextView
-                                android:id="@+id/nav_account_summary"
-                                style="@style/nav_button"
-                                android:drawableStart="@drawable/ic_home_black_24dp"
-                                android:onClick="onAccountSummaryClicked"
-                                android:text="@string/account_summary_title" />
-
-                            <TextView
-                                android:id="@+id/nav_latest_transactions"
-                                style="@style/nav_button"
-                                android:drawableStart="@drawable/ic_event_note_black_24dp"
-                                android:onClick="onLatestTransactionsClicked"
-                                android:text="@string/nav_latest_transactions_title" />
-
-                            <TextView
-                                android:id="@+id/textView5"
-                                style="@style/nav_button"
-                                android:drawableStart="@drawable/ic_assignment_black_24dp"
-                                android:text="@string/nav_reports_title" />
-
-                        </LinearLayout>
-
-                    </LinearLayout>
-                </ScrollView>
-
-            </androidx.constraintlayout.widget.ConstraintLayout>
-
-        </com.google.android.material.navigation.NavigationView>
+        <include layout="@layout/main_navigation" />
 
     </androidx.drawerlayout.widget.DrawerLayout>
 </LinearLayout>
diff --git a/app/src/main/res/layout/main_navigation.xml b/app/src/main/res/layout/main_navigation.xml
new file mode 100644 (file)
index 0000000..4f4f5c5
--- /dev/null
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright © 2019 Damyan Ivanov.
+  ~  This file is part of MoLe.
+  ~  MoLe is free software: you can distribute it and/or modify it
+  ~  under the term of the GNU General Public License as published by
+  ~  the Free Software Foundation, either version 3 of the License, or
+  ~  (at your opinion), any later version.
+  ~
+  ~  MoLe 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 terms for details.
+  ~
+  ~  You should have received a copy of the GNU General Public License
+  ~  along with Mobile-Ledger. If not, see <https://www.gnu.org/licenses/>.
+  -->
+
+<com.google.android.material.navigation.NavigationView 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:id="@+id/nav_view"
+    android:layout_width="wrap_content"
+    android:layout_height="match_parent"
+    android:layout_gravity="start"
+    android:fitsSystemWindows="true"
+    android:theme="@style/ThemeOverlay.AppCompat.Light"
+    tools:showIn="@layout/activity_main">
+
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_marginBottom="0dp"
+        android:animateLayoutChanges="true"
+        android:orientation="vertical">
+
+        <LinearLayout
+            android:id="@+id/nav_fixed_items"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:divider="@drawable/list_divider"
+            android:elevation="2dp"
+            android:orientation="vertical"
+            android:showDividers="beginning"
+            app:layout_constraintBottom_toBottomOf="parent">
+
+            <TextView
+                android:id="@+id/textView2"
+                style="@style/nav_button"
+                android:layout_weight="1"
+                android:drawableStart="@drawable/ic_settings_black_24dp"
+                android:onClick="navSettingsClicked"
+                android:text="@string/action_settings" />
+
+        </LinearLayout>
+
+        <ScrollView
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            app:layout_constraintBottom_toTopOf="@+id/nav_fixed_items"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintLeft_toLeftOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent">
+
+            <LinearLayout
+                android:id="@+id/nav_upper"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:animateLayoutChanges="true"
+                android:divider="@drawable/list_divider_inside_out"
+                android:orientation="vertical"
+                android:showDividers="beginning"
+                app:layout_constraintBottom_toTopOf="@+id/nav_fixed_items"
+                app:layout_constraintTop_toBottomOf="@+id/nav_header">
+
+                <LinearLayout
+                    android:id="@+id/nav_header"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:background="@drawable/side_nav_bar"
+                    android:gravity="center_vertical"
+                    android:orientation="horizontal"
+                    android:padding="@dimen/activity_vertical_margin"
+                    android:theme="@style/ThemeOverlay.AppCompat.Dark"
+                    app:layout_constraintTop_toTopOf="parent">
+
+                    <include layout="@layout/nav_header_logo" />
+
+                    <LinearLayout
+                        android:layout_width="match_parent"
+                        android:layout_height="match_parent"
+                        android:layout_marginStart="@dimen/activity_horizontal_margin"
+                        android:layout_marginEnd="@dimen/activity_horizontal_margin"
+                        android:gravity="center_vertical"
+                        android:orientation="vertical">
+
+                        <TextView
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:text="@string/app_name"
+                            android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
+
+                        <TextView
+                            android:id="@+id/drawer_version_text"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:text="dummy version"
+                            tools:ignore="HardcodedText" />
+                    </LinearLayout>
+
+                </LinearLayout>
+
+                <LinearLayout
+                    android:id="@+id/nav_actions"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:orientation="vertical">
+
+                    <TextView
+                        android:id="@+id/nav_account_summary"
+                        style="@style/nav_button"
+                        android:drawableStart="@drawable/ic_home_black_24dp"
+                        android:onClick="onAccountSummaryClicked"
+                        android:text="@string/account_summary_title" />
+
+                    <TextView
+                        android:id="@+id/nav_latest_transactions"
+                        style="@style/nav_button"
+                        android:drawableStart="@drawable/ic_event_note_black_24dp"
+                        android:onClick="onLatestTransactionsClicked"
+                        android:text="@string/nav_latest_transactions_title" />
+
+                    <TextView
+                        android:id="@+id/textView5"
+                        style="@style/nav_button"
+                        android:drawableStart="@drawable/ic_assignment_black_24dp"
+                        android:text="@string/nav_reports_title" />
+
+                    <include layout="@layout/nav_profile_list_head" />
+
+                    <LinearLayout
+                        android:id="@+id/nav_profile_list_container"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:animateLayoutChanges="true"
+                        android:orientation="vertical"
+                        android:visibility="gone">
+
+                        <androidx.recyclerview.widget.RecyclerView
+                            android:id="@+id/nav_profile_list"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:orientation="vertical"
+                            android:paddingStart="0dp">
+
+                        </androidx.recyclerview.widget.RecyclerView>
+
+                        <include layout="@layout/nav_profile_list_new_profile_row" />
+                    </LinearLayout>
+
+                </LinearLayout>
+
+            </LinearLayout>
+        </ScrollView>
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+</com.google.android.material.navigation.NavigationView>
\ No newline at end of file
diff --git a/app/src/main/res/layout/nav_profile_list_head.xml b/app/src/main/res/layout/nav_profile_list_head.xml
new file mode 100644 (file)
index 0000000..540ded5
--- /dev/null
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+  ~ Copyright © 2019 Damyan Ivanov.
+  ~  This file is part of MoLe.
+  ~  MoLe is free software: you can distribute it and/or modify it
+  ~  under the term of the GNU General Public License as published by
+  ~  the Free Software Foundation, either version 3 of the License, or
+  ~  (at your opinion), any later version.
+  ~
+  ~  MoLe 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 terms for details.
+  ~
+  ~  You should have received a copy of the GNU General Public License
+  ~  along with Mobile-Ledger. If not, see <https://www.gnu.org/licenses/>.
+  -->
+
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="@dimen/thumb_row_height"
+    android:paddingEnd="@dimen/activity_horizontal_margin">
+
+    <TextView
+        android:id="@+id/nav_profiles_arrow"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:drawableStart="@drawable/ic_expand_more_black_24dp"
+        android:gravity="end|center_vertical"
+        android:onClick="navProfilesHeadClicked"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <TextView
+        android:id="@+id/nav_profiles_label"
+        style="@style/nav_button"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:layout_marginEnd="8dp"
+        android:drawableStart="@drawable/ic_view_list_black_24dp"
+        android:gravity="start|center_vertical"
+        android:text="@string/profiles"
+        android:onClick="navProfilesHeadClicked"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toStartOf="@+id/nav_profiles_arrow"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/nav_profile_list_new_profile_row.xml b/app/src/main/res/layout/nav_profile_list_new_profile_row.xml
new file mode 100644 (file)
index 0000000..d93743a
--- /dev/null
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright © 2019 Damyan Ivanov.
+  ~  This file is part of MoLe.
+  ~  MoLe is free software: you can distribute it and/or modify it
+  ~  under the term of the GNU General Public License as published by
+  ~  the Free Software Foundation, either version 3 of the License, or
+  ~  (at your opinion), any later version.
+  ~
+  ~  MoLe 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 terms for details.
+  ~
+  ~  You should have received a copy of the GNU General Public License
+  ~  along with Mobile-Ledger. If not, see <https://www.gnu.org/licenses/>.
+  -->
+
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/nav_new_profile_button"
+        android:layout_width="wrap_content"
+        android:layout_height="@dimen/thumb_row_height"
+        android:drawableStart="@drawable/ic_add_circle_white_24dp"
+        android:gravity="center_horizontal|center_vertical"
+        android:paddingStart="@dimen/activity_horizontal_margin"
+        android:paddingEnd="@dimen/activity_horizontal_margin"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
index c1b1087e1f6e20ec2f5b6c762f913bb7bfaf5833..0f23c761c25fb34d5657550e59ac43c303eeb382 100644 (file)
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:id="@+id/profile_list_item"
+    android:alpha="0.50"
+    android:animateLayoutChanges="true"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content"
+    android:layout_height="@dimen/thumb_row_height"
     android:layout_gravity="center_horizontal"
     android:foregroundGravity="center_vertical">
 
     <TextView
         android:id="@+id/colorTag"
-        android:layout_width="@dimen/activity_horizontal_margin"
+        android:layout_width="16dp"
         android:layout_height="0dp"
+        android:layout_marginStart="32dp"
+        android:layout_marginTop="4dp"
+        android:layout_marginBottom="4dp"
         android:background="?colorPrimary"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintStart_toStartOf="parent"
         android:id="@+id/profile_list_edit_button"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginEnd="16dp"
+        android:layout_marginEnd="8dp"
         android:layout_weight="9"
         android:drawableStart="@drawable/ic_mode_edit_black_24dp"
         android:padding="8dp"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintTop_toTopOf="parent" />
+        app:layout_constraintTop_toTopOf="parent"
+        android:visibility="invisible"/>
 
-    <RadioButton
-        android:id="@+id/profile_list_radio"
+    <ImageView
+        android:id="@+id/profile_list_rearrange_handle"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginStart="16dp"
         android:layout_weight="9"
+        android:background="@drawable/ic_unfold_more_black_24dp"
+        android:visibility="gone"
+        android:layout_marginStart="@dimen/activity_horizontal_margin"
         app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent"
-        tools:ignore="HardcodedText" />
+        app:layout_constraintStart_toEndOf="@id/colorTag"
+        app:layout_constraintEnd_toStartOf="@id/title"/>
 
     <TextView
         android:id="@+id/title"
-        style="@style/TextAppearance.AppCompat.Large"
+        style="@style/TextAppearance.AppCompat.Medium"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
-        android:layout_marginStart="16dp"
-        android:layout_marginTop="@dimen/nav_header_vertical_spacing"
-        android:layout_marginEnd="16dp"
+        android:layout_marginStart="8dp"
+        android:layout_marginEnd="8dp"
+        android:gravity="center_vertical"
+        android:paddingStart="@dimen/activity_horizontal_margin"
         android:text="Profile name"
+        app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toStartOf="@id/profile_list_edit_button"
-        app:layout_constraintStart_toEndOf="@id/profile_list_radio"
+        app:layout_constraintStart_toEndOf="@id/profile_list_rearrange_handle"
         app:layout_constraintTop_toTopOf="parent"
         tools:ignore="HardcodedText" />
 
-    <TextView
-        android:id="@+id/subtitle"
-        style="@style/TextAppearance.AppCompat.Medium"
-        android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="16dp"
-        android:layout_marginEnd="16dp"
-        android:layout_marginBottom="@dimen/nav_header_vertical_spacing"
-        android:text="Sub-heading"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toStartOf="@id/profile_list_edit_button"
-        app:layout_constraintStart_toEndOf="@id/profile_list_radio"
-        app:layout_constraintTop_toBottomOf="@id/title"
-        tools:ignore="HardcodedText" />
+    <!--<TextView-->
+        <!--android:id="@+id/subtitle"-->
+        <!--style="@style/TextAppearance.AppCompat.Small"-->
+        <!--android:layout_width="0dp"-->
+        <!--android:layout_height="wrap_content"-->
+        <!--android:layout_marginStart="8dp"-->
+        <!--android:layout_marginEnd="8dp"-->
+        <!--android:layout_marginBottom="4dp"-->
+        <!--android:text="Sub-heading"-->
+        <!--app:layout_constraintBottom_toBottomOf="parent"-->
+        <!--app:layout_constraintEnd_toStartOf="@id/profile_list_edit_button"-->
+        <!--app:layout_constraintStart_toEndOf="@id/profile_list_radio"-->
+        <!--app:layout_constraintTop_toBottomOf="@id/title"-->
+        <!--tools:ignore="HardcodedText" />-->
 
 
 </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
index aa98a23cd743c6baf6b781d2da39f9400a1dc6bf..c7315af10faea8e8f0794f11220a3b88a73246e2 100644 (file)
 
 <resources>
 
-    <style name="nav_button">
+    <style name="nav_button" parent="Base.TextAppearance.AppCompat.Medium">
         <item name="android:layout_width">match_parent</item>
-        <item name="android:layout_height">48dp</item>
+        <item name="android:layout_height">56dp</item>
         <item name="android:clickable">true</item>
-        <item name="android:drawablePadding">36dp</item>
+        <item name="android:drawablePadding">@dimen/activity_horizontal_margin</item>
         <item name="android:focusable">auto</item>
         <item name="android:gravity">center_vertical|start</item>
         <item name="android:paddingStart">@dimen/activity_horizontal_margin</item>
         <item name="android:paddingEnd">@dimen/activity_horizontal_margin</item>
+        <!--<item name="android:textSize">16sp</item>-->
     </style>
 </resources>
\ No newline at end of file
index cdc6d5a0c90552c0fa002d22c50810790c3a594b..21eb5e363a0dc4ed147f7aed1a6c3a451409f9fc 100644 (file)
 
     <style name="nav_button">
         <item name="android:layout_width">match_parent</item>
-        <item name="android:layout_height">40dp</item>
+        <item name="android:layout_height">@dimen/thumb_row_height</item>
+        <item name="android:drawablePadding">@dimen/activity_horizontal_margin</item>
         <item name="android:clickable">true</item>
-        <item name="android:drawablePadding">24dp</item>
         <item name="android:focusable">auto</item>
         <item name="android:gravity">center_vertical|start</item>
         <item name="android:paddingStart">@dimen/activity_horizontal_margin</item>
         <item name="android:layout_height">match_parent</item>
     </style>
 
+    <dimen name="thumb_row_height">40dp</dimen>
 </resources>