I am using ItemTouchHelper
with AlertDialog
. The problem is when user swipe the element to the right side. AlertDialog
with EditText
is show at the screen. Now I want to do something like that:
When user press "save" button
the element disappears not removed, only "go out" from whole RecyclerView
list.
When "cancel" button
is pressed the element should return to the same place that it was before (It was be pretty that it will be the animation for mAdapter.notifyItemChanged();
or mAdapter.notifyItemInserted();
So I tried two solutions but without success.
itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0,
ItemTouchHelper.RIGHT) {
@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) {
position = viewHolder.getAbsoluteAdapterPosition(); // 2. solution
openDialog();
vieholder2 = viewHolder; // 1. Solution
}
});
itemTouchHelper.attachToRecyclerView(recyclerView);
First I tried implemented my own interface and after user press "cancel" button
interface should be invoke and set code below:
itemTouchHelper.startSwipe(vieholder2);
Second:
After interface is invoked I set mAdapter.notifyItemChanged(position);
Both solutions works good, directly in onSwiped
method in ItemTouchHelper
, but after method was triggered and Dialog
is showing. Solutions aren't working.
So how can I return the invisible item back to the RecyclerView
list after "cancel" button
on Dialog
is clicked?
I am using LiveData if it is helpful.
EDIT
Fragment class.
package com.example.application;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
/**
* A simple {@link Fragment} subclass.
* Use the {@link Main_Database_fragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class Main_Database_fragment extends Fragment implements Dialog_Amount.Dialog_AmountListener {
private View rootView;
private RecyclerView recyclerView;
private Recycler_Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
private Item_get_VIEWMODEL item_get_viewmodel;
private ActivityResultLauncher<Intent> start_next_activity;
private Item_get item_get;
int pospos;
ItemTouchHelper itemTouchHelper;
RecyclerView.ViewHolder viewholder;
int deleted = 0;
private int id;
private int type;
private int package_category;
Item_get item_get2;
int positionItem;
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
public Main_Database_fragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment Main_Database_fragment.
*/
// TODO: Rename and change types and number of parameters
public static Main_Database_fragment newInstance(String param1, String param2) {
Main_Database_fragment fragment = new Main_Database_fragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@Override
public View onCreateView(final LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_main__database_fragment,container,false);
return rootView;
}
@Override
public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
build_RecyclerView();
mAdapter.setOnItemClickListener(new Recycler_Adapters_items() {
@Override
public void onEditClick(Item_get item_get) {
Intent intent = new Intent(getActivity(), Edit_Delete_details.class);
type = item_get.food.getCode();
package_category = item_get.package_type.getCode();
intent.putExtra(Edit_Delete_details.EXTRA_DATA, item_get);
intent.putExtra(Edit_Delete_details.EXTRA_ID, item_get.getId());
intent.putExtra(Edit_Delete_details.EXTRA_CATEGORY, type);
intent.putExtra(Edit_Delete_details.EXTRA_PACKAGE_TYPE,package_category);
start_next_activity.launch(intent);
}
@Override
public void onDeleteClick(Item_get item_get) {
item_get_viewmodel.delete(item_get);
}
@Override
public void onItemClick(Item_get item_get) {
Intent intent = new Intent(getActivity(), Product_specific_detail.class);
intent.putExtra(Product_specific_detail.EXTRA_ID_2, item_get.getId());
start_next_activity.launch(intent);
}
});
item_get_viewmodel = new ViewModelProvider(this).get(Item_get_VIEWMODEL.class);
item_get_viewmodel.getAll_ItemsModel().observe(getViewLifecycleOwner(), new Observer<List<Item_get>>() {
@Override
public void onChanged(List<Item_get> item_gets) {
mAdapter.submitList(item_gets);
mAdapter.copylist(item_gets);
}
});
itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0,
ItemTouchHelper.RIGHT) {
@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) {
positionItem = viewHolder.getAbsoluteAdapterPosition();
openDialog();
item_get2 = mAdapter.getItemAt(viewHolder.getAbsoluteAdapterPosition());
deleted = viewHolder.getAbsoluteAdapterPosition();
viewholder = viewHolder;
}
});
itemTouchHelper.attachToRecyclerView(recyclerView);
super.onViewCreated(view, savedInstanceState);
}
public void build_RecyclerView(){
recyclerView = rootView.findViewById(R.id.recycler_edit_del_product);
recyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
mAdapter = new Recycler_Adapter();
recyclerView.setAdapter(mAdapter);
start_next_activity = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
if(result.getResultCode() == Activity.RESULT_OK){
Intent intent = result.getData();
assert intent != null;
id = intent.getIntExtra(Edit_Delete_details.EXTRA_ID,-1);
if(id == -1){
Toast.makeText(getContext(),"Error", Toast.LENGTH_SHORT).show();
return;
}else if(id == -5){
item_get = intent.getParcelableExtra(Edit_Delete_details.EXTRA_DATA);
item_get.setId(id);
item_get_viewmodel.delete(item_get);
Toast.makeText(getContext(),"Delete",Toast.LENGTH_SHORT).show();
}else {
item_get = intent.getParcelableExtra(Edit_Delete_details.EXTRA_DATA);
type = intent.getIntExtra(Edit_Delete_details.EXTRA_CATEGORY, -1);
package_category = intent.getIntExtra(Edit_Delete_details.EXTRA_PACKAGE_TYPE, -1);
if(type == -1){
Toast.makeText(getContext(),"Category may not be updated", Toast.LENGTH_LONG).show();
}else {
set_food_type(type);
}
if(package_category == -1){
Toast.makeText(getContext(),"Packages may not be updated", Toast.LENGTH_LONG).show();
}else {
set_packages_type(package_category);
}
item_get.setId(id);
item_get_viewmodel.update(item_get);
Toast.makeText(getContext(),"Update",Toast.LENGTH_SHORT).show();
}
}
}
}
);
}
//Set our foodType from int to enum and later we pass it to db to update;
public void set_food_type(int type){
switch (type){
case 1:
item_get.food = Item_get.Food.SWEETS;
break;
case 2:
item_get.food = Item_get.Food.VEGETABLES_FRUITS;
break;
case 3:
item_get.food = Item_get.Food.DRINKS;
break;
case 4:
item_get.food = Item_get.Food.OTHER;
break;
default:
break;
}
}
// Same as it is with food. Difference is Package Category enum not Package Type enum;
public void set_packages_type(int type){
switch (type){
case 1:
item_get.package_type = Item_get.Package_type.PACKAGE_BOX;
break;
case 2:
item_get.package_type = Item_get.Package_type.PIECE;
break;
case 3:
item_get.package_type = Item_get.Package_type.OTHER_PACK;
break;
default:
break;
}
}
public void openDialog(){
Dialog_Amount dialog_amount = new Dialog_Amount();
dialog_amount.setCancelable(false);
dialog_amount.show(getChildFragmentManager(),"This is dialog");
}
@Override
public void applyText(int text) {
if(text != -1){
item_get2.setNameProduct(item_get2.getNameProduct());
item_get2.setDate_buy(null);
item_get2.setAmount(0);
int a = item_get2.food.getCode();
int b = item_get2.package_type.getCode();
item_get2.setPrice(0.0);
item_get2.setValue(0.0);
item_get2.setTo_shop(1);
item_get2.setAmount_toShop(text);
item_get_viewmodel.update(item_get2);
}else {
mAdapter.add_SingleItem(positionItem,item_get2);
mAdapter.notifyItemInserted(positionItem);
}
}
}
My Adapter.
package com.example.application;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.ListAdapter;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
public class Recycler_Adapter extends ListAdapter<Item_get,Recycler_Adapter.recyclerViewHolder> {
public Recycler_Adapters_items clickListener;
private List<Item_get> data_list2;
private List<Item_get> data_list2_full;
public Recycler_Adapter() {
super(DIFF_CALLBACK);
}
private static final DiffUtil.ItemCallback<Item_get> DIFF_CALLBACK = new DiffUtil.ItemCallback<Item_get>() {
@Override
public boolean areItemsTheSame(@NonNull Item_get oldItem, @NonNull Item_get newItem) {
return oldItem.getId() == newItem.getId();
}
@Override
public boolean areContentsTheSame(@NonNull Item_get oldItem, @NonNull Item_get newItem) {
return oldItem.getNameProduct().equals(newItem.getNameProduct()) && oldItem.getAmount() == newItem.getAmount()
&& oldItem.food.getCode() == newItem.food.getCode() && oldItem.package_type.getCode() == newItem.package_type.getCode();
}
};
public void copylist(List<Item_get> item_gets){
if (data_list2 != null){
data_list2.clear();
}else {
data_list2 = new ArrayList<>();
}
data_list2.addAll(item_gets);
if(data_list2_full != null){
data_list2_full.clear();
data_list2_full.addAll(data_list2);
}else{
data_list2_full = new ArrayList<>(data_list2);
}
}
public void add_SingleItem(int position, List<Item_get> item_get){
item_get.add(position, (Item_get) item_get);
}
public void setOnItemClickListener(Recycler_Adapters_items mClickListener) {
clickListener = mClickListener;
}
public class recyclerViewHolder extends RecyclerView.ViewHolder {
public ImageView mImageView1;
public ImageView mImageView2;
public ImageView mImageView3;
public TextView mTextView1;
public TextView mTextView2;
public TextView mTextView3;
public TextView mTextView4;
public recyclerViewHolder(final View itemView, final Recycler_Adapters_items listener) {
super(itemView);
mImageView1 = itemView.findViewById(R.id.rec_image);
mImageView2 = itemView.findViewById(R.id.rec_image_edit);
mImageView3 = itemView.findViewById(R.id.rec_image_del);
mTextView1 = itemView.findViewById(R.id.rec_text_1);
mTextView2 = itemView.findViewById(R.id.rec_text_2);
mTextView3 = itemView.findViewById(R.id.rec_text_3);
mTextView4 = itemView.findViewById(R.id.rect_text_4);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null) {
int position = getAbsoluteAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
listener.onItemClick(getItem(position));
}
}
}
});
mImageView2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null) {
int position = getAbsoluteAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
listener.onEditClick(getItem(position));
}
}
}
});
mImageView3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null) {
int position = getAbsoluteAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
listener.onDeleteClick(getItem(position));
}
}
}
});
}
}
@NonNull
@Override
public recyclerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_template, parent, false);
return new recyclerViewHolder(v,clickListener);
}
@Override
public void onBindViewHolder(@NonNull recyclerViewHolder holder, int position) {
Item_get currentItem = getItem(position);
currentItem.setId(currentItem.getId());
holder.mTextView1.setText(currentItem.getNameProduct());
if (currentItem.food == Item_get.Food.SWEETS) {
holder.mTextView2.setText(R.string.sweets);
}
if (currentItem.food == Item_get.Food.Vegetables) {
holder.mTextView2.setText(R.string.vegetables);
}
if (currentItem.food == Item_get.Food.drinks) {
holder.mTextView2.setText(R.string.drinks);
}
if (currentItem.food == Item_get.Food.other) {
holder.mTextView2.setText(R.string.other);
}
String amount = String.valueOf(currentItem.getAmount());
holder.mTextView3.setText(amount);
if(currentItem.package_type == Item_get.Package_type.PACKAGE_BOX){
holder.mTextView4.setText(R.string.product_cat_pack_short);
}else if(currentItem.package_type == Item_get.Package_type.PIECE){
holder.mTextView4.setText(R.string.product_cat_piece);
} else if(currentItem.package_type == Item_get.Package_type.OTHER_PACK){
holder.mTextView4.setText(R.string.product_amount);
}
else {
holder.mTextView4.setText(R.string.product_amount);
}
}
public Item_get getItemAt(int position){
return getItem(position);
}
}
You need to do this in your Fragment class
madapter.notifyItemChanged(viewholder.getAbsoluteAdapterPostion());