Hello,
Welcome to our Microsoft Q&A platform!
I created a basic demo to test the function, it works as expected. This problem will occur only when I comment the adapter.NotifyItemMoved
line code. If I change the 'OnMove' method like below, it still works fine.
public override bool OnMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target)
{
if (viewHolder.ItemViewType != target.ItemViewType)
{
return false;
}
var adapter = recyclerView.GetAdapter();
// Notify the adapter of the move
adapter.NotifyItemMoved(viewHolder.AdapterPosition, target.AdapterPosition);
return true;
}
Here is the sample code, please check it to get the difference.
MainActivity class
public class MainActivity : AppCompatActivity, IOnStartDragListener
{
public static MainActivity Instance;
RecyclerView recyclerView;
RecyclerView.LayoutManager layoutManager;
public static ObservableCollection<TestModel> data;
private ItemTouchHelper _mItemTouchHelper;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
SetContentView(Resource.Layout.activity_main);
Instance = this;
recyclerView = FindViewById<RecyclerView>(Resource.Id.test_recyclerView);
layoutManager = new LinearLayoutManager(this);
data = new ObservableCollection<TestModel>();
data.Add(new TestModel { content = "item_1" });
data.Add(new TestModel { content = "item_2" });
data.Add(new TestModel { content = "item_3" });
TestAdapter testAdapter = new TestAdapter(data, this);
recyclerView.SetLayoutManager(layoutManager);
recyclerView.SetAdapter(testAdapter);
ItemTouchHelper.Callback callback = new SimpleItemTouchHelperCallback(testAdapter);
_mItemTouchHelper = new ItemTouchHelper(callback);
_mItemTouchHelper.AttachToRecyclerView(recyclerView);
}
public void OnStartDrag(RecyclerView.ViewHolder viewHolder)
{
_mItemTouchHelper.StartDrag(viewHolder);
}
}
ViewHolder and Adapter class
public class TestViewHolder : RecyclerView.ViewHolder
{
public TextView ItemText { get; set; }
public TestViewHolder(View itemView) : base(itemView)
{
ItemText = itemView.FindViewById<TextView>(Resource.Id.itemText);
}
}
public class TestAdapter : RecyclerView.Adapter, ITemTouchHelperAdapter, IOnLongClickListener
{
public ObservableCollection<TestModel> list;
TestViewHolder viewHolder;
private readonly IOnStartDragListener dragStartListener;
public TestAdapter(ObservableCollection<TestModel> list, IOnStartDragListener dragStartListener)
{
this.list = list;
this.dragStartListener = dragStartListener;
}
public override int ItemCount
{
get
{
return list.Count;
}
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
viewHolder = holder as TestViewHolder;
viewHolder.ItemText.Text = list[position].content;
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
View itemView = LayoutInflater.From(MainActivity.Instance).Inflate(Resource.Layout.recyclerView_itemLayout, parent, false);
TestViewHolder viewHolder = new TestViewHolder(itemView);
return viewHolder;
}
public bool OnItemMove(int fromPosition, int toPosition)
{
var tempPlanResource = list[fromPosition];
list[fromPosition] = list[toPosition];
list[toPosition] = tempPlanResource;
MainActivity.data = list;
NotifyItemMoved(fromPosition, toPosition);
return true;
}
public void OnItemDismiss(int position)
{
var item = list[position];
list.Remove(item);
NotifyItemRemoved(position);
}
public bool OnLongClick(View v)
{
dragStartListener.OnStartDrag(viewHolder);
return true;
}
}
public class TestModel
{
public string content { get; set; }
}
Related interfaces and touch callback class
public interface IOnStartDragListener
{
void OnStartDrag(RecyclerView.ViewHolder viewHolder);
}
public interface ITemTouchHelperAdapter
{
bool OnItemMove(int fromPosition, int toPosition);
void OnItemDismiss(int position);
}
public class SimpleItemTouchHelperCallback : ItemTouchHelper.Callback
{
private readonly ITemTouchHelperAdapter _mAdapter;
public SimpleItemTouchHelperCallback(ITemTouchHelperAdapter adapter)
{
_mAdapter = adapter;
}
public override int GetMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder)
{
const int dragFlags = ItemTouchHelper.Up | ItemTouchHelper.Down;
const int swipeFlags = ItemTouchHelper.ActionStateIdle;
return MakeMovementFlags(dragFlags, swipeFlags);
}
public override bool OnMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target)
{
if (viewHolder.ItemViewType != target.ItemViewType)
{
return false;
}
_mAdapter.OnItemMove(viewHolder.AdapterPosition, target.AdapterPosition);
return true;
}
public override void OnSwiped(RecyclerView.ViewHolder viewHolder, int direction)
{
_mAdapter.OnItemDismiss(viewHolder.AdapterPosition);
}
}
Best Regards,
Jarvan Zhang
If the response is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.