我正在试验支持库的recyclerview和卡片。我有回收卡的卡片。每张卡的右上角都有一个“x”图标可将其删除:
卡片xml,list_item.xml
:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/taskDesc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:textSize="40sp"
android:text="hi"/>
<ImageView
android:id="@+id/xImg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:src="@drawable/ic_remove"/>
</RelativeLayout>
</android.support.v7.widget.CardView>
我尝试使用我在notifyItemRemoved(position)
TaskAdapter.java
public class TaskAdapter extends RecyclerView.Adapter<TaskAdapter.TaskViewHolder> {
private List<Task> taskList;
private TaskAdapter thisAdapter = this;
// cache of views to reduce number of findViewById calls
public static class TaskViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
protected TextView taskTV;
protected ImageView closeBtn;
public TaskViewHolder(View v) {
super(v);
taskTV = (TextView)v.findViewById(R.id.taskDesc);
}
@Override
public void onClick(View v) {
int position = v.getTag();
adapter.notifyItemRemoved(position);
}
}
public TaskAdapter(List<Task> tasks) {
if(tasks == null)
throw new IllegalArgumentException("tasks cannot be null");
taskList = tasks;
}
// onBindViewHolder binds a model to a viewholder
@Override
public void onBindViewHolder(TaskViewHolder taskViewHolder, int pos) {
final int position = pos;
Task currTask = taskList.get(pos);
taskViewHolder.taskTV.setText(currTask.getDescription());
taskViewHolder.closeBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
thisAdapter.notifyItemRemoved(position);
}
});
}
@Override
public int getItemCount() {
return taskList.size();
}
// inflates row to create a viewHolder
@Override
public TaskViewHolder onCreateViewHolder(ViewGroup parent, int pos) {
View itemView = LayoutInflater.from(parent.getContext()).
inflate(R.layout.list_item, parent, false);
return new TaskViewHolder(itemView);
}
}
中使用的位置标记行:
onClick.
这不起作用,因为您无法设置标签,也无法从{{1}}
访问适配器答案 0 :(得分:93)
将onClickListener
设置为onBindViewHolder()
,您可以从那里访问该位置。如果您在ViewHolder
中设置它们,除非您将该位置传递到ViewHolder
修改强>
由于pskink
指出ViewHolder
有一个getPosition()
所以你最初这样做的方式是正确的。
点击视图后,您可以在getPosition()
中使用ViewHolder
并返回位置
<强>更新强>
getPosition()
现已弃用,已替换为getAdapterPosition()
Kotlin代码:
override fun onBindViewHolder(holder: MyHolder, position: Int) {
// - get element from your dataset at this position
val item = myDataset.get(holder.adapterPosition)
}
答案 1 :(得分:14)
另一种方法 - 使用View类的 setTag()和 getTag()方法。
在适配器的onBindViewHolder方法中使用 setTag()
public MyDbContext(string connectionString)
: base(connectionString)
{
if (!Database.Exists())
{
Database.SetInitializer(new CreateInitializer());
}
else
{
bool isCompatible = false;
isCompatible = Database.CompatibleWithModel(false);
if (!isCompatible)
{
// Here is where it gets thrown.
throw new ExceptionDatabaseVersion("Data structure changed");
}
}
}`
其中mCardView在myViewHolder类中定义
@Override
public void onBindViewHolder(myViewHolder viewHolder, int position) {
viewHolder.mCardView.setTag(position);
}
在OnClickListener实现中使用 getTag()
private class myViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public View mCardView;
public myViewHolder(View view) {
super(view);
mCardView = (CardView) view.findViewById(R.id.card_view);
mCardView.setOnClickListener(this);
}
}
答案 2 :(得分:8)
补充@tyczj答案:
通用适配器Pseido代码:
public abstract class GenericRecycleAdapter<T, K extends RecyclerView.ViewHolder> extends RecyclerView.Adapter{
private List<T> mList;
//default implementation code
public abstract int getLayout();
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(getLayout(), parent, false);
return getCustomHolder(v);
}
public Holders.TextImageHolder getCustomHolder(View v) {
return new Holders.TextImageHolder(v){
@Override
public void onClick(View v) {
onItem(mList.get(this.getAdapterPosition()));
}
};
}
abstract void onItem(T t);
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
onSet(mList.get(position), (K) holder);
}
public abstract void onSet(T item, K holder);
}
ViewHolder:
public class Holders {
public static class TextImageHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
public TextView text;
public TextImageHolder(View itemView) {
super(itemView);
text = (TextView) itemView.findViewById(R.id.text);
text.setOnClickListener(this);
}
@Override
public void onClick(View v) {
}
}
}
适配器使用:
public class CategoriesAdapter extends GenericRecycleAdapter<Category, Holders.TextImageHolder> {
public CategoriesAdapter(List<Category> list, Context context) {
super(list, context);
}
@Override
void onItem(Category category) {
}
@Override
public int getLayout() {
return R.layout.categories_row;
}
@Override
public void onSet(Category item, Holders.TextImageHolder holder) {
}
}
答案 3 :(得分:5)
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
FrameLayout root;
public ViewHolder(View itemView) {
super(itemView);
root = (FrameLayout) itemView.findViewById(R.id.root);
root.setOnClickListener(this);
}
@Override
public void onClick(View v) {
LogUtils.errorLog("POS_CLICKED: ",""+getAdapterPosition());
}
}
答案 4 :(得分:3)
就个人而言,我发现并且对我有用的最简单的方法如下:
在“RecycleAdapter”类(子类)中创建一个界面
public interface ClickCallback {
void onItemClick(int position);
}
在构造函数中添加接口变量作为参数。
private String[] items;
private ClickCallback callback;
public RecyclerAdapter(String[] items, ClickCallback clickCallback) {
this.items = items;
this.callback = clickCallback;
}
在ViewHolder(另一个子类)中设置Click侦听器并通过界面传递'position'
AwesomeViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
callback.onItemClick(getAdapterPosition());
}
});
mTextView = (TextView) itemView.findViewById(R.id.mTextView);
}
现在,在活动/片段中初始化回收器适配器时,只需创建一个新的'ClickCallback'(界面)
String[] values = {"Hello","World"};
RecyclerAdapter recyclerAdapter = new RecyclerAdapter(values, new RecyclerAdapter.ClickCallback() {
@Override
public void onItemClick(int position) {
// Do anything with the item position
}
});
这对我来说。 :)
答案 5 :(得分:2)
我这样解决了
class MyOnClickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
int itemPosition = mRecyclerView.getChildAdapterPosition(v);
myResult = results.get(itemPosition);
}
}
在适配器中
@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_wifi, parent, false);
v.setOnClickListener(new MyOnClickListener());
ViewHolder vh = new ViewHolder(v);
return vh;
}
答案 6 :(得分:2)
获得专注的孩子,并用它来获得适配器中的位置。
mRecyclerView.getChildAdapterPosition(mRecyclerView.getFocusedChild())
答案 7 :(得分:1)
我认为获得项目位置的最正确方法是
.article {
@-: ~'>';
@{-}, *:not(.example) {
h1 {color: red}
h2 {color: blue}
}
}
由于视图,您不一定要点击行布局的根视图。如果视图不是根视图(例如按钮),您将获得类强制转换异常。因此,首先我们需要找到视图,这是你reciclerview的直接孩子。然后,使用recyclerView.getChildAdapterPosition(view);
查找位置答案 8 :(得分:1)
1。创建类名称RecyclerTouchListener.java
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
public class RecyclerTouchListener implements RecyclerView.OnItemTouchListener
{
private GestureDetector gestureDetector;
private ClickListener clickListener;
public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final ClickListener clickListener) {
this.clickListener = clickListener;
gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
@Override
public void onLongPress(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null) {
clickListener.onLongClick(child, recyclerView.getChildAdapterPosition(child));
}
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View child = rv.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
clickListener.onClick(child, rv.getChildAdapterPosition(child));
}
return false;
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
public interface ClickListener {
void onClick(View view, int position);
void onLongClick(View view, int position);
}
}
2。致电RecyclerTouchListener
recycleView.addOnItemTouchListener(new RecyclerTouchListener(this, recycleView,
new RecyclerTouchListener.ClickListener() {
@Override
public void onClick(View view, int position) {
Toast.makeText(MainActivity.this,Integer.toString(position),Toast.LENGTH_SHORT).show();
}
@Override
public void onLongClick(View view, int position) {
}
}));
答案 9 :(得分:0)
无需让ViewHolder实现View.OnClickListener。您可以通过在RecyclerView的方法onCreateViewHolder中设置单击侦听器来直接获取单击的位置.Adapter这里是一个代码示例:
public class ItemListAdapterRecycler extends RecyclerView.Adapter<ItemViewHolder>
{
private final List<Item> items;
public ItemListAdapterRecycler(List<Item> items)
{
this.items = items;
}
@Override
public ItemViewHolder onCreateViewHolder(final ViewGroup parent, int viewType)
{
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_row, parent, false);
view.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
int currentPosition = getClickedPosition(view);
Log.d("DEBUG", "" + currentPosition);
}
});
return new ItemViewHolder(view);
}
@Override
public void onBindViewHolder(ItemViewHolder itemViewHolder, int position)
{
...
}
@Override
public int getItemCount()
{
return items.size();
}
private int getClickedPosition(View clickedView)
{
RecyclerView recyclerView = (RecyclerView) clickedView.getParent();
ItemViewHolder currentViewHolder = (ItemViewHolder) recyclerView.getChildViewHolder(clickedView);
return currentViewHolder.getAdapterPosition();
}
}
答案 10 :(得分:0)
每个项目都会调用onBindViewHolder(),并且当您可以在ViewHolder构造函数中调用一次时,将onBindVieHolder()内的点击侦听器设置为重复是不必要的选择。
public class MyViewHolder extends RecyclerView.ViewHolder
implements View.OnClickListener{
public final TextView textView;
public MyViewHolder(View view){
textView = (TextView) view.findViewById(R.id.text_view);
view.setOnClickListener(this);
// getAdapterPosition() retrieves the position here.
}
@Override
public void onClick(View v){
// Clicked on item
Toast.makeText(mContext, "Clicked on position: " + getAdapterPosition(), Toast.LENGTH_SHORT).show();
}
}
答案 11 :(得分:0)
@Override
public void onClick(View v) {
int pos = getAdapterPosition();
}
就这么简单,在ViewHolder
答案 12 :(得分:0)
使用数据绑定时,您需要从项目的点击侦听器内部了解RecyclerView点击位置:
科特琳
val recyclerView = view.parent as RecyclerView
val position = recyclerView.getChildAdapterPosition(view)