RecyclerView бросить и нажмите элемент
У меня есть RecyclerView
это имеет сетку предметов. При нажатии на элемент, он выделяется.
Я также хочу, чтобы, когда пользователь проводит пальцем вправо, вызывается метод "next", а когда пользователь проводит пальцем влево, вызывается "предыдущий" метод.
Однако эти два не работают друг с другом, поскольку каждый перехватывает события другого.
Как мне заставить их работать вместе?
Это мой код:
RecyclerView Adapter
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
myHolder = holder as MyView;
myHolder.mMainView.SetOnClickListener(this);
if (selected_position == position)
{
holder.ItemView.SetBackgroundColor(Color.LightGray);
}
else
{
holder.ItemView.SetBackgroundColor(Color.Transparent);
}
}
public void OnClick(View v)
{
int position = mRecyclerView.GetChildLayoutPosition((View)sender);
// Updating old as well as new positions
NotifyItemChanged(selected_position);
selected_position = position;
NotifyItemChanged(selected_position);
}
Фрагмент, который содержит RecyclerView
calendarRecyclerView.SetOnTouchListener(this);
public bool OnTouch(View v, MotionEvent e)
{
switch (e.Action)
{
case MotionEventActions.Down:
x1 = e.GetX();
break;
case MotionEventActions.Up:
x2 = e.GetX();
float deltaX = x2 - x1;
if (Math.Abs(deltaX) > MIN_DISTANCE)
{
// Left to Right swipe action
if (x2 > x1)
{
NextMonth();
}
// Right to left swipe action
else
{
PreviousMonth();
}
}
break;
}
return false;
}
Потому что я положил return false
в событии OnTouch происходит событие щелчка элемента. Однако событие MouseDown не запускается в OnTouch, что предотвращает повторное обнаружение (поскольку x1 всегда равно 0).
2 ответа
Событие OnTouch вызывается при первом нажатии, а событие OnClick вызывается только при втором щелчке.
Так как MotionEventActions.Down
а также OnClick
конфликт. В качестве обходного пути я предлагаю вам изменить цвет фона на MotionEventActions.Down
событие.
- Создайте свой собственный слушатель кликов
- Позвоните слушателю, когда вы дотронетесь до предметов.
- Слушатель перезвонит
MainActivity
уведомить об изменении предмета. - Одновременно будет вызвано сенсорное событие.
Я установил OnTouchListener
в видоискателе:
public class MyViewHolder:RecyclerView.ViewHolder,IOnTouchListener
{
private TextView textView;
private MyItemClickListener mListener;
private Context myContext;
float x1 = 0;
float x2 = 0;
public TextView TextView { get { return textView; } }
public MyViewHolder(View v, MyItemClickListener mItemClickListener) : base(v)
{
textView = v.FindViewById<TextView>(Resource.Id.itemText);
mListener = mItemClickListener;
v.SetOnTouchListener(this);
}
public MyViewHolder(View v, MyItemClickListener mItemClickListener, Context myContext) : this(v, mItemClickListener)
{
this.myContext = myContext;
}
public bool OnTouch(View v, MotionEvent e)
{
switch (e.Action)
{
case MotionEventActions.Down:
x1 = e.GetX();
if (mListener != null)
{
mListener.OnItemClick(v, Position);
}
break;
case MotionEventActions.Up:
x2 = e.GetX();
float deltaX = x2 - x1;
if (Math.Abs(deltaX) > 5)
{
// Left to Right swipe action
if (x2 > x1)
{
NextMonth(v);
}
// Right to left swipe action
else
{
PreviousMonth(v);
}
}
break;
}
return true;
}
public Boolean NextMonth(View v)
{
Toast.MakeText(myContext, "NextMonth called", ToastLength.Short).Show();
return true;
}
public Boolean PreviousMonth(View v)
{
Toast.MakeText(myContext, "PreviousMonth called", ToastLength.Short).Show();
return true;
}
}
Определен интерфейс клика:
public interface MyItemClickListener
{
void OnItemClick(View view, int postion);
}
установить обратный вызов клика в MainActivity
изменить цвет фона:
public class MainActivity : Activity,MyItemClickListener
{
RecyclerView mRecyclerView;
RecyclerView.LayoutManager mLayoutManager;
CustomAdapter mAdapter;
string[] dataSet;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
InitDataSet();
SetContentView(Resource.Layout.Main);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView = FindViewById<RecyclerView>(Resource.Id.recyclerView);
mRecyclerView.SetLayoutManager(mLayoutManager);
mAdapter = new CustomAdapter(dataSet,this);
mAdapter.setOnItemClickListener(this);
mRecyclerView.SetAdapter(mAdapter);
//mRecyclerView.SetOnTouchListener(this);
}
public void InitDataSet()
{
dataSet = new string[60];
for (int i = 0; i < 60; i++)
{
dataSet[i] = "This is element #" + i;
}
}
public void OnItemClick(View view, int postion)
{
mAdapter.NotifyItemChanged(CustomAdapter.selected_position);
CustomAdapter.selected_position = postion;
mAdapter.NotifyItemChanged(postion);
}
}
}
Примечание. Держите палец быстрым, если скорость достаточно низкая, MotionEventActions.Down
не будет называться.
Скриншот:
Попробуйте это в своем клике
public void OnClick(View v)
{
int position = mRecyclerView.GetChildLayoutPosition((View)sender);
int oldPosition = selectedPosition;
selected_position = position;
// Updating old as well as new positions
NotifyItemChanged(oldPosition);
NotifyItemChanged(selected_position);
}
Обратите внимание, что вы должны изменить выбранную позицию перед обновлением обоих элементов