Java 回收浏览并点击物品
我有一个Java 回收浏览并点击物品,java,android,xamarin,android-recyclerview,android-touch-event,Java,Android,Xamarin,Android Recyclerview,Android Touch Event,我有一个RecyclerView,它有一个项目网格。单击某个项目时,它会高亮显示。 我还希望当用户向右滑动时,调用“下一步”方法,当用户向左滑动时,调用“上一步”方法。 但是,这两种方法彼此不起作用,因为它们都截取对方的事件。 我如何让他们一起工作 这是我的代码: 回收视图适配器 public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position) { myHolder =
RecyclerView
,它有一个项目网格。单击某个项目时,它会高亮显示。我还希望当用户向右滑动时,调用“下一步”方法,当用户向左滑动时,调用“上一步”方法。
但是,这两种方法彼此不起作用,因为它们都截取对方的事件。
我如何让他们一起工作 这是我的代码: 回收视图适配器
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;
}
因为我在OnTouch事件中放入了
return false
,所以触发了该项目的click事件。但是,MouseDown事件不会在OnTouch中触发,从而阻止刷回检测(因为x1始终为0)。在onClick中尝试此操作
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);
}
请注意,在更新这两个项目之前,必须更改选定的位置
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;
}
}
在main活动
中设置单击回调以更改背景颜色:
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);
}
}
}
public类main活动:活动,MyItemClickListener
{
回收视图mRecyclerView;
RecyclerView.LayoutManager mllayoutmanager;
定制适配器mAdapter;
字符串[]数据集;
创建时受保护的覆盖无效(捆绑包)
{
base.OnCreate(bundle);
InitDataSet();
SetContentView(Resource.Layout.Main);
mLayoutManager=新的LinearLayoutManager(此);
mRecyclerView=findviewbyd(Resource.Id.recyclerView);
mRecyclerView.SetLayoutManager(mllayoutmanager);
mAdapter=新的CustomAdapter(数据集,此);
mAdapter.setOnItemClickListener(本);
mRecyclerView.SetAdapter(mAdapter);
//mRecyclerView.SetOnTouchListener(这个);
}
公共void InitDataSet()
{
数据集=新字符串[60];
对于(int i=0;i<60;i++)
{
数据集[i]=“这是元素#”+i;
}
}
公共空白位置单击(视图、内部位置)
{
mAdapter.NotifyItemChanged(CustomAdapter.selected_位置);
CustomAdapter.selected_position=position;
mAdapter.NotifyItemChanged(职位);
}
}
}
注意:保持手指快速移动,如果速度足够慢,则不会调用MotionEventActions.Down
。
屏幕截图:
然而,这两种方法彼此不协调,因为它们都截取对方的事件,您能对此进行更多解释吗line@OmarHossamEldin我的意思是,并不是所有的事件都被完全调用,因为它们彼此“阻塞”。在问题的底部添加了解释。如果仍然不清楚,请告诉我。您可以使用ViewPagerAs中的RecyclerView作为开始,您需要在
NextMonth
和PreviousMonth
返回true之后添加,然后,您必须记录这些值,以检查您的值是如何计算的,以及它是否符合您的头脑或大脑中的需要not@OmarHossamEldin我在你说的地方加上了returntrue。现在,NextMonth和PreviousMonth都被调用,但是您必须在某个项目上单击两次才能突出显示。谢谢。但问题不在于点击事件。它很好用。问题是OnTouch事件在第一次单击时被调用,而OnClick仅在第二次单击时被调用。
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);
}
}
}