Makes the swipe to delete callback more generic.
This commit is contained in:
@@ -1,19 +1,11 @@
|
||||
package com.majinnaibu.monstercards.ui.library;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffXfermode;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.navigation.NavDirections;
|
||||
import androidx.navigation.Navigation;
|
||||
import androidx.recyclerview.widget.ItemTouchHelper;
|
||||
@@ -27,6 +19,7 @@ import com.majinnaibu.monstercards.data.MonsterRepository;
|
||||
import com.majinnaibu.monstercards.models.Monster;
|
||||
import com.majinnaibu.monstercards.ui.MCFragment;
|
||||
import com.majinnaibu.monstercards.ui.MonsterListRecyclerViewAdapter;
|
||||
import com.majinnaibu.monstercards.ui.shared.SwipeToDeleteCallback;
|
||||
import com.majinnaibu.monstercards.utils.Logger;
|
||||
|
||||
import java.util.UUID;
|
||||
@@ -41,30 +34,10 @@ public class LibraryFragment extends MCFragment {
|
||||
View root = inflater.inflate(R.layout.fragment_library, container, false);
|
||||
|
||||
FloatingActionButton fab = root.findViewById(R.id.fab);
|
||||
fab.setOnClickListener(view -> {
|
||||
Monster monster = new Monster();
|
||||
monster.name = "Unnamed Monster";
|
||||
MonsterRepository repository = this.getMonsterRepository();
|
||||
repository.addMonster(monster)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(() -> {
|
||||
Snackbar.make(
|
||||
getView(),
|
||||
String.format("%s created", monster.name),
|
||||
Snackbar.LENGTH_LONG)
|
||||
.setAction("Action", (_view) -> {
|
||||
navigateToMonsterDetail(monster.id);
|
||||
})
|
||||
.show();
|
||||
}, throwable -> {
|
||||
Logger.logError("Error creating monster", throwable);
|
||||
Snackbar.make(getView(), "Failed to create monster", Snackbar.LENGTH_LONG)
|
||||
.setAction("Action", null).show();
|
||||
});
|
||||
});
|
||||
assert fab != null;
|
||||
setupAddMonsterButton(fab);
|
||||
|
||||
RecyclerView recyclerView = root.findViewById(R.id.monster_list);
|
||||
final RecyclerView recyclerView = root.findViewById(R.id.monster_list);
|
||||
assert recyclerView != null;
|
||||
setupRecyclerView(recyclerView);
|
||||
|
||||
@@ -89,69 +62,40 @@ public class LibraryFragment extends MCFragment {
|
||||
mTwoPane);
|
||||
recyclerView.setAdapter(adapter);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new SwipeToDeleteMonsterCallback(adapter));
|
||||
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new SwipeToDeleteCallback(getContext(), (position) -> {
|
||||
adapter.deleteItem(position);
|
||||
}));
|
||||
itemTouchHelper.attachToRecyclerView(recyclerView);
|
||||
}
|
||||
|
||||
private void setupAddMonsterButton(@NonNull FloatingActionButton fab) {
|
||||
fab.setOnClickListener(view -> {
|
||||
Monster monster = new Monster();
|
||||
monster.name = "Unnamed Monster";
|
||||
MonsterRepository repository = this.getMonsterRepository();
|
||||
repository.addMonster(monster)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(() -> {
|
||||
Snackbar.make(
|
||||
getView(),
|
||||
String.format("%s created", monster.name),
|
||||
Snackbar.LENGTH_LONG)
|
||||
.setAction("Action", (_view) -> {
|
||||
navigateToMonsterDetail(monster.id);
|
||||
})
|
||||
.show();
|
||||
}, throwable -> {
|
||||
Logger.logError("Error creating monster", throwable);
|
||||
Snackbar.make(getView(), "Failed to create monster", Snackbar.LENGTH_LONG)
|
||||
.setAction("Action", null).show();
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
protected void navigateToMonsterDetail(UUID monsterId) {
|
||||
NavDirections action = LibraryFragmentDirections.actionNavigationLibraryToNavigationMonster(monsterId.toString());
|
||||
Navigation.findNavController(getView()).navigate(action);
|
||||
}
|
||||
|
||||
public static class SwipeToDeleteMonsterCallback extends ItemTouchHelper.SimpleCallback {
|
||||
private final MonsterListRecyclerViewAdapter mAdapter;
|
||||
private final Drawable icon;
|
||||
private final ColorDrawable background;
|
||||
private final Paint clearPaint;
|
||||
|
||||
public SwipeToDeleteMonsterCallback(MonsterListRecyclerViewAdapter adapter) {
|
||||
super(0, ItemTouchHelper.LEFT);
|
||||
mAdapter = adapter;
|
||||
icon = ContextCompat.getDrawable(mAdapter.getContext(), R.drawable.ic_delete_white_36);
|
||||
background = new ColorDrawable(Color.RED);
|
||||
clearPaint = new Paint();
|
||||
clearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
|
||||
int position = viewHolder.getAdapterPosition();
|
||||
mAdapter.deleteItem(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
|
||||
View itemView = viewHolder.itemView;
|
||||
int itemHeight = itemView.getBottom() - itemView.getTop();
|
||||
boolean isCancelled = dX == 0 && !isCurrentlyActive;
|
||||
|
||||
if (isCancelled) {
|
||||
c.drawRect(itemView.getRight() + dX, itemView.getTop(), itemView.getRight(), itemView.getBottom(), clearPaint);
|
||||
return;
|
||||
}
|
||||
// Draw the red delete background
|
||||
background.setBounds(itemView.getRight() + (int) dX, itemView.getTop(), itemView.getRight(), itemView.getBottom());
|
||||
background.draw(c);
|
||||
|
||||
// Calculate position of delete icon
|
||||
int iconHeight = icon.getIntrinsicHeight();
|
||||
int iconWidth = icon.getIntrinsicWidth();
|
||||
int iconTop = itemView.getTop() + (itemHeight - iconHeight) / 2;
|
||||
int iconMargin = (itemHeight - iconHeight) / 2;
|
||||
int iconLeft = itemView.getRight() - iconMargin - iconWidth;
|
||||
int iconRight = itemView.getRight() - iconMargin;
|
||||
int iconBottom = iconTop + iconHeight;
|
||||
|
||||
// Draw the icon
|
||||
icon.setBounds(iconLeft, iconTop, iconRight, iconBottom);
|
||||
icon.draw(c);
|
||||
|
||||
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
package com.majinnaibu.monstercards.ui.shared;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffXfermode;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.recyclerview.widget.ItemTouchHelper;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.majinnaibu.monstercards.R;
|
||||
|
||||
public class SwipeToDeleteCallback extends ItemTouchHelper.SimpleCallback {
|
||||
|
||||
public interface OnDeleteCallback {
|
||||
void onDelete(int position);
|
||||
}
|
||||
|
||||
private final Drawable icon;
|
||||
private final ColorDrawable background;
|
||||
private final Paint clearPaint;
|
||||
private final OnDeleteCallback mOnDelete;
|
||||
private final Context mContext;
|
||||
|
||||
public SwipeToDeleteCallback(Context context, OnDeleteCallback onDelete) {
|
||||
super(0, ItemTouchHelper.LEFT);
|
||||
mOnDelete = onDelete;
|
||||
mContext = context;
|
||||
icon = ContextCompat.getDrawable(mContext, R.drawable.ic_delete_white_36);
|
||||
background = new ColorDrawable(context.getResources().getColor(R.color.red));
|
||||
clearPaint = new Paint();
|
||||
clearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMove(
|
||||
@NonNull RecyclerView recyclerView,
|
||||
@NonNull RecyclerView.ViewHolder viewHolder,
|
||||
@NonNull RecyclerView.ViewHolder target
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
|
||||
if (mOnDelete != null) {
|
||||
int position = viewHolder.getAdapterPosition();
|
||||
mOnDelete.onDelete(position);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
|
||||
View itemView = viewHolder.itemView;
|
||||
int itemHeight = itemView.getBottom() - itemView.getTop();
|
||||
boolean isCancelled = dX == 0 && !isCurrentlyActive;
|
||||
|
||||
if (isCancelled) {
|
||||
c.drawRect(itemView.getRight() + dX, itemView.getTop(), itemView.getRight(), itemView.getBottom(), clearPaint);
|
||||
return;
|
||||
}
|
||||
// Draw the red delete background
|
||||
background.setBounds(itemView.getRight() + (int) dX, itemView.getTop(), itemView.getRight(), itemView.getBottom());
|
||||
background.draw(c);
|
||||
|
||||
// Calculate position of delete icon
|
||||
int iconHeight = icon.getIntrinsicHeight();
|
||||
int iconWidth = icon.getIntrinsicWidth();
|
||||
int iconTop = itemView.getTop() + (itemHeight - iconHeight) / 2;
|
||||
int iconMargin = (itemHeight - iconHeight) / 2;
|
||||
int iconLeft = itemView.getRight() - iconMargin - iconWidth;
|
||||
int iconRight = itemView.getRight() - iconMargin;
|
||||
int iconBottom = iconTop + iconHeight;
|
||||
|
||||
// Draw the icon
|
||||
icon.setBounds(iconLeft, iconTop, iconRight, iconBottom);
|
||||
icon.draw(c);
|
||||
|
||||
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
|
||||
}
|
||||
}
|
||||
@@ -4,4 +4,14 @@
|
||||
<color name="colorPrimaryDark">#661A10</color>
|
||||
<!-- <color name="colorAccent">#188B9B</color>-->
|
||||
<color name="colorAccent">#995500</color>
|
||||
|
||||
<!-- fruit system colors -->
|
||||
<color name="red">#FF3B30</color>
|
||||
<color name="orange">#FF9500</color>
|
||||
<color name="yellow">#FFCC00</color>
|
||||
<color name="green">#4CD964</color>
|
||||
<color name="tealBlue">#5AC8FA</color>
|
||||
<color name="blue">#007AFF</color>
|
||||
<color name="purple">#5855D6</color>
|
||||
<color name="pink">#FF2D55</color>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user