Add menu drawer
This commit is contained in:
parent
82cc4760cf
commit
13d06d8905
@ -27,6 +27,7 @@ import com.cringe_studios.cringe_authenticator.databinding.DialogInputCodeChoice
|
|||||||
import com.cringe_studios.cringe_authenticator.fragment.AboutFragment;
|
import com.cringe_studios.cringe_authenticator.fragment.AboutFragment;
|
||||||
import com.cringe_studios.cringe_authenticator.fragment.GroupFragment;
|
import com.cringe_studios.cringe_authenticator.fragment.GroupFragment;
|
||||||
import com.cringe_studios.cringe_authenticator.fragment.HomeFragment;
|
import com.cringe_studios.cringe_authenticator.fragment.HomeFragment;
|
||||||
|
import com.cringe_studios.cringe_authenticator.fragment.MenuDrawerFragment;
|
||||||
import com.cringe_studios.cringe_authenticator.fragment.MenuFragment;
|
import com.cringe_studios.cringe_authenticator.fragment.MenuFragment;
|
||||||
import com.cringe_studios.cringe_authenticator.fragment.NamedFragment;
|
import com.cringe_studios.cringe_authenticator.fragment.NamedFragment;
|
||||||
import com.cringe_studios.cringe_authenticator.fragment.SettingsFragment;
|
import com.cringe_studios.cringe_authenticator.fragment.SettingsFragment;
|
||||||
@ -143,7 +144,8 @@ public class MainActivity extends BaseActivity {
|
|||||||
|
|
||||||
setSupportActionBar(binding.toolbar);
|
setSupportActionBar(binding.toolbar);
|
||||||
|
|
||||||
binding.fabMenu.setOnClickListener(view -> NavigationUtil.navigate(this, MenuFragment.class, null));
|
//binding.fabMenu.setOnClickListener(view -> NavigationUtil.navigate(this, MenuFragment.class, null)); TODO: remove old menu
|
||||||
|
binding.fabMenu.setOnClickListener(view -> NavigationUtil.openMenu(this, null));
|
||||||
binding.fabScan.setOnClickListener(view -> scanCode());
|
binding.fabScan.setOnClickListener(view -> scanCode());
|
||||||
binding.fabScanImage.setOnClickListener(view -> scanCodeFromImage());
|
binding.fabScanImage.setOnClickListener(view -> scanCodeFromImage());
|
||||||
binding.fabInput.setOnClickListener(view -> inputCode());
|
binding.fabInput.setOnClickListener(view -> inputCode());
|
||||||
@ -155,6 +157,8 @@ public class MainActivity extends BaseActivity {
|
|||||||
}else {
|
}else {
|
||||||
NavigationUtil.navigate(this, HomeFragment.class, null);
|
NavigationUtil.navigate(this, HomeFragment.class, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new MenuDrawerFragment().show(getSupportFragmentManager(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -0,0 +1,134 @@
|
|||||||
|
package com.cringe_studios.cringe_authenticator.fragment;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.cringe_studios.cringe_authenticator.R;
|
||||||
|
import com.cringe_studios.cringe_authenticator.databinding.FragmentMenuDrawerBinding;
|
||||||
|
import com.cringe_studios.cringe_authenticator.grouplist.GroupListAdapter;
|
||||||
|
import com.cringe_studios.cringe_authenticator.grouplist.GroupListItem;
|
||||||
|
import com.cringe_studios.cringe_authenticator.util.DialogUtil;
|
||||||
|
import com.cringe_studios.cringe_authenticator.util.FabUtil;
|
||||||
|
import com.cringe_studios.cringe_authenticator.util.NavigationUtil;
|
||||||
|
import com.cringe_studios.cringe_authenticator.util.SettingsUtil;
|
||||||
|
import com.cringe_studios.cringe_authenticator.util.StyledDialogBuilder;
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class MenuDrawerFragment extends BottomSheetDialogFragment {
|
||||||
|
|
||||||
|
private FragmentMenuDrawerBinding binding;
|
||||||
|
|
||||||
|
private GroupListAdapter groupListAdapter;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||||
|
binding = FragmentMenuDrawerBinding.inflate(inflater);
|
||||||
|
|
||||||
|
groupListAdapter = new GroupListAdapter(requireContext(), binding.menuItems, group -> {
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putString(GroupFragment.BUNDLE_GROUP, group);
|
||||||
|
NavigationUtil.navigate(this, GroupFragment.class, bundle);
|
||||||
|
getParentFragmentManager().beginTransaction().remove(this).commit();
|
||||||
|
}, () -> SettingsUtil.setGroups(requireContext(), groupListAdapter.getItems()), this::updateToolbarOptions);
|
||||||
|
binding.menuItems.setAdapter(groupListAdapter);
|
||||||
|
|
||||||
|
binding.menuAdd.setOnClickListener(view -> this.addGroup());
|
||||||
|
binding.menuEdit.setOnClickListener(view -> this.editGroup());
|
||||||
|
binding.menuDelete.setOnClickListener(view -> this.removeSelectedGroups());
|
||||||
|
|
||||||
|
loadGroups();
|
||||||
|
updateToolbarOptions();
|
||||||
|
|
||||||
|
return binding.getRoot();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateToolbarOptions() {
|
||||||
|
binding.menuEdit.setVisibility(isEditing() && !hasSelectedMultipleItems() ? View.VISIBLE : View.GONE);
|
||||||
|
binding.menuDelete.setVisibility(isEditing() ? View.VISIBLE : View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadGroups() {
|
||||||
|
List<String> items = SettingsUtil.getGroups(requireContext());
|
||||||
|
|
||||||
|
for(String item : items) {
|
||||||
|
groupListAdapter.add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addGroup() {
|
||||||
|
DialogUtil.showCreateGroupDialog(getLayoutInflater(), null, groupName -> {
|
||||||
|
String id = UUID.randomUUID().toString();
|
||||||
|
SettingsUtil.addGroup(requireContext(), id, groupName);
|
||||||
|
groupListAdapter.add(id);
|
||||||
|
}, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void editGroup() {
|
||||||
|
if(!groupListAdapter.isEditing()) return;
|
||||||
|
|
||||||
|
List<GroupListItem> items = groupListAdapter.getSelectedGroups();
|
||||||
|
if(items.size() != 1) return;
|
||||||
|
|
||||||
|
String group = items.get(0).getGroupId();
|
||||||
|
|
||||||
|
DialogUtil.showCreateGroupDialog(getLayoutInflater(), SettingsUtil.getGroupName(requireContext(), group), newName -> { // TODO: edit group dialog (with "Edit Group" title)
|
||||||
|
renameGroup(group, newName);
|
||||||
|
groupListAdapter.finishEditing();
|
||||||
|
}, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeSelectedGroups() {
|
||||||
|
if(!groupListAdapter.isEditing()) return;
|
||||||
|
|
||||||
|
new StyledDialogBuilder(requireContext())
|
||||||
|
.setTitle(R.string.group_delete_title)
|
||||||
|
.setMessage(R.string.group_delete_message)
|
||||||
|
.setPositiveButton(R.string.yes, (d, w) -> {
|
||||||
|
for(GroupListItem item : groupListAdapter.getSelectedGroups()) {
|
||||||
|
removeGroup(item.getGroupId());
|
||||||
|
}
|
||||||
|
|
||||||
|
groupListAdapter.finishEditing();
|
||||||
|
})
|
||||||
|
.setNegativeButton(R.string.no, (d, w) -> {})
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeGroup(String group) {
|
||||||
|
SettingsUtil.removeGroup(requireContext(), group);
|
||||||
|
groupListAdapter.remove(group);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void renameGroup(String group, String newName) {
|
||||||
|
SettingsUtil.setGroupName(requireContext(), group, newName);
|
||||||
|
groupListAdapter.update(group);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEditing() {
|
||||||
|
return groupListAdapter.isEditing();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void finishEditing() {
|
||||||
|
groupListAdapter.finishEditing();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasSelectedMultipleItems() {
|
||||||
|
return groupListAdapter.getSelectedGroups().size() > 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyView() {
|
||||||
|
super.onDestroyView();
|
||||||
|
this.binding = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -44,7 +44,7 @@ public class MenuFragment extends NamedFragment {
|
|||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
bundle.putString(GroupFragment.BUNDLE_GROUP, group);
|
bundle.putString(GroupFragment.BUNDLE_GROUP, group);
|
||||||
NavigationUtil.navigate(this, GroupFragment.class, bundle);
|
NavigationUtil.navigate(this, GroupFragment.class, bundle);
|
||||||
}, () -> SettingsUtil.setGroups(requireContext(), groupListAdapter.getItems()));
|
}, () -> SettingsUtil.setGroups(requireContext(), groupListAdapter.getItems()), requireActivity()::invalidateMenu);
|
||||||
binding.menuItems.setAdapter(groupListAdapter);
|
binding.menuItems.setAdapter(groupListAdapter);
|
||||||
|
|
||||||
loadGroups();
|
loadGroups();
|
||||||
|
@ -42,13 +42,16 @@ public class GroupListAdapter extends RecyclerView.Adapter<GroupListItem> {
|
|||||||
|
|
||||||
private Runnable saveGroups;
|
private Runnable saveGroups;
|
||||||
|
|
||||||
|
private Runnable updateToolbarOptions;
|
||||||
|
|
||||||
private boolean editing;
|
private boolean editing;
|
||||||
|
|
||||||
public GroupListAdapter(Context context, RecyclerView recyclerView, Consumer<String> navigateToGroup, Runnable saveGroups) {
|
public GroupListAdapter(Context context, RecyclerView recyclerView, Consumer<String> navigateToGroup, Runnable saveGroups, Runnable updateToolbarOptions) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.recyclerView = recyclerView;
|
this.recyclerView = recyclerView;
|
||||||
this.navigateToGroup = navigateToGroup;
|
this.navigateToGroup = navigateToGroup;
|
||||||
this.saveGroups = saveGroups;
|
this.saveGroups = saveGroups;
|
||||||
|
this.updateToolbarOptions = updateToolbarOptions;
|
||||||
this.inflater = LayoutInflater.from(context);
|
this.inflater = LayoutInflater.from(context);
|
||||||
this.items = new ArrayList<>();
|
this.items = new ArrayList<>();
|
||||||
this.handler = new Handler(Looper.getMainLooper());
|
this.handler = new Handler(Looper.getMainLooper());
|
||||||
@ -78,7 +81,7 @@ public class GroupListAdapter extends RecyclerView.Adapter<GroupListItem> {
|
|||||||
}else {
|
}else {
|
||||||
holder.setSelected(!holder.isSelected());
|
holder.setSelected(!holder.isSelected());
|
||||||
if(getSelectedGroups().isEmpty()) editing = false;
|
if(getSelectedGroups().isEmpty()) editing = false;
|
||||||
((BaseActivity) context).invalidateMenu();
|
updateToolbarOptions.run();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -87,7 +90,7 @@ public class GroupListAdapter extends RecyclerView.Adapter<GroupListItem> {
|
|||||||
|
|
||||||
holder.setSelected(true);
|
holder.setSelected(true);
|
||||||
editing = true;
|
editing = true;
|
||||||
((BaseActivity) context).invalidateMenu();
|
updateToolbarOptions.run();
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -131,7 +134,7 @@ public class GroupListAdapter extends RecyclerView.Adapter<GroupListItem> {
|
|||||||
item.setSelected(false);
|
item.setSelected(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
((BaseActivity) context).invalidateMenu();
|
updateToolbarOptions.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<GroupListItem> getSelectedGroups() {
|
public List<GroupListItem> getSelectedGroups() {
|
||||||
|
@ -6,8 +6,10 @@ import androidx.appcompat.app.ActionBar;
|
|||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
import androidx.fragment.app.FragmentTransaction;
|
||||||
|
|
||||||
import com.cringe_studios.cringe_authenticator.R;
|
import com.cringe_studios.cringe_authenticator.R;
|
||||||
|
import com.cringe_studios.cringe_authenticator.fragment.MenuDrawerFragment;
|
||||||
import com.cringe_studios.cringe_authenticator.fragment.NamedFragment;
|
import com.cringe_studios.cringe_authenticator.fragment.NamedFragment;
|
||||||
|
|
||||||
public class NavigationUtil {
|
public class NavigationUtil {
|
||||||
@ -25,6 +27,13 @@ public class NavigationUtil {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void openMenu(AppCompatActivity activity, Bundle args) {
|
||||||
|
FragmentManager manager = activity.getSupportFragmentManager();
|
||||||
|
MenuDrawerFragment fragment = instantiateFragment(manager, MenuDrawerFragment.class, args);
|
||||||
|
|
||||||
|
fragment.show(manager, null);
|
||||||
|
}
|
||||||
|
|
||||||
public static void navigate(Fragment currentFragment, Class<? extends NamedFragment> fragmentClass, Bundle args) {
|
public static void navigate(Fragment currentFragment, Class<? extends NamedFragment> fragmentClass, Bundle args) {
|
||||||
navigate((AppCompatActivity) currentFragment.requireActivity(), fragmentClass, args);
|
navigate((AppCompatActivity) currentFragment.requireActivity(), fragmentClass, args);
|
||||||
}
|
}
|
||||||
|
63
app/src/main/res/layout/fragment_menu_drawer.xml
Normal file
63
app/src/main/res/layout/fragment_menu_drawer.xml
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.core.widget.NestedScrollView 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="match_parent"
|
||||||
|
tools:context=".fragment.HomeFragment">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:paddingVertical="10dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/menu_tools_container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="end"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingHorizontal="16dp"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageButton
|
||||||
|
android:id="@+id/menu_add"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:src="@drawable/baseline_add_24"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:padding="10dp"
|
||||||
|
android:layout_marginStart="10dp" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageButton
|
||||||
|
android:id="@+id/menu_edit"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:src="@drawable/baseline_edit_24"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:padding="10dp"
|
||||||
|
android:layout_marginStart="10dp" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageButton
|
||||||
|
android:id="@+id/menu_delete"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:src="@drawable/baseline_delete_24"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:padding="10dp"
|
||||||
|
android:layout_marginStart="10dp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/menu_items"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/menu_tools_container" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
@ -7,7 +7,7 @@
|
|||||||
android:icon="@drawable/baseline_add_24"
|
android:icon="@drawable/baseline_add_24"
|
||||||
android:title="@string/action_new_group"
|
android:title="@string/action_new_group"
|
||||||
android:onClick="addOTP"
|
android:onClick="addOTP"
|
||||||
app:showAsAction="always" />
|
app:showAsAction="ifRoom" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_settings"
|
android:id="@+id/action_settings"
|
||||||
android:orderInCategory="100"
|
android:orderInCategory="100"
|
||||||
|
Loading…
Reference in New Issue
Block a user