按位置直接从 RecyclerView 访问 ViewHolder
Accessing a ViewHolder, directly from the RecyclerView, by position
我有一个 RecyclerView,它显示了从数据库派生的一系列视图。我想通过突出显示其边缘来确认用户已经 select 编辑了其中一个视图,我已经成功地做到了这一点。如果用户继续 select 一个不同的 运行t 选项,我希望删除原始 selection 上的突出显示。这是我 运行 有点麻烦的地方。
最初的亮点没有问题,就像我在内部做的那样。但是,我不知道如何仅通过其适配器位置访问先前的视图。我已经在 Whosebug 上搜索了大约一个小时,因为我在 Android API 或 google 中找不到太多内容。许多用户似乎都在问类似的问题,但最终,细微的差异会使任何有用的答案无效。
在我的 ViewHolder
中,这是我的 RecyclerView
的内部 public class
,我有一个 OnClickListener
如下:
@Override
public void onClick(View view) {
if(!selected) {
selected = true;
view.setBackgroundResource(R.drawable.default_selection_background);
} else {
selected = false;
view.setBackgroundResource(0);
}
UpdateSelected(getAdapterPosition());
}
这指向我的 RecyclerView
,f运行kly,我还没有向我的 UpdateSelected(int position)
方法添加任何工作代码。
如果有帮助,我打算让它像这样运行:
void UpdateSelected(int position) {
if(position != currentlySelected) {
ViewHolder[currentlySelected].Deselect();
}
}
public class ViewHolder extends RecyclerView.ViewHolder {
...
public void Deselect() {
// and from here, I can go on as normal.
}
}
我注意到用户建议其他人出于 UI 目的使用 getLayoutPosition()
推导出位置,除非他们特别希望继续使用内部数据,这正是我打算做的。
如何使用 RecyclerView 的位置访问特定的 ViewHolder?
你可以这样做。
在您的适配器中,创建一个成员变量来跟踪所选项目的位置。
int selectedPosition = -1; // -1 some default value for nothing selected
然后在你的onBindViewHolder
of recycler view adapter
int backgroundRes = (position == selectedPosition)? R.drawable.default_selection_background : 0;
view.setBackgroundResource(backgroundRes);
最后在你的 viewholder 的 onClick 中
@Override
public void onClick(View view) {
selectedPosition = getAdapterPosition();
notifyDataSetChanged();
}
您可以通过它在 recyclerview 中的位置访问 viewholder
这是我的实现
recyclerView.addOnItemTouchListener(new RecyclerItemClickListener(this,
recyclerView, new RecyclerItemClickListener.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
/*your coding */
}
@Override
public void onItemLongClick(View view, int position) {
}
}));
并创建 Class
public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
private OnItemClickListener mListener;
private GestureDetector mGestureDetector;
public RecyclerItemClickListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener) {
mListener = listener;
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
@Override
public void onLongPress(MotionEvent e) {
View childView = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null) {
mListener.onItemLongClick(childView, recyclerView.getChildPosition(childView));
}
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
View childView = view.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
mListener.onItemClick(childView, view.getChildPosition(childView));
}
return false;
}
@Override
public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
public interface OnItemClickListener {
void onItemClick(View view, int position);
void onItemLongClick(View view, int position);
}
}
您可以将视图标记为已选中或未选中,并Android使用可绘制选择器更改背景,而不是手动交换背景资源。
res/drawable/background.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="@drawable/default_selection_background" />
<item android:drawable="@null" />
</selector>
background.xml
将被设置为项目布局中的 android:background
XML。
然后在您的 onBindViewHolder(ViewHolder holder, int position)
中更新 Android 视图的状态:
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
boolean isSelected = position == selectedPosition;
holder.itemView.setSelected(isSelected);
}
对我来说,我更喜欢有一个更笨、逻辑更少的适配器。您可以通过保留一个 ViewModel 列表(数据 类 来表示您将在视图中显示的内容 - 不多也不少),其中一个属性可以是所选标志(在每个 ViewModel 中)。
当用户选择或取消选择视图时,回调会向展示器发出更新,然后更新适配器,并通知适配器哪些位置已更新。这意味着将当前选定的项目(最好是 ID,但可以存储 ViewModel 或位置)保留在演示者中,以便您可以更新它。
我有一个 RecyclerView,它显示了从数据库派生的一系列视图。我想通过突出显示其边缘来确认用户已经 select 编辑了其中一个视图,我已经成功地做到了这一点。如果用户继续 select 一个不同的 运行t 选项,我希望删除原始 selection 上的突出显示。这是我 运行 有点麻烦的地方。
最初的亮点没有问题,就像我在内部做的那样。但是,我不知道如何仅通过其适配器位置访问先前的视图。我已经在 Whosebug 上搜索了大约一个小时,因为我在 Android API 或 google 中找不到太多内容。许多用户似乎都在问类似的问题,但最终,细微的差异会使任何有用的答案无效。
在我的 ViewHolder
中,这是我的 RecyclerView
的内部 public class
,我有一个 OnClickListener
如下:
@Override
public void onClick(View view) {
if(!selected) {
selected = true;
view.setBackgroundResource(R.drawable.default_selection_background);
} else {
selected = false;
view.setBackgroundResource(0);
}
UpdateSelected(getAdapterPosition());
}
这指向我的 RecyclerView
,f运行kly,我还没有向我的 UpdateSelected(int position)
方法添加任何工作代码。
如果有帮助,我打算让它像这样运行:
void UpdateSelected(int position) {
if(position != currentlySelected) {
ViewHolder[currentlySelected].Deselect();
}
}
public class ViewHolder extends RecyclerView.ViewHolder {
...
public void Deselect() {
// and from here, I can go on as normal.
}
}
我注意到用户建议其他人出于 UI 目的使用 getLayoutPosition()
推导出位置,除非他们特别希望继续使用内部数据,这正是我打算做的。
如何使用 RecyclerView 的位置访问特定的 ViewHolder?
你可以这样做。
在您的适配器中,创建一个成员变量来跟踪所选项目的位置。
int selectedPosition = -1; // -1 some default value for nothing selected
然后在你的onBindViewHolder
of recycler view adapter
int backgroundRes = (position == selectedPosition)? R.drawable.default_selection_background : 0;
view.setBackgroundResource(backgroundRes);
最后在你的 viewholder 的 onClick 中
@Override
public void onClick(View view) {
selectedPosition = getAdapterPosition();
notifyDataSetChanged();
}
您可以通过它在 recyclerview 中的位置访问 viewholder
这是我的实现
recyclerView.addOnItemTouchListener(new RecyclerItemClickListener(this,
recyclerView, new RecyclerItemClickListener.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
/*your coding */
}
@Override
public void onItemLongClick(View view, int position) {
}
}));
并创建 Class
public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
private OnItemClickListener mListener;
private GestureDetector mGestureDetector;
public RecyclerItemClickListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener) {
mListener = listener;
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
@Override
public void onLongPress(MotionEvent e) {
View childView = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null) {
mListener.onItemLongClick(childView, recyclerView.getChildPosition(childView));
}
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
View childView = view.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
mListener.onItemClick(childView, view.getChildPosition(childView));
}
return false;
}
@Override
public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
public interface OnItemClickListener {
void onItemClick(View view, int position);
void onItemLongClick(View view, int position);
}
}
您可以将视图标记为已选中或未选中,并Android使用可绘制选择器更改背景,而不是手动交换背景资源。
res/drawable/background.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="@drawable/default_selection_background" />
<item android:drawable="@null" />
</selector>
background.xml
将被设置为项目布局中的 android:background
XML。
然后在您的 onBindViewHolder(ViewHolder holder, int position)
中更新 Android 视图的状态:
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
boolean isSelected = position == selectedPosition;
holder.itemView.setSelected(isSelected);
}
对我来说,我更喜欢有一个更笨、逻辑更少的适配器。您可以通过保留一个 ViewModel 列表(数据 类 来表示您将在视图中显示的内容 - 不多也不少),其中一个属性可以是所选标志(在每个 ViewModel 中)。
当用户选择或取消选择视图时,回调会向展示器发出更新,然后更新适配器,并通知适配器哪些位置已更新。这意味着将当前选定的项目(最好是 ID,但可以存储 ViewModel 或位置)保留在演示者中,以便您可以更新它。