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.GroupFragment;
|
||||
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.NamedFragment;
|
||||
import com.cringe_studios.cringe_authenticator.fragment.SettingsFragment;
|
||||
@ -143,7 +144,8 @@ public class MainActivity extends BaseActivity {
|
||||
|
||||
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.fabScanImage.setOnClickListener(view -> scanCodeFromImage());
|
||||
binding.fabInput.setOnClickListener(view -> inputCode());
|
||||
@ -155,6 +157,8 @@ public class MainActivity extends BaseActivity {
|
||||
}else {
|
||||
NavigationUtil.navigate(this, HomeFragment.class, null);
|
||||
}
|
||||
|
||||
new MenuDrawerFragment().show(getSupportFragmentManager(), null);
|
||||
}
|
||||
|
||||
@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.putString(GroupFragment.BUNDLE_GROUP, group);
|
||||
NavigationUtil.navigate(this, GroupFragment.class, bundle);
|
||||
}, () -> SettingsUtil.setGroups(requireContext(), groupListAdapter.getItems()));
|
||||
}, () -> SettingsUtil.setGroups(requireContext(), groupListAdapter.getItems()), requireActivity()::invalidateMenu);
|
||||
binding.menuItems.setAdapter(groupListAdapter);
|
||||
|
||||
loadGroups();
|
||||
|
@ -42,13 +42,16 @@ public class GroupListAdapter extends RecyclerView.Adapter<GroupListItem> {
|
||||
|
||||
private Runnable saveGroups;
|
||||
|
||||
private Runnable updateToolbarOptions;
|
||||
|
||||
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.recyclerView = recyclerView;
|
||||
this.navigateToGroup = navigateToGroup;
|
||||
this.saveGroups = saveGroups;
|
||||
this.updateToolbarOptions = updateToolbarOptions;
|
||||
this.inflater = LayoutInflater.from(context);
|
||||
this.items = new ArrayList<>();
|
||||
this.handler = new Handler(Looper.getMainLooper());
|
||||
@ -78,7 +81,7 @@ public class GroupListAdapter extends RecyclerView.Adapter<GroupListItem> {
|
||||
}else {
|
||||
holder.setSelected(!holder.isSelected());
|
||||
if(getSelectedGroups().isEmpty()) editing = false;
|
||||
((BaseActivity) context).invalidateMenu();
|
||||
updateToolbarOptions.run();
|
||||
}
|
||||
});
|
||||
|
||||
@ -87,7 +90,7 @@ public class GroupListAdapter extends RecyclerView.Adapter<GroupListItem> {
|
||||
|
||||
holder.setSelected(true);
|
||||
editing = true;
|
||||
((BaseActivity) context).invalidateMenu();
|
||||
updateToolbarOptions.run();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
@ -131,7 +134,7 @@ public class GroupListAdapter extends RecyclerView.Adapter<GroupListItem> {
|
||||
item.setSelected(false);
|
||||
}
|
||||
|
||||
((BaseActivity) context).invalidateMenu();
|
||||
updateToolbarOptions.run();
|
||||
}
|
||||
|
||||
public List<GroupListItem> getSelectedGroups() {
|
||||
|
@ -6,8 +6,10 @@ import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
|
||||
import com.cringe_studios.cringe_authenticator.R;
|
||||
import com.cringe_studios.cringe_authenticator.fragment.MenuDrawerFragment;
|
||||
import com.cringe_studios.cringe_authenticator.fragment.NamedFragment;
|
||||
|
||||
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) {
|
||||
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:title="@string/action_new_group"
|
||||
android:onClick="addOTP"
|
||||
app:showAsAction="always" />
|
||||
app:showAsAction="ifRoom" />
|
||||
<item
|
||||
android:id="@+id/action_settings"
|
||||
android:orderInCategory="100"
|
||||
|
Loading…
Reference in New Issue
Block a user