How do I delete Items from recycler view and Firebase database? - java

I have a recycler view connected to my Firebase database. I have implemented the ItemTouchHelper. SImpleCallback method so that I am able to slide and the items off to delete them. My codes work, the only issue is that I am not deleting the data from the database. I can't seem to find anything method that can help my situation since I haven't used DocumentReference.
Can anybody help me with this, How do I delete the items from the database when I click the delete icon in the on child draw?
personal fragment with the ItemTouch Helper
public class personalFragment extends Fragment {
private FirebaseAuth mAuth;
private String currentUserID;
private RecyclerView recyclerView;
private FirebaseRecyclerAdapter adapter;
private DatabaseReference mDatabase;
private TextView expense_txt;
LinearLayout mExpense;
#SuppressLint("SourceLockedOrientationActivity")
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
final View myView = inflater.inflate(R.layout.fragment_personal, container, false);
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
String uid = user.getUid();
mExpense = myView.findViewById(R.id.recycler_layout);
mDatabase = FirebaseDatabase.getInstance().getReference("Expenses").child(uid);
mAuth = FirebaseAuth.getInstance();
currentUserID = mAuth.getCurrentUser().getUid();
recyclerView = myView.findViewById(R.id.recycler_expense);
expense_txt = myView.findViewById(R.id.expenses_txt);
getActivity().setRequestedOrientation(
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
final LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
layoutManager.setStackFromEnd(true);
layoutManager.setReverseLayout(true);
recyclerView.setHasFixedSize(true);
DisplayItemOnRecycler();
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
sumExpenses();
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleCallback);
itemTouchHelper.attachToRecyclerView(recyclerView);
return myView;
}
public void deleteItem(){
}
ItemTouchHelper.SimpleCallback simpleCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
#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(direction == ItemTouchHelper.LEFT ){
Toast.makeText(getActivity(), "Deleting", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onChildDraw(#NonNull Canvas c, #NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
new RecyclerViewSwipeDecorator.Builder(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
.addBackgroundColor(ContextCompat.getColor(personalFragment.this.getActivity(), R.color.Delete))
.addActionIcon(R.drawable.ic_delete_black_24dp)
.create()
.decorate();
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
};
private void DisplayItemOnRecycler(){
Query query = FirebaseDatabase.getInstance()
.getReference("Expenses")
.child(currentUserID)
.limitToLast(100);
FirebaseRecyclerOptions<PersonalExpenses> options =
new FirebaseRecyclerOptions.Builder<PersonalExpenses>()
.setQuery(query, PersonalExpenses.class)
.build();
adapter = new FirebaseRecyclerAdapter<PersonalExpenses, MyViewHolder>(options) {
#Override
protected void onBindViewHolder(final MyViewHolder holder, int position, PersonalExpenses personalExpenses) {
holder.setDate(personalExpenses.getDate());
holder.setDescription(personalExpenses.getDescription());
holder.setAmount(personalExpenses.getAmount());
holder.setType(personalExpenses.getType());
holder.setCurrency(personalExpenses.getCurrency());
}
#Override
public MyViewHolder onCreateViewHolder( ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.expense_recycler, parent, false);
return new MyViewHolder(view);
}
};
}
private void sumExpenses(){
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
int totalsum = 0;
for(DataSnapshot mySnapshot: dataSnapshot.getChildren()){
PersonalExpenses personal = mySnapshot.getValue(PersonalExpenses.class);
totalsum += Integer.parseInt(personal.getAmount());
String stTotalsum = String.valueOf((totalsum));
expense_txt.setText(stTotalsum);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
#Override
public void onStart() {
super.onStart();
adapter.startListening();
}
#Override
public void onStop() {
super.onStop();
adapter.stopListening();
}
public static class MyViewHolder extends RecyclerView.ViewHolder {
private final View mView;
public MyViewHolder(View itemView) {
super(itemView);
mView = itemView;
}
protected void setDate(String date) {
TextView mDate = mView.findViewById(R.id.date_income);
mDate.setText(date);
}
protected void setType(String type) {
TextView mType = mView.findViewById(R.id.type_txt);
mType.setText(type);
}
protected void setDescription(String description) {
TextView mNote = mView.findViewById(R.id.note_txt);
mNote.setText(description);
}
protected void setAmount(String amount) {
TextView mAmount = mView.findViewById(R.id.amount_income);
String strammount = String.valueOf(amount);
mAmount.setText(strammount);
}
protected void setCurrency(String currency) {
TextView mCurrency = mView.findViewById(R.id.currency);
mCurrency.setText(currency);
}
}
}
This is the ItemTouchHelper method in the fragment above
ItemTouchHelper.SimpleCallback simpleCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
#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(direction == ItemTouchHelper.LEFT ){
Toast.makeText(getActivity(), "Deleting", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onChildDraw(#NonNull Canvas c, #NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
new RecyclerViewSwipeDecorator.Builder(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
.addBackgroundColor(ContextCompat.getColor(personalFragment.this.getActivity(), R.color.Delete))
.addActionIcon(R.drawable.ic_delete_black_24dp)
.create()
.decorate();
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
};

Related

Why i remove some item from the adapter viewPager2, viewPager can not call registerOnPageChangeCallback?

I added viewpager2 in my screen and set adapter on it, see adapter structure in below
public class NewTravelListAdapter extends RecyclerView.Adapter<NewTravelListAdapter.VH> {
MainActivityCallback newTravelCallback;
public Picasso picasso;
private BottomSheetBehavior mBottomSheetBehavior;
public ArrayList<NewTravelRequestPopUpModel> newTravelRequestPopUpModel;
public OptionsAdapter optionsAdapter;
private NewTravelSuggestPopupViewInterface.GetSize getSize;
Context context;
int viewHeight = 0;
private CountDownCustumTimer circle_progress_bar_timer;
ChangeItemTravelListInterface changeItemTravelListInterface;
VH holder;
public DiffUtil.ItemCallback<NewTravelRequestPopUpModel> diffUtil = new DiffUtil.ItemCallback<NewTravelRequestPopUpModel>(){
#Override
public boolean areItemsTheSame(#NonNull NewTravelRequestPopUpModel oldItem, #NonNull NewTravelRequestPopUpModel newItem) {
return false;
}
#Override
public boolean areContentsTheSame(#NonNull NewTravelRequestPopUpModel oldItem, #NonNull NewTravelRequestPopUpModel newItem) {
return false;
}
};
public AsyncListDiffer<NewTravelRequestPopUpModel> differ = new AsyncListDiffer<NewTravelRequestPopUpModel>(this , diffUtil);
public NewTravelListAdapter(#NonNull MainActivityCallback newTravelCallback, Picasso picasso,
ArrayList<NewTravelRequestPopUpModel> newTravelRequestPopUpModel,
NewTravelSuggestPopupViewInterface.GetSize getSize ,
ChangeItemTravelListInterface changeItemTravelListInterface){
this.newTravelCallback = newTravelCallback;
this.picasso = picasso;
this.getSize=getSize;
this.newTravelRequestPopUpModel = newTravelRequestPopUpModel;
optionsAdapter = new OptionsAdapter(picasso, newTravelRequestPopUpModel.get(0).optionsModelArrayList);
this.changeItemTravelListInterface = changeItemTravelListInterface;
}
#NonNull
#Override
public VH onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
ItemNewTravelSuggestPopupLayoutBinding binding = ItemNewTravelSuggestPopupLayoutBinding.inflate(inflater , parent , false);
return new VH(binding);
}
#Override
public void onBindViewHolder(#NonNull VH holder, int position) {
NewTravelRequestPopUpModel item = differ.getCurrentList().get(position);
this.holder = holder;
View view = holder.binding.newTravelSuggestPopup;
view.post(() -> {
viewHeight = view.getHeight()+20;
getSize.getHeight((view.getHeight()+50));
});
}
#Override
public int getItemCount() {
return differ.getCurrentList().size();
}
public void setList(ArrayList<NewTravelRequestPopUpModel> newTravelRequestPopUpModel){
differ.submitList(newTravelRequestPopUpModel);
notifyDataSetChanged();
}
public void removeItem(int pos){
notifyItemRemoved(pos);
changeItemTravelListInterface.itemRemoved(pos);
}
public static class VH extends RecyclerView.ViewHolder{
ItemNewTravelSuggestPopupLayoutBinding binding;
public VH(ItemNewTravelSuggestPopupLayoutBinding binding ) {
super(binding.newTravelSuggestPopup);
this.binding= binding;
}
}
}
Then I set adapter above to the viewPAger2 and listen with registerOnPageChangeCallback to viewPager2 scroll.
adapterList = new NewTravelListAdapter(newTravelCallback , picasso , newTravelRequestPopUpModel,
getSize , this);
setList(newTravelRequestPopUpModel);
binding.viewPager.setAdapter(adapterList);
binding.viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
super.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
#Override
public void onPageSelected(int position) {
super.onPageSelected(position);
selectedTravel = newTravelRequestPopUpModel.get(position);
ChangeItem(selectedTravel , position);
newTravelCallback.changeRequest(selectedTravel , height);
}
#Override
public void onPageScrollStateChanged(int state) {
super.onPageScrollStateChanged(state);
}
});
Now my problem is that after calling the ‍‍‍‍‍‍‍removeItem‍‍‍ method in the NewTravelListAdapter adapter
Removed the item from the adapter, but I can't listen to the adapter change

Recycler View List Sort position saving notepad app

In my program I added code to move the list items around but for example if I move shopping list above Test 123 and fully close the app the positioning resets to the original instead of the updated location I cannot figure out for the life of me what to do.
Code for click drag in mainactivity.java
//Click drag Notes feature *****************************************************
ItemTouchHelper.SimpleCallback simpleCallback = new ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.START | ItemTouchHelper.END, 0) {
#Override
public boolean onMove(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, #NonNull RecyclerView.ViewHolder target) {
int fromPosition = viewHolder.getBindingAdapterPosition();
int toPosition = target.getBindingAdapterPosition();
Collections.swap(notesList, fromPosition, toPosition);
Objects.requireNonNull(recyclerView.getAdapter()).notifyItemMoved(fromPosition, toPosition);
return false;
}
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int direction) {
}
#Override //This forces arrangement up or down not any direction
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
return makeMovementFlags(dragFlags, 0);
}
};
//******************************************* Click Drag Notes ***************************************
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleCallback);
itemTouchHelper.attachToRecyclerView(recyclerView);
ItemTouchHelper helper = new ItemTouchHelper(callback);
helper.attachToRecyclerView(recyclerView);
//
notesList = new ArrayList<>();
databaseClass = new
DatabaseClass(this);
fetchAllNotesFromDatabase();
recyclerView.setLayoutManager(new
LinearLayoutManager(this));
adapter = new
Adapter(this, MainActivity.this, notesList);
recyclerView.setAdapter(adapter);
}
Adapter Code
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_view_layout, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, #SuppressLint("RecyclerView") int position) {
holder.title.setText(notesList.get(position).getTitle());
holder.description.setText(notesList.get(position).getDescription());
holder.layout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, UpdateNotesActivity.class);
intent.putExtra("title", notesList.get(position).getTitle());
intent.putExtra("description", notesList.get(position).getDescription());
intent.putExtra("id", notesList.get(position).getId());
activity.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return notesList.size();
}
#Override
public Filter getFilter() {
return exampleFilter;
}
private Filter exampleFilter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
List<Model> filteredList = new ArrayList<>();
if (constraint == null || constraint.length() == 0) {
filteredList.addAll(newList);
} else {
String filterPattern = constraint.toString().toLowerCase().trim();
for (Model item : newList) {
if (item.getTitle().toLowerCase().contains(filterPattern)) {
filteredList.add(item);
}
}
}
FilterResults results = new FilterResults();
results.values = filteredList;
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
notesList.clear();
notesList.addAll((List) results.values);
notifyDataSetChanged();
}
};
public class MyViewHolder extends RecyclerView.ViewHolder {
private static final String TAG = "MyViewHolder";
TextView title, description, textView;
ImageButton imageButton;
RelativeLayout layout;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
title = itemView.findViewById(R.id.title);
description = itemView.findViewById(R.id.description);
layout = itemView.findViewById(R.id.note_layout);
}
}
public List<Model> getList() {
return notesList;
}
public void removeItem(int position) {
notesList.remove(position);
notifyItemRemoved(position);
}
public void restoreItem(Model item, int position) {
notesList.add(position, item);
notifyItemInserted(position);
}
}

Change the background color of a button in a Recycler view

I want to change the background color of a specific button in my recycler view when certain conditions are met. How do I get to that specific button?
This is my adapter class :-
public class mixandmatchadapter extends
RecyclerView.Adapter<mixandmatchadapter.ViewHolder>{
private static final String TAG = "RecyclerAdapter";
List datalist;
Context context;
int index;
String text;
public mixandmatchadapter(int index, String text) {
this.index = index;
this.text = text;
}
public mixandmatchadapter(List<Mixmatchclass> datalist, Context context) {
this.datalist = datalist;
this.context = context;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater= LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.row_itemmixandmatch,parent,false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.mainbutton.setText(datalist.get(position).getStatement());
//String.valueOf(position))
}
#Override
public int getItemCount() {
return datalist.size();
}
class ViewHolder extends RecyclerView.ViewHolder{
Button mainbutton;
public ViewHolder(#NonNull View itemView) {
super(itemView);
mainbutton = itemView.findViewById(R.id.mainbutton);
}
} }
For example:- If I have ten buttons in my recycler view and I want to change the color of a button at position 5 how would I access it?
This is my main fragment :-
public class Mixandmatch extends Fragment {
RecyclerView recyclerView;
mixandmatchadapter mixandmatchadapter;
public static List<Mixmatchclass> datalist;
private static int slideCounter=2;
#Override
public void onStart() {
super.onStart();
}
public Mixandmatch() {
}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_mixandmatch, container,false);
recyclerView = view.findViewById(R.id.rightlyt);
datalist=new ArrayList<>();
datalist.add(new Mixmatchclass("Statement 2",0));
datalist.add(new Mixmatchclass("Statement 4",1));
datalist.add(new Mixmatchclass("Statement 1",2));
datalist.add(new Mixmatchclass("Statement 5",3));
datalist.add(new Mixmatchclass("Statement 3",4));
datalist.add(new Mixmatchclass("Statement 7",5));
datalist.add(new Mixmatchclass("Statement 6",6));
recyclerView.setAdapter(new mixandmatchadapter(datalist,getActivity()));
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleCallback);
itemTouchHelper.attachToRecyclerView(recyclerView);
return view;
}
ItemTouchHelper.SimpleCallback simpleCallback = new
ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP
| ItemTouchHelper.DOWN | ItemTouchHelper.START | ItemTouchHelper.END , 0) {
#Override
public boolean onMove(#NonNull RecyclerView recyclerView, #NonNull
RecyclerView.ViewHolder viewHolder, #NonNull RecyclerView.ViewHolder target) {
int fromPosition = viewHolder.getAdapterPosition();
int toPosition = target.getAdapterPosition();
Collections.swap(datalist,fromPosition,toPosition);
recyclerView.getAdapter().notifyItemMoved(fromPosition,toPosition);
recyclerView.getAdapter().notifyDataSetChanged();
return false;
}
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int direction) {
}
};
Any help would be appreciated.

How to add a button into a recyclerview layout with cardview and adapter?

I am trying to add a button inside my recyclerview's cardview holder.
When the button is pressed, the user is directed to an external website when clicked.I also want to add multiple buttons to each cardview so that each button leads to a different website when clicked. How to do this?
My code:
Fragment class (i am using fragments):
public class BooksFragment extends Fragment {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_books, container, false);
mLayoutManager = new LinearLayoutManager(this.getActivity());
return view;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ArrayList<exampleItemBooks> exampleList = new ArrayList<>();
exampleList.add(new exampleItemBooks(R.drawable.thritysixstrategems, "The Thirty-Six Stratagems", "300 years ago, an unknown author compiled the Stratagems, a strangely seductive meditation on deception.", "-Unknown Author"));
exampleList.add(new exampleItemBooks(R.drawable.medidations, "Meditations", "A book by the great Stoic Roman Emperor Marcus Aurelius. The book was written in Koine Greek, during the Emperor's reign.", "-Marcus Aurelius"));
mRecyclerView = view.findViewById(R.id.recyclerViewBooks);
mRecyclerView.setHasFixedSize(false);
mAdapter = new exampleBooksAdapter(exampleList);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
}
Adapter:
public class exampleBooksAdapter extends RecyclerView.Adapter<exampleBooksAdapter.ExampleViewHolder> {
private ArrayList<exampleItemBooks> mExampleList;
public static class ExampleViewHolder extends RecyclerView.ViewHolder {
public ImageView mImageView;
public TextView mTextView1;
public TextView mTextView2;
public TextView mTextView3;
public ExampleViewHolder(View itemView) {
super(itemView);
mImageView = itemView.findViewById(R.id.imageViewCards);
mTextView1 = itemView.findViewById(R.id.textViewCard1);
mTextView2 = itemView.findViewById(R.id.textViewCard2);
mTextView3 = itemView.findViewById(R.id.textViewCard3);
}
}
public exampleBooksAdapter(ArrayList<exampleItemBooks> exampleItemBooks) {
mExampleList = exampleItemBooks;
}
#Override
public ExampleViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.example_item_books, parent, false);
ExampleViewHolder evh = new ExampleViewHolder(v);
return evh;
}
#Override
public void onBindViewHolder(#NonNull ExampleViewHolder holder, int position) {
exampleItemBooks currentItem = mExampleList.get(position);
holder.mImageView.setImageResource(currentItem.getImageResource());
holder.mTextView1.setText(currentItem.getText1());
holder.mTextView2.setText(currentItem.getText2());
holder.mTextView3.setText(currentItem.getText3());
}
#Override
public int getItemCount() {
return mExampleList.size();
}
}
ArrayList class:
private int mImageResource;
private String mText1;
private String mText2;
private String mText3;
public exampleItemBooks(int imageResource, String text1, String text2, String text3) {
mImageResource = imageResource;
mText1 = text1;
mText2 = text2;
mText3 = text3;
}
public int getImageResource() {
return mImageResource;
}
public String getText1() {
return mText1;
}
public String getText2() {
return mText2;
}
public String getText3() {
return mText3;
}
}
Add a button to your viewholder layout and
#Override
public void onBindViewHolder(#NonNull ExampleViewHolder holder, int position) {
exampleItemBooks currentItem = mExampleList.get(position);
...
holder.mButton.setTag("URL OF THE SITE");
holder.mButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Take user to browser.
}
});
}

ItemTouchHelper not being applied to every View in Adapter

In implementing swipe-to-delete functionality I accidentally made my forground view of the viewholder transparent. In doing so I've uncovered a bug with my ItemTouchHandler not changing the background or hiding the text when it is supposed to.
It appears to me that my ItemTouchHelper is not being applied to every view in my ReycleViewAdapter and/or the views are not being updated or they all share a single parent of some sort, after many hours of attempted debugging I'm at my wit's end, I've included a handy gif of the issue.
The ItemTouchHelper's onDrawChild() and onDrawChildOver() methods are passed to my fragment in order to handle the actions
Code:
AllLists_fragment.java:
public class showAllLists_fragment extends android.support.v4.app.Fragment implements RecycleItemTouchHelper.RecyclerItemTouchHelperListener {
private static final String TAG = "showAllLists";
private RecyclerView mAllItemsView = null;
private DataCommunication mData = null;
private ItemTouchHelper.SimpleCallback itemTouchHelper = null;;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.show_all_lists_frag, container, false);
this.mAllItemsView = (RecyclerView) view.findViewById(R.id.allItems);
this.itemTouchHelper = new RecycleItemTouchHelper(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT, this);
new ItemTouchHelper(this.itemTouchHelper).attachToRecyclerView(this.mAllItemsView);
this.mAllItemsView.setAdapter(this.mData.getAdapter());
this.mAllItemsView.setLayoutManager(new LinearLayoutManager(getActivity()){
//
#Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
try {
super.onLayoutChildren(recycler, state);
} catch (IndexOutOfBoundsException e) {
Log.d(TAG, "Inconsistent Exception Caught -See stack trace");
e.printStackTrace();
}
}
});
viewShadow();
return view;
}
#TargetApi(21)
public void viewShadow(){
this.mAllItemsView.setTranslationZ(100);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
try {
this.mData = (DataCommunication) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString()
+ " must implement DataCommunication");
}
}
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if(isVisibleToUser){
this.mData.getAdapter().notifyDataSetChanged();
this.mData.refresh();
}
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction, int position) {
int noSwipeSize = mData.getAllToDo().size();
if (direction == ItemTouchHelper.LEFT) {
mData.deleteTask(mData.getAdapter().getResults().get(viewHolder.getAdapterPosition()));
mData.getAdapter().notifyItemRangeRemoved(viewHolder.getAdapterPosition(), noSwipeSize);
} else if (direction == ItemTouchHelper.RIGHT) {
mData.completeTask(mData.getAdapter().getResults().get(viewHolder.getAdapterPosition()));
mData.getAdapter().notifyItemRangeRemoved(viewHolder.getAdapterPosition(), noSwipeSize);
}
}
#Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
final View foregroundView = ((com.lab1.ac01220.bloomv2.ViewHolder) viewHolder).getForeground();
if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
if(dX < 0){
this.mData.getViewHolder().getDeleteText().setVisibility(View.VISIBLE);
this.mData.getViewHolder().getCompleteText().setVisibility(View.INVISIBLE);
this.mData.getViewHolder().getBackground().setBackgroundColor(getResources().getColor(R.color.colorAccent));
} else if(dX >0){
this.mData.getViewHolder().getCompleteText().setVisibility(View.VISIBLE);
this.mData.getViewHolder().getDeleteText().setVisibility(View.INVISIBLE);
this.mData.getViewHolder().getBackground().setBackgroundColor(getResources().getColor(R.color.colorComplete));
}
}
ItemTouchHelper.SimpleCallback.getDefaultUIUtil().onDraw(c, recyclerView, foregroundView, dX, dY,actionState, isCurrentlyActive);
}
#Override
public void onChildDrawOver(Canvas c, RecyclerView recyclerView, ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
final View foregroundView = ((com.lab1.ac01220.bloomv2.ViewHolder) viewHolder).getForeground();
ItemTouchHelper.SimpleCallback.getDefaultUIUtil().onDrawOver(c, recyclerView, foregroundView, dX, dY,actionState, isCurrentlyActive);
}
}
RecycleitemTouchHelper.java
public RecycleItemTouchHelper(int dragDirs, int swipeDirs, RecyclerItemTouchHelperListener listener) {
super(dragDirs, swipeDirs);
this.listener = listener;
}
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
this.listener.onSwiped(viewHolder, direction, viewHolder.getAdapterPosition());
}
#Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
this.listener.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
#Override
public void onChildDrawOver(Canvas c, RecyclerView recyclerView,
RecyclerView.ViewHolder viewHolder, float dX, float dY,
int actionState, boolean isCurrentlyActive) {
this.listener.onChildDrawOver(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
#Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
final View foregroundView = ((ViewHolder) viewHolder).getForeground();
getDefaultUIUtil().clearView(foregroundView);
}
#Override
public int convertToAbsoluteDirection(int flags, int layoutDirection) {
return super.convertToAbsoluteDirection(flags, layoutDirection);
}
public interface RecyclerItemTouchHelperListener {
void onSwiped(RecyclerView.ViewHolder viewHolder, int direction, int position);
void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive);
void onChildDrawOver(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive);
}
}
RecycleViewAdapter.java:
public class RecycleViewAdapter extends RecyclerView.Adapter<ViewHolder>{
private LayoutInflater inflater = null;
private List<GlobalLists> results = null;
private DataCommunication mData = null;
public RecycleViewAdapter(Context context, List<GlobalLists> results){
this.inflater = LayoutInflater.from(context);
this.results = results;
this.mData = (DataCommunication)context;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.custom_row, parent, false);
ViewHolder holder = new ViewHolder(view);
this.mData.setViewHolder(holder);
return holder;
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
GlobalLists item = this.results.get(position);
holder.setRowTitle(item.getTitle());
//Grab the first 14 characters of the contents if the row is not null
if(item.getContents() != null){
StringBuffer currentContent = new StringBuffer(item.getContents().substring(0, Math.min(item.getContents().length(),28)));
if(item.getContents().length() > 28) currentContent.append("...");
holder.setRowContent(currentContent.toString());
}
}
public void reloadAdapterData(List<GlobalLists> refresh){
this.results = refresh;
}
#Override
public int getItemCount() {
return this.results == null || this.results.isEmpty() ? 0 : this.results.size();
}
public List<GlobalLists> getResults(){
return this.results;
}
}
The problem was that I was simply setting the first ViewHolder to be a global variable and only anacting changes on that. Instead I should have been getting the current View being draw in onChildDraw and performing functions on that:
Was:
#Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
final View foregroundView = ((com.lab1.ac01220.bloomv2.ViewHolder) viewHolder).getForeground();
if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
if(dX < 0){
this.mData.getViewHolder().getDeleteText().setVisibility(View.VISIBLE);
this.mData.getViewHolder().getCompleteText().setVisibility(View.INVISIBLE);
this.mData.getViewHolder().getBackground().setBackgroundColor(getResources().getColor(R.color.colorAccent));
} else if(dX >0){
this.mData.getViewHolder().getCompleteText().setVisibility(View.VISIBLE);
this.mData.getViewHolder().getDeleteText().setVisibility(View.INVISIBLE);
this.mData.getViewHolder().getBackground().setBackgroundColor(getResources().getColor(R.color.colorComplete));
}
}
ItemTouchHelper.SimpleCallback.getDefaultUIUtil().onDraw(c, recyclerView, foregroundView, dX, dY,actionState, isCurrentlyActive);
}
Should be:
#Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
com.lab1.ac01220.bloomv2.ViewHolder current = (com.lab1.ac01220.bloomv2.ViewHolder) viewHolder;
final View foregroundView = ((com.lab1.ac01220.bloomv2.ViewHolder) viewHolder).getForeground();
if (isCurrentlyActive) {
if(dX < 0){
current.getDeleteText().setVisibility(View.VISIBLE);
current.getCompleteText().setVisibility(View.INVISIBLE);
current.getBackground().setBackground(getResources().getDrawable(R.drawable.ic_rounded_rectangle_accent));
} else if(dX >0){
current.getCompleteText().setVisibility(View.VISIBLE);
current.getDeleteText().setVisibility(View.INVISIBLE);
current.getBackground().setBackground(getResources().getDrawable(R.drawable.ic_rounded_rectangle_complete));
}
}
ItemTouchHelper.SimpleCallback.getDefaultUIUtil().onDraw(c, recyclerView, foregroundView, dX, dY,actionState, isCurrentlyActive);
}

Categories