繁体   English   中英

recyclerview项目位置错误

[英]wrong recyclerview item position

我的recyclerview滚动效果很好,但是当它包含两个以上的项目并单击最后一个项目之前,或者在它给我错误的位置之前单击它,并抛出NullPointerException,这是我从适配器到侦听器的全部代码。 我的代码:

public class ListAdapter extends RecyclerView.Adapter<ViewHolder> {

private List<ItemView> items;
private Context context;

public ListAdapter(List<ItemView> items, Context context) {
    this.items = items;
    this.context = context;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.item_style, parent, false);
    return new ViewHolder(view);
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    ItemView i = items.get(position);

    ViewHolder.setHeadText(i.getHead());
    ViewHolder.setScoreText(i.getContent());
}
@Override
public int getItemCount() {
    return items.size();
}

}

class ViewHolder extends RecyclerView.ViewHolder {
private RecyclerViewOnTouchItemListener.ClickListener clickListener;
private static TextView headText, urlText;
private ConstraintLayout itemLayout;

public ViewHolder(View itemView) {
    super(itemView);

    headText = (TextView) itemView.findViewById(R.id.list_item_header);
    urlText = (TextView) itemView.findViewById(R.id.list_item_content);
    itemLayout = (ConstraintLayout) itemView.findViewById(R.id.item_list);
    // itemLayout.setOnClickListener(this);
}


public static void setHeadText(String headText) {
    ViewHolder.headText.setText(headText);
}

public static void setScoreText(String scoreText) {
    ViewHolder.urlText.setText(scoreText);
}

public static String getHeadText(){return headText.getText().toString();}

public static String getUrlText(){return urlText.getText().toString();}

}

class RecyclerViewOnTouchItemListener implements RecyclerView.OnItemTouchListener {

private GestureDetector gestureDetector;
private ClickListener clickListener;

public RecyclerViewOnTouchItemListener(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) { }

interface ClickListener {
    void onClick(View view, int position);
    void onLongClick(View view, int position);
}

}

这是持有recyclerview的活动:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_url_list);

    context = getApplicationContext();
    database = new DatabaseHelper(context);
    listOfUrl = (RecyclerView) findViewById(R.id.url_list);
    find = (Button) findViewById(R.id.findBtn);
    cancel = (Button) findViewById(R.id.cancelBtn);

    makeItPopUp();

    listOfUrl.setLayoutManager(new LinearLayoutManager(this));
    listOfUrl.setHasFixedSize(true);
    listOfUrl.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
    adapter = new ListAdapter(fillList(), context);
    listOfUrl.setAdapter(adapter);
    adapter.notifyDataSetChanged();

    selectedItems = new ArrayList<Boolean>(Arrays.asList(new Boolean[listOfUrl.getAdapter().getItemCount()]));
    Collections.fill(selectedItems, Boolean.FALSE);

    listOfUrl.addOnItemTouchListener(
            new RecyclerViewOnTouchItemListener(this, listOfUrl
                    , new RecyclerViewOnTouchItemListener.ClickListener() {
                @Override
                public void onClick(View view, int position) {
                    if (selectedItems.get(position))
                        setItemSelectedState(false, position, Color.WHITE);
                    else
                        setItemSelectedState(true, position, Color.LTGRAY);
                }
                @Override
                public void onLongClick(View view, int position) {}

                private void setItemSelectedState(boolean isSelected, int position, int color) {
                    try {
                        listOfUrl.getChildAt(position).setBackgroundColor(color);
                        selectedItems.add(position, isSelected);
                    } catch (NullPointerException e) {
                        e.printStackTrace();
                    }
                }
            })
    );
    find.setOnClickListener(this);
    cancel.setOnClickListener(this); }

任何可以告诉我我做错了什么。

简单的解决方案,创建接口类:

public interface ListListener {
    void onClick(int pos);
    void onLongClick(int pos);
}

调整您的RecyclerViewAdapter类的内容:

public class ListAdapter extends RecyclerView.Adapter<ViewHolder> {

private ListListener listener;
private List<ItemView> items;
private Context context;

public ListAdapter(List<ItemView> items, Context context) {
    this.items = items;
    this.context = context;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.item_style, parent, false);
    return new ViewHolder(view);
}

public ItemView getItem(int pos) {
    return items.get(pos);
}

public void setListener(ListListener listener) {
    this.listener = listener;
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    ItemView i = items.get(position);

    holder.setHeadText(i.getHead());
    holder.setScoreText(i.getContent());

    holder.itemLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int pos = holder.getAdapterPosition();
                if (listener != null && pos != RecyclerView.NO_POSITION) {
                    listener.onClick(pos);
                }
            }
    });

    holder.itemLayout.setOnLongClickListener(new View.OnLongClickListener() {
                    @Override
                    public boolean onLongClick(View view) {
                        int pos = holder.getAdapterPosition();
                        if (pos != -1) {
                            if (listener != null) {
                                listener.onLongClick(getItem(pos));
                            }
                        }
                        return true;
                    }
                });
}

在您的Activity类中,我编辑了一些部分:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_url_list);

    context = getApplicationContext();
    database = new DatabaseHelper(context);
    listOfUrl = (RecyclerView) findViewById(R.id.url_list);
    find = (Button) findViewById(R.id.findBtn);
    cancel = (Button) findViewById(R.id.cancelBtn);

    makeItPopUp();

    listOfUrl.setLayoutManager(new LinearLayoutManager(this));
    listOfUrl.setHasFixedSize(true);
    listOfUrl.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
    adapter = new ListAdapter(fillList(), context);
    adapter.setListener(new SelectCountryDialogListener() {
            @Override
            public void onClick(int pos) {
                ItemView item = adapter.getItem(pos);
            }

            @Override
            public void onLongClick(int pos) {
                ItemView item = adapter.getItem(pos);
            }
        });
    listOfUrl.setAdapter(adapter);

    selectedItems = new ArrayList<Boolean>(Arrays.asList(new Boolean[listOfUrl.getAdapter().getItemCount()]));
    Collections.fill(selectedItems, Boolean.FALSE);

    find.setOnClickListener(this);
    cancel.setOnClickListener(this); 
}

我很确定,现在对您来说非常容易。 仅用于实现onClick和onLongClick方法中的功能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM