I have a RecyclerView
and have implemented an onMove
command called onItemMove
. I'm using onItemMove
to try and get the list elements to swap position when dragged around, but the list elements just hover over each, they don't swap. How can I correct this?
Note 1: onItemDismiss
works fine; it swipes the item away and removes it from the list.
Note 2: I've tried to Override
onItemMove
, but it doesn't actually override its superclass.
List Adaptor Class: This contains the onItemMove command
public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ListViewHolder> { private static final String TAG = "ListAdapter"; Context context; private List<UserData> dataList = new ArrayList<>(); LayoutInflater inflater; Listener listener; DbHelper dbHelper; public interface Listener { void nameToChnge(String name); } public ListAdapter(Context context, List<UserData> dataList1) { this.context = context; this.dataList = dataList1; this.listener= (Listener) context; inflater = LayoutInflater.from(context); } @Override public ListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View convertView = inflater.inflate(R.layout.recylerview_one, parent, false); ListViewHolder viewHolder = new ListViewHolder(convertView); return viewHolder; } @Override public void onBindViewHolder(ListViewHolder holder, final int position) { holder.tv_name.setText(dataList.get(position).name); holder.tv_quantity.setText(dataList.get(position).quantity); holder.tv_description.setText(dataList.get(position).description + ""); holder.relLayout.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v) { String s = dataList.get(position).id; Integer stringo = Integer.parseInt(s); Intent intent = new Intent(context, ItemEditActivity.class); intent.putExtra("ItemNumber", stringo); context.startActivity(intent); } }); } @Override public int getItemCount() { return dataList.size(); } class ListViewHolder extends RecyclerView.ViewHolder { TextView tv_name, tv_quantity, tv_description; RelativeLayout relLayout; public ListViewHolder(View itemView) { super(itemView); tv_name = (TextView) itemView.findViewById(R.id.nameDisplay); tv_quantity = (TextView) itemView.findViewById(R.id.quantityDisplay); tv_description = (TextView) itemView.findViewById(R.id.descriptionDisplay); relLayout = (RelativeLayout) itemView.findViewById(R.id.relLayout); } } public void onItemDismiss(final int position) { dataList.remove(position); notifyItemRemoved(position); } public void onItemMove(int fromPosition, int toPosition) { Collections.swap(dataList, fromPosition, toPosition); notifyItemMoved(fromPosition, toPosition); } }
ItemTouchHelper Class:
public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback{ private final ListAdapter mAdapter; public SimpleItemTouchHelperCallback(ListAdapter adapter) { mAdapter = adapter; } @Ov erride public boolean isLongPressDragEnabled() { return true; } @Override public boolean isItemViewSwipeEnabled() { return true; } @Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END; return makeMovementFlags(dragFlags, swipeFlags); } @Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { mAdapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition()); return true; } @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { mAdapter.onItemDismiss(viewHolder.getAdapterPosition()); } }
Part of the Main Activity where I initialise the RecyclerView
and SimpleItemTouchHelperCallback:
public class MainActivity extends AppCompatActivity implements ListAdapter.Listener { private static final String TAG = "MainActivity"; RecyclerView recyclerView; DbHelper dbHelper; ListAdapter adapter; FloatingActionButton fab; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); introItem(); dbHelper = DbHelper.getInstance(getApplicationContext()); recyclerView= (RecyclerView) findViewById(R.id.rv_contactlist); adapter = new ListAdapter(this, dbHelper.getAllUser()); recyclerView.setAdapter(adapter); recyclerView.setLayoutManager(new LinearLayoutManager(this)); ItemTouchHelper.Callback callback = new SimpleItemTouchHelperCallback(adapter); ItemTouchHelper touchHelper = new ItemTouchHelper(callback); touchHelper.attachToRecyclerView(recyclerView); totalQuantity(); adapter.notifyDataSetChanged(); fabHideShow(); versionCheckMethod(); }
2 Answers
Answers 1
You just need to study the code of this sample and implement it: https://github.com/iPaulPro/Android-ItemTouchHelper-Demo/tree/master/app/src/main/java/co/paulburke/android/itemtouchhelperdemo
But basically what you need is to create two interfaces. The first one:
public interface ItemTouchHelperAdapter { /** * Called when an item has been dragged far enough to trigger a move. This is called every time * an item is shifted, and not at the end of a "drop" event. * * @param fromPosition The start position of the moved item. * @param toPosition Then end position of the moved item. */ void onItemMove(int fromPosition, int toPosition); /** * Called when an item has been dismissed by a swipe. * * @param position The position of the item dismissed. */ void onItemDismiss(int position); }
And the second one:
public interface ItemTouchHelperViewHolder { /** * Implementations should update the item view to indicate it's active state. */ void onItemSelected(); /** * state should be cleared. */ void onItemClear(); }
The in the SimpleItemTouchHelperCallback something like that:
public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback { private final ItemTouchHelperAdapter mAdapter; public SimpleItemTouchHelperCallback(ItemTouchHelperAdapter adapter) { mAdapter = adapter; } @Override public boolean isLongPressDragEnabled() { return true; } @Override public boolean isItemViewSwipeEnabled() { return false; } @Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; final int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END; return makeMovementFlags(dragFlags, swipeFlags); } @Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) { mAdapter.onItemMove(source.getAdapterPosition(), target.getAdapterPosition()); return true; } @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int i) { mAdapter.onItemDismiss(viewHolder.getAdapterPosition()); } @Override public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) { if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) { ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder; itemViewHolder.onItemSelected(); } super.onSelectedChanged(viewHolder, actionState); } @Override public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { super.clearView(recyclerView, viewHolder); ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder; itemViewHolder.onItemClear(); } }
Then you have to change the RecyclerViewAdapter, and implement there the onItemMove
method as we said in the oder comments. And you should implemement also the onStartDragListener
like so:
public interface OnStartDragListener { /** * Called when a view is requesting a start of a drag. * * @param viewHolder The holder of the view to drag. */ void onStartDrag(RecyclerView.ViewHolder viewHolder); }
And then use it in your adapter onBindViewHolder (remember to implement all the interfaces in the class declaration) like this (You need to change this code based on your variable name):
holder.handleView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) { mDragStartListener.onStartDrag(holder); } return false; } });
Where mDragListener is a OnStartDragListener
variable.
Finally check this guide for more: http://valokafor.com/remember-drag-and-drop-position-with-recyclerview/
Answers 2
I found an advance library
The demo is on youtube here
0 comments:
Post a Comment