RecyclerView(获取RecyclerView上的项)

8

我已经在 GitHub 上使用这个实现了 SearchView + Recyclerview。 GITHUB
我的下一步是获取选定部分的 RecyclerView 项。
然后我看到了一些获取 RecyclerView 的子项的代码。
当 getChildAt(index) = 0 时,该代码有效。
但是当我将 index 设置为 12 或大于 12 时,程序崩溃了。

mRecyclerView.setAdapter(mAdapter);
        mRecyclerView.addOnItemTouchListener(
                new RecyclerItemClickListener(getContext(), new RecyclerItemClickListener.OnItemClickListener() {
                    @Override
                    public void onItemClick(View view, int position) {
                        final int valueThisIteration = position;
                        mRecyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                            @Override
                            public void onGlobalLayout() {
                                TextView textViewDrawerTitle = (TextView) mRecyclerView.getChildAt(valueThisIteration).findViewById(R.id.tvText);
                                textViewDrawerTitle.setText("Checked");
                                mRecyclerView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                            }
                        });

                    }
                })
        );

我遇到了这个错误。

11-04 09:36:02.818 1629-1629/? E/AndroidRuntime: FATAL EXCEPTION: main
11-04 09:36:02.818 1629-1629/? E/AndroidRuntime: Process: com.thesis.juandirection.juandirectionfinale, PID: 1629
11-04 09:36:02.818 1629-1629/? E/AndroidRuntime: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference
11-04 09:36:02.818 1629-1629/? E/AndroidRuntime:     at com.thesis.juandirection.juandirectionfinale.fragments.FragmentSearch$1$1.onGlobalLayout(FragmentSearch.java:94)
11-04 09:36:02.818 1629-1629/? E/AndroidRuntime:     at android.view.ViewTreeObserver.dispatchOnGlobalLayout(ViewTreeObserver.java:815)
11-04 09:36:02.818 1629-1629/? E/AndroidRuntime:     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1867)
11-04 09:36:02.818 1629-1629/? E/AndroidRuntime:     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1054)
11-04 09:36:02.818 1629-1629/? E/AndroidRuntime:     at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5779)
11-04 09:36:02.818 1629-1629/? E/AndroidRuntime:     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
11-04 09:36:02.818 1629-1629/? E/AndroidRuntime:     at android.view.Choreographer.doCallbacks(Choreographer.java:580)
11-04 09:36:02.818 1629-1629/? E/AndroidRuntime:     at android.view.Choreographer.doFrame(Choreographer.java:550)
11-04 09:36:02.818 1629-1629/? E/AndroidRuntime:     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
11-04 09:36:02.818 1629-1629/? E/AndroidRuntime:     at android.os.Handler.handleCallback(Handler.java:739)
11-04 09:36:02.818 1629-1629/? E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:95)
11-04 09:36:02.818 1629-1629/? E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:135)
11-04 09:36:02.818 1629-1629/? E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5221)
11-04 09:36:02.818 1629-1629/? E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Native Method)
11-04 09:36:02.818 1629-1629/? E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Method.java:372)
11-04 09:36:02.818 1629-1629/? E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
11-04 09:36:02.818 1629-1629/? E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

正如StackTrace所指出的那样,在迭代过程中,您从mRecyclerView.getChildAt(valueThisIteration)获取了一个空值。您只是想处理RecyclerView的项目点击吗?如果是这样,有更好的方法可以实现。 - AdamMc331
这是其中之一。但我还想获取 RecyclerView 上选择的项目。将其存储在变量中等等。 - Charles Galvez
好的。我会写一篇答案,我相信我理解了。 - AdamMc331
只需在recyclerView上设置onItemClickListener,它也会为您提供所选索引... - Nanoc
@CharlesGalvez 你是将数据存储在 Adapter 类中的 ListArray 对象中吗?如果是这种情况,我相信我的答案方法会很好地解决问题。 - AdamMc331
显示剩余2条评论
1个回答

42

处理RecyclerView中的项目点击,我建议将逻辑移至Adapter的ViewHolder中。您可以让ViewHolder实现View.OnClickListener,并重写onClick()方法来执行操作。如果您的操作依赖于所点击的项目,您可以使用getAdapterPosition()引用它。代码将类似于以下内容:

public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
   public MyViewHolder(View view) {
      super(view);

      view.setOnClickListener(this);
   }

   @Override
   public void onClick(View view) {
      // Get the item clicked
      // For this example, I'm assuming your data source is of type `List<MyObject>`
      MyObject myObject = mDataSource.get(getAdapterPosition());
      // Then you can do any actions on it, for example: 
      myObject.setChecked();
   }
}

显然,onClick 内发生的逻辑将会根据你的示例而改变,但我希望这能使你走上正确的道路。如需更多示例以及有关在 ViewHolder 中处理点击逻辑的好处的解释,请查看我撰写的一篇博客文章(查找标有“More explicit click listeners”的部分)。


1
哦,你改了什么? - AdamMc331
1
这是我的错。我在我的textView上设置了view.setOnClickListener(this)。现在它正常工作了。谢谢。 - Charles Galvez
@CharlesGalvez 简单的错误!很高兴能帮到你。 - AdamMc331
3
你从哪里获取mDataSource? - eskalera
3
如果 getAdapterPosition() 返回 NO_POSITION (-1),那么上述代码将会崩溃。在这种情况下我们应该怎么办? - Minas Mina
显示剩余12条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接